grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

consolidate ELF header checks


From: Guillem Jover
Subject: consolidate ELF header checks
Date: Tue, 1 Feb 2005 05:47:08 +0100
User-agent: Mutt/1.5.6+20040907i

Hi,

I'm working on the kFreeBSD loader and thus merging some common
code to not have to duplicate it even more. This is the first patch
from this serie.

I've spoken with Marco about creating a new elf helper loader module
so other loaders can share common functions. Maybe later we can add
a.out or coff helper modules... Or maybe even move most of the
functionality from dl to the elf module.

This patch merges common ELF header checks. Please test this on PPC
as I've only tested on x86.


2005-02-01  Guillem Jover  <address@hidden>

        * include/grub/dl.h (grub_dl_check_header): New prototype.
        (grub_arch_dl_check_header): Change return type to grub_err_t.
        * kern/dl.c (grub_dl_check_header): New function.
        (grub_dl_load_core): Use grub_dl_check_header instead of
        grub_arch_dl_check_header. Check ELF type. Check sections to be
        inside the core.
        * kern/i386/dl.c (grub_arch_dl_check_header): Remove arch
        independent ELF header checks.
        * kern/powerpc/dl.c (grub_arch_dl_check_header): Likewise.
        * loader/i386/pc/multiboot.c (grub_rescue_cmd_multiboot): Use
        grub_dl_check_header instead of explicit checks. Check for ELF type.
        * loader/powerpc/ieee1275/linux.c (grub_rescue_cmd_linux): Use
        grub_dl_check_header instead of explicit checks. Remove arch specific
        ELF header checks.
        * util/grub-emu.c (grub_arch_dl_check_header): Change return type.

diff -Naupr -x CVS grub2-cvs/include/grub/dl.h grub2.dl/include/grub/dl.h
--- grub2-cvs/include/grub/dl.h 2005-02-01 04:34:12.000000000 +0100
+++ grub2.dl/include/grub/dl.h  2005-02-01 04:03:26.000000000 +0100
@@ -70,6 +70,7 @@ struct grub_dl
 };
 typedef struct grub_dl *grub_dl_t;
 
+grub_err_t EXPORT_FUNC(grub_dl_check_header) (void *ehdr, grub_size_t size);
 grub_dl_t EXPORT_FUNC(grub_dl_load_file) (const char *filename);
 grub_dl_t EXPORT_FUNC(grub_dl_load) (const char *name);
 grub_dl_t grub_dl_load_core (void *addr, grub_size_t size);
@@ -84,7 +85,7 @@ grub_err_t EXPORT_FUNC(grub_dl_register_
                                            grub_dl_t mod);
 void *EXPORT_FUNC(grub_dl_resolve_symbol) (const char *name);
 
-int grub_arch_dl_check_header (void *ehdr, grub_size_t size);
+grub_err_t grub_arch_dl_check_header (void *ehdr, grub_size_t size);
 grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr);
 
 #endif /* ! GRUB_DL_H */
diff -Naupr -x CVS grub2-cvs/kern/dl.c grub2.dl/kern/dl.c
--- grub2-cvs/kern/dl.c 2005-02-01 04:34:13.000000000 +0100
+++ grub2.dl/kern/dl.c  2005-02-01 04:05:45.000000000 +0100
@@ -238,6 +238,29 @@
   return 0;
 }
 
+/* Check if EHDR is a valid ELF header.  */
+grub_err_t
+grub_dl_check_header (void *ehdr, grub_size_t size)
+{
+  Elf_Ehdr *e = ehdr;
+
+  /* Check the header size.  */
+  if (size < sizeof (Elf_Ehdr))
+    return grub_error (GRUB_ERR_BAD_OS, "ELF size");
+
+  /* Check the magic numbers.  */
+  if (grub_arch_dl_check_header (ehdr, size)
+      || e->e_ident[EI_MAG0] != ELFMAG0
+      || e->e_ident[EI_MAG1] != ELFMAG1
+      || e->e_ident[EI_MAG2] != ELFMAG2
+      || e->e_ident[EI_MAG3] != ELFMAG3
+      || e->e_ident[EI_VERSION] != EV_CURRENT
+      || e->e_version != EV_CURRENT)
+    return grub_error (GRUB_ERR_BAD_OS, "Generic ELF magic");
+
+  return GRUB_ERR_NONE;
+}
+
 /* Load all segments from memory specified by E.  */
 static grub_err_t
 grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
@@ -497,12 +520,26 @@
   grub_dl_t mod;
   
   e = addr;
-  if (! grub_arch_dl_check_header (e, size))
+  if (grub_dl_check_header (e, size))
     {
       grub_error (GRUB_ERR_BAD_MODULE, "invalid ELF header");
       return 0;
     }
   
+  if (e->e_type != ET_REL)
+    {
+      grub_error (GRUB_ERR_BAD_MODULE,
+                 "This ELF file is not of the right type\n");
+      return 0;
+    }
+
+  /* Make sure that every section is within the core.  */
+  if (size < e->e_shoff + e->e_shentsize * e->e_shnum)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "ELF sections inside core");
+      return 0;
+    }
+
   mod = (grub_dl_t) grub_malloc (sizeof (*mod));
   if (! mod)
     return 0;
diff -Naupr -x CVS grub2-cvs/kern/i386/dl.c grub2.dl/kern/i386/dl.c
--- grub2-cvs/kern/i386/dl.c    2005-02-01 04:34:13.000000000 +0100
+++ grub2.dl/kern/i386/dl.c     2005-02-01 04:03:26.000000000 +0100
@@ -24,32 +24,18 @@
 #include <grub/err.h>
 
 /* Check if EHDR is a valid ELF header.  */
-int
+grub_err_t
 grub_arch_dl_check_header (void *ehdr, grub_size_t size)
 {
   Elf32_Ehdr *e = ehdr;
 
-  /* Check the header size.  */
-  if (size < sizeof (Elf32_Ehdr))
-    return 0;
-
   /* Check the magic numbers.  */
-  if (e->e_ident[EI_MAG0] != ELFMAG0
-      || e->e_ident[EI_MAG1] != ELFMAG1
-      || e->e_ident[EI_MAG2] != ELFMAG2
-      || e->e_ident[EI_MAG3] != ELFMAG3
-      || e->e_version != EV_CURRENT
-      || e->e_ident[EI_CLASS] != ELFCLASS32
+  if (e->e_ident[EI_CLASS] != ELFCLASS32
       || e->e_ident[EI_DATA] != ELFDATA2LSB
-      || e->e_machine != EM_386
-      || e->e_type != ET_REL)
-    return 0;
-
-  /* Make sure that every section is within the core.  */
-  if (size < e->e_shoff + e->e_shentsize * e->e_shnum)
-    return 0;
+      || e->e_machine != EM_386)
+    return grub_error (GRUB_ERR_BAD_OS, "Arch ELF magic");
 
-  return 1;
+  return GRUB_ERR_NONE;
 }
 
 /* Relocate symbols.  */
diff -Naupr -x CVS grub2-cvs/kern/powerpc/dl.c grub2.dl/kern/powerpc/dl.c
--- grub2-cvs/kern/powerpc/dl.c 2005-02-01 04:34:13.000000000 +0100
+++ grub2.dl/kern/powerpc/dl.c  2005-02-01 04:03:26.000000000 +0100
@@ -24,32 +24,18 @@
 #include <grub/err.h>
 
 /* Check if EHDR is a valid ELF header.  */
-int
+grub_err_t
 grub_arch_dl_check_header (void *ehdr, grub_size_t size)
 {
   Elf32_Ehdr *e = ehdr;
 
-  /* Check the header size.  */
-  if (size < sizeof (Elf32_Ehdr))
-    return 0;
-
   /* Check the magic numbers.  */
-  if (!((e->e_ident[EI_MAG0] == ELFMAG0) 
-       && (e->e_ident[EI_MAG1] == ELFMAG1)
-       && (e->e_ident[EI_MAG2] == ELFMAG2) 
-       && (e->e_ident[EI_MAG3] == ELFMAG3)
-       && (e->e_ident[EI_CLASS] == ELFCLASS32) 
-       && (e->e_ident[EI_DATA] == ELFDATA2MSB)
-       && (e->e_ident[EI_VERSION] == EV_CURRENT) 
-       && (e->e_type == ET_REL) && (e->e_machine == EM_PPC) 
-       && (e->e_version == EV_CURRENT)))
-    return 0;
-  
-  /* Make sure that every section is within the core.  */
-  if (size < e->e_shoff + e->e_shentsize * e->e_shnum)
-    return 0;
+  if (e->e_ident[EI_CLASS] != ELFCLASS32
+      || e->e_ident[EI_DATA] != ELFDATA2MSB
+      || e->e_machine != EM_PPC)
+    return grub_error (GRUB_ERR_BAD_OS, "Arch ELF magic");
 
-  return 1;
+  return GRUB_ERR_NONE;
 }
 
 
diff -Naupr -x CVS grub2-cvs/loader/i386/pc/multiboot.c 
grub2.dl/loader/i386/pc/multiboot.c
--- grub2-cvs/loader/i386/pc/multiboot.c        2005-02-01 04:34:13.000000000 
+0100
+++ grub2.dl/loader/i386/pc/multiboot.c 2005-02-01 04:35:25.000000000 +0100
@@ -140,20 +140,19 @@ grub_rescue_cmd_multiboot (int argc, cha
 
   ehdr = (Elf32_Ehdr *) buffer;
 
-  if (!((ehdr->e_ident[EI_MAG0] == ELFMAG0) 
-       && (ehdr->e_ident[EI_MAG1] == ELFMAG1)
-       && (ehdr->e_ident[EI_MAG2] == ELFMAG2) 
-       && (ehdr->e_ident[EI_MAG3] == ELFMAG3)
-       && (ehdr->e_ident[EI_CLASS] == ELFCLASS32) 
-       && (ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
-       && (ehdr->e_ident[EI_VERSION] == EV_CURRENT) 
-       && (ehdr->e_type == ET_EXEC) && (ehdr->e_machine == EM_386) 
-       && (ehdr->e_version == EV_CURRENT)))
+  if (grub_dl_check_header (ehdr, sizeof(*ehdr)))
     {
       grub_error (GRUB_ERR_UNKNOWN_OS, "No valid ELF header found");
       goto fail;
     }
 
+  if (ehdr->e_type != ET_EXEC)
+    {
+      grub_error (GRUB_ERR_UNKNOWN_OS,
+                 "This ELF file is not of the right type\n");
+      goto fail;
+    }
+
   /* FIXME: Should we support program headers at strange locations?  */
   if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > GRUB_MB_SEARCH)
     {
diff -Naupr -x CVS grub2-cvs/loader/powerpc/ieee1275/linux.c 
grub2.dl/loader/powerpc/ieee1275/linux.c
--- grub2-cvs/loader/powerpc/ieee1275/linux.c   2005-02-01 04:34:13.000000000 
+0100
+++ grub2.dl/loader/powerpc/ieee1275/linux.c    2005-02-01 04:03:26.000000000 
+0100
@@ -124,15 +124,7 @@ grub_rescue_cmd_linux (int argc, char *a
       goto fail;
     }
   
-  if (!((ehdr.e_ident[EI_MAG0] == ELFMAG0) 
-       && (ehdr.e_ident[EI_MAG1] == ELFMAG1)
-       && (ehdr.e_ident[EI_MAG2] == ELFMAG2) 
-       && (ehdr.e_ident[EI_MAG3] == ELFMAG3)
-       && (ehdr.e_ident[EI_CLASS] == ELFCLASS32) 
-       && (ehdr.e_ident[EI_DATA] == ELFDATA2MSB)
-       && (ehdr.e_ident[EI_VERSION] == EV_CURRENT) 
-       && (ehdr.e_type == ET_EXEC) && (ehdr.e_machine == EM_PPC) 
-       && (ehdr.e_version == EV_CURRENT)))
+  if (grub_dl_check_header (ehdr, sizeof(ehdr)))
     {
       grub_error (GRUB_ERR_UNKNOWN_OS, "No valid ELF header found");
       goto fail;
@@ -145,20 +137,6 @@ grub_rescue_cmd_linux (int argc, char *a
       goto fail;
     }
 
-  if (ehdr.e_machine != EM_PPC)
-    {
-      grub_error (GRUB_ERR_UNKNOWN_OS,
-                 "This ELF file is not for the PPC32\n");
-      goto fail;
-    }
-  
-  if (ehdr.e_version != EV_CURRENT)
-    {
-      grub_error (GRUB_ERR_UNKNOWN_OS,
-                 "Invalid ELF version\n");
-      goto fail;
-    }
-
   /* Read the sections.  */
   entry = ehdr.e_entry;
   if (entry == 0xc0000000)
diff -Naupr -x CVS grub2-cvs/util/grub-emu.c grub2.dl/util/grub-emu.c
--- grub2-cvs/util/grub-emu.c   2005-02-01 04:34:13.000000000 +0100
+++ grub2.dl/util/grub-emu.c    2005-02-01 04:03:26.000000000 +0100
@@ -51,7 +51,7 @@ grub_arch_modules_addr (void)
   return 0;
 }
 
-int
+grub_err_t
 grub_arch_dl_check_header (void *ehdr, grub_size_t size)
 {
   (void) ehdr;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]