[PATCH v4 2/4] KEYS: Add ELF class-independent certificate insertion support

2017-04-20 Thread Mehmet Kayaalp
Use ELF class-independent GElf API for processing the kernel binary. This
patch adds support for compiling the script for 64-bit and the kernel for
32-bit (e.g. make ARCH=i386 on x86-64).

Signed-off-by: Mehmet Kayaalp 
---
 scripts/Makefile  |   1 +
 scripts/insert-sys-cert.c | 215 +++---
 2 files changed, 109 insertions(+), 107 deletions(-)

diff --git a/scripts/Makefile b/scripts/Makefile
index 1d80897..5633f2c 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -25,6 +25,7 @@ HOSTCFLAGS_sortextable.o = -I$(srctree)/tools/include
 HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include
 HOSTLOADLIBES_sign-file = -lcrypto
 HOSTLOADLIBES_extract-cert = -lcrypto
+HOSTLOADLIBES_insert-sys-cert = -lelf
 
 always := $(hostprogs-y) $(hostprogs-m)
 
diff --git a/scripts/insert-sys-cert.c b/scripts/insert-sys-cert.c
index 8902836..86a3d41 100644
--- a/scripts/insert-sys-cert.c
+++ b/scripts/insert-sys-cert.c
@@ -24,7 +24,8 @@
 #include 
 #include 
 #include 
-#include 
+#include 
+#include 
 
 #define CERT_SYM  "system_extra_cert"
 #define USED_SYM  "system_extra_cert_used"
@@ -34,18 +35,6 @@
 #define warn(format, args...) fprintf(stdout, "WARNING: " format, ## args)
 #define  err(format, args...) fprintf(stderr, "ERROR:   " format, ## args)
 
-#if UINTPTR_MAX == 0x
-#define CURRENT_ELFCLASS ELFCLASS32
-#define Elf_Ehdr   Elf32_Ehdr
-#define Elf_Shdr   Elf32_Shdr
-#define Elf_SymElf32_Sym
-#else
-#define CURRENT_ELFCLASS ELFCLASS64
-#define Elf_Ehdr   Elf64_Ehdr
-#define Elf_Shdr   Elf64_Shdr
-#define Elf_SymElf64_Sym
-#endif
-
 static unsigned char endianness(void)
 {
uint16_t two_byte = 0x00FF;
@@ -65,22 +54,17 @@ struct sym {
int size;
 };
 
-static unsigned long get_offset_from_address(Elf_Ehdr *hdr, unsigned long addr)
+static unsigned long get_offset_from_address(Elf *elf, unsigned long addr)
 {
-   Elf_Shdr *x;
-   unsigned int i, num_sections;
-
-   x = (void *)hdr + hdr->e_shoff;
-   if (hdr->e_shnum == SHN_UNDEF)
-   num_sections = x[0].sh_size;
-   else
-   num_sections = hdr->e_shnum;
-
-   for (i = 1; i < num_sections; i++) {
-   unsigned long start = x[i].sh_addr;
-   unsigned long end = start + x[i].sh_size;
-   unsigned long offset = x[i].sh_offset;
-
+   Elf_Scn *scn = NULL;
+   GElf_Shdr shdr;
+   unsigned long start, end, offset;
+
+   while ((scn = elf_nextscn(elf, scn)) != NULL) {
+   gelf_getshdr(scn, );
+   start = shdr.sh_addr;
+   end = start + shdr.sh_size;
+   offset = shdr.sh_offset;
if (addr >= start && addr <= end)
return addr - start + offset;
}
@@ -90,7 +74,7 @@ static unsigned long get_offset_from_address(Elf_Ehdr *hdr, 
unsigned long addr)
 
 #define LINE_SIZE 100
 
-static void get_symbol_from_map(Elf_Ehdr *hdr, FILE *f, char *name,
+static void get_symbol_from_map(Elf *elf, void *base, FILE *f, char *name,
struct sym *s)
 {
char l[LINE_SIZE];
@@ -125,76 +109,65 @@ static void get_symbol_from_map(Elf_Ehdr *hdr, FILE *f, 
char *name,
s->address = strtoul(l, NULL, 16);
if (s->address == 0)
return;
-   s->offset = get_offset_from_address(hdr, s->address);
+   s->offset = get_offset_from_address(elf, s->address);
s->name = name;
-   s->content = (void *)hdr + s->offset;
-}
-
-static Elf_Sym *find_elf_symbol(Elf_Ehdr *hdr, Elf_Shdr *symtab, char *name)
-{
-   Elf_Sym *sym, *symtab_start;
-   char *strtab, *symname;
-   unsigned int link;
-   Elf_Shdr *x;
-   int i, n;
-
-   x = (void *)hdr + hdr->e_shoff;
-   link = symtab->sh_link;
-   symtab_start = (void *)hdr + symtab->sh_offset;
-   n = symtab->sh_size / symtab->sh_entsize;
-   strtab = (void *)hdr + x[link].sh_offset;
-
-   for (i = 0; i < n; i++) {
-   sym = _start[i];
-   symname = strtab + sym->st_name;
-   if (strcmp(symname, name) == 0)
-   return sym;
-   }
-   err("Unable to find symbol: %s\n", name);
-   return NULL;
+   s->content = (void *)base + s->offset;
 }
 
-static void get_symbol_from_table(Elf_Ehdr *hdr, Elf_Shdr *symtab,
+static void get_symbol_from_table(Elf *elf, Elf_Scn *symtab, void *base,
  char *name, struct sym *s)
 {
-   Elf_Shdr *sec;
-   int secndx;
-   Elf_Sym *elf_sym;
-   Elf_Shdr *x;
+   GElf_Shdr shdr;
+   Elf_Data *data;
+   int count;
+   int i;
+   GElf_Sym sym;
+   char *symname;
+   int found = 0;
+   size_t secndx;
+   Elf_Scn *sec;
+
+   gelf_getshdr(symtab, );
+   data = elf_getdata(symtab, NULL);
+   count = shdr.sh_size / shdr.sh_entsize;
+

[PATCH v4 2/4] KEYS: Add ELF class-independent certificate insertion support

2017-04-20 Thread Mehmet Kayaalp
Use ELF class-independent GElf API for processing the kernel binary. This
patch adds support for compiling the script for 64-bit and the kernel for
32-bit (e.g. make ARCH=i386 on x86-64).

Signed-off-by: Mehmet Kayaalp 
---
 scripts/Makefile  |   1 +
 scripts/insert-sys-cert.c | 215 +++---
 2 files changed, 109 insertions(+), 107 deletions(-)

diff --git a/scripts/Makefile b/scripts/Makefile
index 1d80897..5633f2c 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -25,6 +25,7 @@ HOSTCFLAGS_sortextable.o = -I$(srctree)/tools/include
 HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include
 HOSTLOADLIBES_sign-file = -lcrypto
 HOSTLOADLIBES_extract-cert = -lcrypto
+HOSTLOADLIBES_insert-sys-cert = -lelf
 
 always := $(hostprogs-y) $(hostprogs-m)
 
diff --git a/scripts/insert-sys-cert.c b/scripts/insert-sys-cert.c
index 8902836..86a3d41 100644
--- a/scripts/insert-sys-cert.c
+++ b/scripts/insert-sys-cert.c
@@ -24,7 +24,8 @@
 #include 
 #include 
 #include 
-#include 
+#include 
+#include 
 
 #define CERT_SYM  "system_extra_cert"
 #define USED_SYM  "system_extra_cert_used"
@@ -34,18 +35,6 @@
 #define warn(format, args...) fprintf(stdout, "WARNING: " format, ## args)
 #define  err(format, args...) fprintf(stderr, "ERROR:   " format, ## args)
 
-#if UINTPTR_MAX == 0x
-#define CURRENT_ELFCLASS ELFCLASS32
-#define Elf_Ehdr   Elf32_Ehdr
-#define Elf_Shdr   Elf32_Shdr
-#define Elf_SymElf32_Sym
-#else
-#define CURRENT_ELFCLASS ELFCLASS64
-#define Elf_Ehdr   Elf64_Ehdr
-#define Elf_Shdr   Elf64_Shdr
-#define Elf_SymElf64_Sym
-#endif
-
 static unsigned char endianness(void)
 {
uint16_t two_byte = 0x00FF;
@@ -65,22 +54,17 @@ struct sym {
int size;
 };
 
-static unsigned long get_offset_from_address(Elf_Ehdr *hdr, unsigned long addr)
+static unsigned long get_offset_from_address(Elf *elf, unsigned long addr)
 {
-   Elf_Shdr *x;
-   unsigned int i, num_sections;
-
-   x = (void *)hdr + hdr->e_shoff;
-   if (hdr->e_shnum == SHN_UNDEF)
-   num_sections = x[0].sh_size;
-   else
-   num_sections = hdr->e_shnum;
-
-   for (i = 1; i < num_sections; i++) {
-   unsigned long start = x[i].sh_addr;
-   unsigned long end = start + x[i].sh_size;
-   unsigned long offset = x[i].sh_offset;
-
+   Elf_Scn *scn = NULL;
+   GElf_Shdr shdr;
+   unsigned long start, end, offset;
+
+   while ((scn = elf_nextscn(elf, scn)) != NULL) {
+   gelf_getshdr(scn, );
+   start = shdr.sh_addr;
+   end = start + shdr.sh_size;
+   offset = shdr.sh_offset;
if (addr >= start && addr <= end)
return addr - start + offset;
}
@@ -90,7 +74,7 @@ static unsigned long get_offset_from_address(Elf_Ehdr *hdr, 
unsigned long addr)
 
 #define LINE_SIZE 100
 
-static void get_symbol_from_map(Elf_Ehdr *hdr, FILE *f, char *name,
+static void get_symbol_from_map(Elf *elf, void *base, FILE *f, char *name,
struct sym *s)
 {
char l[LINE_SIZE];
@@ -125,76 +109,65 @@ static void get_symbol_from_map(Elf_Ehdr *hdr, FILE *f, 
char *name,
s->address = strtoul(l, NULL, 16);
if (s->address == 0)
return;
-   s->offset = get_offset_from_address(hdr, s->address);
+   s->offset = get_offset_from_address(elf, s->address);
s->name = name;
-   s->content = (void *)hdr + s->offset;
-}
-
-static Elf_Sym *find_elf_symbol(Elf_Ehdr *hdr, Elf_Shdr *symtab, char *name)
-{
-   Elf_Sym *sym, *symtab_start;
-   char *strtab, *symname;
-   unsigned int link;
-   Elf_Shdr *x;
-   int i, n;
-
-   x = (void *)hdr + hdr->e_shoff;
-   link = symtab->sh_link;
-   symtab_start = (void *)hdr + symtab->sh_offset;
-   n = symtab->sh_size / symtab->sh_entsize;
-   strtab = (void *)hdr + x[link].sh_offset;
-
-   for (i = 0; i < n; i++) {
-   sym = _start[i];
-   symname = strtab + sym->st_name;
-   if (strcmp(symname, name) == 0)
-   return sym;
-   }
-   err("Unable to find symbol: %s\n", name);
-   return NULL;
+   s->content = (void *)base + s->offset;
 }
 
-static void get_symbol_from_table(Elf_Ehdr *hdr, Elf_Shdr *symtab,
+static void get_symbol_from_table(Elf *elf, Elf_Scn *symtab, void *base,
  char *name, struct sym *s)
 {
-   Elf_Shdr *sec;
-   int secndx;
-   Elf_Sym *elf_sym;
-   Elf_Shdr *x;
+   GElf_Shdr shdr;
+   Elf_Data *data;
+   int count;
+   int i;
+   GElf_Sym sym;
+   char *symname;
+   int found = 0;
+   size_t secndx;
+   Elf_Scn *sec;
+
+   gelf_getshdr(symtab, );
+   data = elf_getdata(symtab, NULL);
+   count = shdr.sh_size / shdr.sh_entsize;
+
+   for (i = 0; i <