All of lore.kernel.org
 help / color / mirror / Atom feed
* consolidate ELF header checks
@ 2005-02-01  4:47 Guillem Jover
  2005-02-01 19:26 ` Marco Gerards
  2005-02-04 22:25 ` Marco Gerards
  0 siblings, 2 replies; 17+ messages in thread
From: Guillem Jover @ 2005-02-01  4:47 UTC (permalink / raw)
  To: grub-devel

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  <guillem@hadrons.org>

	* 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;



^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2005-02-11 18:56 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-02-01  4:47 consolidate ELF header checks Guillem Jover
2005-02-01 19:26 ` Marco Gerards
2005-02-04 22:25 ` Marco Gerards
2005-02-04 22:40   ` Yoshinori K. Okuji
2005-02-05 14:10     ` Marco Gerards
2005-02-05 22:55       ` Yoshinori K. Okuji
2005-02-05 22:45   ` Guillem Jover
2005-02-06 11:02     ` Marco Gerards
2005-02-06 12:58       ` Yoshinori K. Okuji
2005-02-06 14:22         ` Marco Gerards
2005-02-06 21:28         ` Guillem Jover
2005-02-08 12:54           ` Yoshinori K. Okuji
2005-02-09  7:10             ` Guillem Jover
2005-02-10 19:21               ` Yoshinori K. Okuji
2005-02-11 17:25                 ` Marco Gerards
2005-02-11 18:07                   ` Yoshinori K. Okuji
2005-02-11 18:24                     ` Marco Gerards

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.