grub-devel
[Top][All Lists]
Advanced

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

[PATCH v3 2/5] elf: Validate number of elf section header table entries


From: Alec Brown
Subject: [PATCH v3 2/5] elf: Validate number of elf section header table entries
Date: Wed, 20 Apr 2022 22:23:14 -0400

In bsdXX.c and multiboot_elfXX.c, e_shnum is used to obtain the number of
section header table entries, but it wasn't being checked if the value was
there.

According to the elf(5) manual page,
"If the number of entries in the section header table is larger than or equal to
SHN_LORESERVE (0xff00), e_shnum holds the value zero and the real number of
entries in the section header table is held in the sh_size member of the intial
entry in section header table. Otherwise, the sh_size member of the initial
entry in the section header table holds the value zero."

Since this check wasn't being made, grub_elfXX_get_shnum() is being added to
elfXX.c to make this check and use whichever member doesn't have a value of
zero. If both are zero, then we must return an error. We also need to make sure
that e_shnum doesn't have a value greater than or equal to SHN_LORESERVE and
sh_size isn't less than SHN_LORESERVE.

Note that even though elf.c and elfXX.c are located in grub-core/kern, they are
compiled as modules and don't need the EXPORT_FUNC macro to define the functions
in elf.h.

Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
---
 grub-core/kern/elf.c               |  9 ++++
 grub-core/kern/elfXX.c             | 34 +++++++++++++
 grub-core/loader/i386/bsdXX.c      | 82 ++++++++++++++++++++++--------
 grub-core/loader/multiboot_elfxx.c | 49 +++++++++++-------
 include/grub/elf.h                 |  9 ++++
 5 files changed, 142 insertions(+), 41 deletions(-)

diff --git a/grub-core/kern/elf.c b/grub-core/kern/elf.c
index 9d7149b38..5be770583 100644
--- a/grub-core/kern/elf.c
+++ b/grub-core/kern/elf.c
@@ -167,11 +167,14 @@ grub_elf_open (const char *name, enum grub_file_type type)
 #define grub_elfXX_load_phdrs grub_elf32_load_phdrs
 #define ElfXX_Phdr Elf32_Phdr
 #define ElfXX_Ehdr Elf32_Ehdr
+#define ElfXX_Shdr Elf32_Shdr
+#define ElfXX_Word Elf32_Word
 #define grub_uintXX_t grub_uint32_t
 #define grub_swap_bytes_addrXX grub_swap_bytes32
 #define grub_swap_bytes_offXX grub_swap_bytes32
 #define grub_swap_bytes_XwordXX grub_swap_bytes32
 #define grub_elfXX_check_endianess_and_bswap_ehdr 
grub_elf32_check_endianess_and_bswap_ehdr
+#define grub_elfXX_get_shnum grub_elf32_get_shnum
 
 #include "elfXX.c"
 
@@ -185,11 +188,14 @@ grub_elf_open (const char *name, enum grub_file_type type)
 #undef grub_elfXX_load_phdrs
 #undef ElfXX_Phdr
 #undef ElfXX_Ehdr
+#undef ElfXX_Shdr
+#undef ElfXX_Word
 #undef grub_uintXX_t
 #undef grub_swap_bytes_addrXX
 #undef grub_swap_bytes_offXX
 #undef grub_swap_bytes_XwordXX
 #undef grub_elfXX_check_endianess_and_bswap_ehdr
+#undef grub_elfXX_get_shnum
 
 
 /* 64-bit */
@@ -203,10 +209,13 @@ grub_elf_open (const char *name, enum grub_file_type type)
 #define grub_elfXX_load_phdrs grub_elf64_load_phdrs
 #define ElfXX_Phdr Elf64_Phdr
 #define ElfXX_Ehdr Elf64_Ehdr
+#define ElfXX_Shdr Elf64_Shdr
+#define ElfXX_Word Elf64_Word
 #define grub_uintXX_t grub_uint64_t
 #define grub_swap_bytes_addrXX grub_swap_bytes64
 #define grub_swap_bytes_offXX grub_swap_bytes64
 #define grub_swap_bytes_XwordXX grub_swap_bytes64
 #define grub_elfXX_check_endianess_and_bswap_ehdr 
grub_elf64_check_endianess_and_bswap_ehdr
+#define grub_elfXX_get_shnum grub_elf64_get_shnum
 
 #include "elfXX.c"
diff --git a/grub-core/kern/elfXX.c b/grub-core/kern/elfXX.c
index 1859d1880..ed2dc7075 100644
--- a/grub-core/kern/elfXX.c
+++ b/grub-core/kern/elfXX.c
@@ -205,3 +205,37 @@ grub_elfXX_check_endianess_and_bswap_ehdr (grub_elf_t elf)
 
   return 0;
 }
+
+grub_err_t
+grub_elfXX_get_shnum (ElfXX_Ehdr *e, ElfXX_Word *shnum)
+{
+  ElfXX_Shdr *s;
+
+  if (shnum == NULL)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("NULL pointer passed for 
shnum"));
+
+  /* Set *shnum to 0 so that shnum doesn't return junk on error */
+  *shnum = 0;
+
+  if (e == NULL)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("NULL pointer passed for elf 
header"));
+
+  *shnum = e->e_shnum;
+  if (*shnum == SHN_UNDEF)
+    {
+      if (e->e_shoff == 0)
+       return grub_error (GRUB_ERR_BAD_NUMBER, N_("invalid section header 
table offset in e_shoff"));
+
+      s = (ElfXX_Shdr *) ((grub_uint8_t *) e + e->e_shoff);
+      *shnum = s->sh_size;
+      if (*shnum < SHN_LORESERVE)
+       return grub_error (GRUB_ERR_BAD_NUMBER, N_("invalid number of section 
header table entries in sh_size: %d"), *shnum);
+    }
+  else
+    {
+      if (*shnum >= SHN_LORESERVE)
+       return grub_error (GRUB_ERR_BAD_NUMBER, N_("invalid number of section 
header table entries in e_shnum: %d"), *shnum);
+    }
+
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/loader/i386/bsdXX.c b/grub-core/loader/i386/bsdXX.c
index 6946cecbb..7d9b65d1a 100644
--- a/grub-core/loader/i386/bsdXX.c
+++ b/grub-core/loader/i386/bsdXX.c
@@ -26,7 +26,10 @@ load (grub_file_t file, const char *filename, void *where, 
grub_off_t off, grub_
 static inline grub_err_t
 read_headers (grub_file_t file, const char *filename, Elf_Ehdr *e, Elf_Shdr 
**shdr)
 {
- if (grub_file_seek (file, 0) == (grub_off_t) -1)
+  Elf_Word shnum;
+  grub_err_t err;
+
+  if (grub_file_seek (file, 0) == (grub_off_t) -1)
     return grub_errno;
 
   if (grub_file_read (file, (char *) e, sizeof (*e)) != sizeof (*e))
@@ -48,15 +51,19 @@ read_headers (grub_file_t file, const char *filename, 
Elf_Ehdr *e, Elf_Shdr **sh
   if (e->e_ident[EI_CLASS] != SUFFIX (ELFCLASS))
     return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF 
magic"));
 
-  *shdr = grub_calloc (e->e_shnum, e->e_shentsize);
+  err = grub_elf_get_shnum (e, &shnum);
+  if (err)
+    return err;
+
+  *shdr = grub_calloc (shnum, e->e_shentsize);
   if (! *shdr)
     return grub_errno;
 
   if (grub_file_seek (file, e->e_shoff) == (grub_off_t) -1)
     return grub_errno;
 
-  if (grub_file_read (file, *shdr, (grub_uint32_t) e->e_shnum * e->e_shentsize)
-      != (grub_ssize_t) ((grub_uint32_t) e->e_shnum * e->e_shentsize))
+  if (grub_file_read (file, *shdr, (grub_ssize_t) shnum * e->e_shentsize)
+      != (grub_ssize_t) ((grub_ssize_t) shnum * e->e_shentsize))
     {
       if (grub_errno)
        return grub_errno;
@@ -79,6 +86,7 @@ SUFFIX (grub_freebsd_load_elfmodule_obj) (struct 
grub_relocator *relocator,
   Elf_Ehdr e;
   Elf_Shdr *s;
   Elf_Shdr *shdr = NULL;
+  Elf_Word shnum;
   grub_addr_t curload, module;
   grub_err_t err;
   grub_size_t chunk_size = 0;
@@ -90,7 +98,11 @@ SUFFIX (grub_freebsd_load_elfmodule_obj) (struct 
grub_relocator *relocator,
   if (err)
     goto out;
 
-  for (s = shdr; s < (Elf_Shdr *) ((grub_uint8_t *) shdr + e.e_shnum * 
e.e_shentsize);
+  err = grub_elf_get_shnum (&e, &shnum);
+  if (err != GRUB_ERR_NONE)
+    goto out;
+
+  for (s = shdr; s < (Elf_Shdr *) ((grub_uint8_t *) shdr + shnum * 
e.e_shentsize);
        s = (Elf_Shdr *) ((grub_uint8_t *) s + e.e_shentsize))
     {
       if (s->sh_size == 0)
@@ -112,7 +124,7 @@ SUFFIX (grub_freebsd_load_elfmodule_obj) (struct 
grub_relocator *relocator,
     chunk_src = get_virtual_current_address (ch);
   }
 
-  for (s = shdr; s < (Elf_Shdr *) ((grub_uint8_t *) shdr + e.e_shnum * 
e.e_shentsize);
+  for (s = shdr; s < (Elf_Shdr *) ((grub_uint8_t *) shdr + shnum * 
e.e_shentsize);
        s = (Elf_Shdr *) ((grub_uint8_t *) s + e.e_shentsize))
     {
       if (s->sh_size == 0)
@@ -155,7 +167,7 @@ SUFFIX (grub_freebsd_load_elfmodule_obj) (struct 
grub_relocator *relocator,
   if (! err)
     err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA
                             | FREEBSD_MODINFOMD_SHDR,
-                            shdr, e.e_shnum * e.e_shentsize);
+                            shdr, shnum * e.e_shentsize);
 
 out:
   grub_free (shdr);
@@ -172,6 +184,7 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator 
*relocator,
   Elf_Ehdr e;
   Elf_Shdr *s;
   Elf_Shdr *shdr = NULL;
+  Elf_Word shnum;
   grub_addr_t curload, module;
   grub_err_t err;
   grub_size_t chunk_size = 0;
@@ -183,7 +196,11 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct 
grub_relocator *relocator,
   if (err)
     goto out;
 
-  for (s = shdr; s < (Elf_Shdr *) ((grub_uint8_t *) shdr + e.e_shnum * 
e.e_shentsize);
+  err = grub_elf_get_shnum (&e, &shnum);
+  if (err != GRUB_ERR_NONE)
+    goto out;
+
+  for (s = shdr; s < (Elf_Shdr *) ((grub_uint8_t *) shdr + shnum * 
e.e_shentsize);
        s = (Elf_Shdr *) ((grub_uint8_t *) s + e.e_shentsize))
     {
       if (s->sh_size == 0)
@@ -198,7 +215,7 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator 
*relocator,
   if (chunk_size < sizeof (e))
     chunk_size = sizeof (e);
   chunk_size += (grub_uint32_t) e.e_phnum * e.e_phentsize;
-  chunk_size += (grub_uint32_t) e.e_shnum * e.e_shentsize;
+  chunk_size += (grub_size_t) shnum * e.e_shentsize;
 
   {
     grub_relocator_chunk_t ch;
@@ -211,7 +228,7 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator 
*relocator,
     chunk_src = get_virtual_current_address (ch);
   }
 
-  for (s = shdr; s < (Elf_Shdr *) ((grub_uint8_t *) shdr + e.e_shnum * 
e.e_shentsize);
+  for (s = shdr; s < (Elf_Shdr *) ((grub_uint8_t *) shdr + shnum * 
e.e_shentsize);
        s = (Elf_Shdr *) ((grub_uint8_t *) s + e.e_shentsize))
     {
       if (s->sh_size == 0)
@@ -249,9 +266,9 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator 
*relocator,
     curload = module + sizeof (e);
 
   load (file, argv[0], (grub_uint8_t *) chunk_src + curload - *kern_end, 
e.e_shoff,
-       (grub_uint32_t) e.e_shnum * e.e_shentsize);
+       (grub_size_t) shnum * e.e_shentsize);
   e.e_shoff = curload - module;
-  curload +=  (grub_uint32_t) e.e_shnum * e.e_shentsize;
+  curload +=  (grub_addr_t) shnum * e.e_shentsize;
 
   load (file, argv[0], (grub_uint8_t *) chunk_src + curload - *kern_end, 
e.e_phoff,
        (grub_uint32_t) e.e_phnum * e.e_phentsize);
@@ -282,6 +299,7 @@ SUFFIX (grub_freebsd_load_elf_meta) (struct grub_relocator 
*relocator,
   Elf_Ehdr e;
   Elf_Shdr *s;
   Elf_Shdr *shdr = NULL;
+  Elf_Word shnum;
   unsigned symoff, stroff, symsize, strsize;
   grub_freebsd_addr_t symstart, symend, symentsize, dynamic;
   Elf_Sym *sym;
@@ -296,17 +314,21 @@ SUFFIX (grub_freebsd_load_elf_meta) (struct 
grub_relocator *relocator,
   if (err)
     goto out;
 
+  err = grub_elf_get_shnum (&e, &shnum);
+  if (err != GRUB_ERR_NONE)
+    goto out;
+
   err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA |
                           FREEBSD_MODINFOMD_ELFHDR, &e,
                           sizeof (e));
   if (err)
     goto out;
 
-  for (s = shdr; s < (Elf_Shdr *) ((grub_uint8_t *) shdr + e.e_shnum * 
e.e_shentsize);
+  for (s = shdr; s < (Elf_Shdr *) ((grub_uint8_t *) shdr + shnum * 
e.e_shentsize);
        s = (Elf_Shdr *) ((grub_uint8_t *) s + e.e_shentsize))
       if (s->sh_type == SHT_SYMTAB)
        break;
-  if (s >= (Elf_Shdr *) ((grub_uint8_t *) shdr + e.e_shnum * e.e_shentsize))
+  if (s >= (Elf_Shdr *) ((grub_uint8_t *) shdr + shnum * e.e_shentsize))
     {
       err = grub_error (GRUB_ERR_BAD_OS, N_("no symbol table"));
       goto out;
@@ -422,6 +444,7 @@ SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator 
*relocator,
   Elf_Ehdr e;
   Elf_Shdr *s, *symsh, *strsh;
   Elf_Shdr *shdr = NULL;
+  Elf_Word shnum;
   unsigned symsize, strsize;
   void *sym_chunk;
   grub_uint8_t *curload;
@@ -437,11 +460,18 @@ SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator 
*relocator,
       return grub_errno;
     }
 
-  for (s = shdr; s < (Elf_Shdr *) ((grub_uint8_t *) shdr + e.e_shnum * 
e.e_shentsize);
+  err = grub_elf_get_shnum (&e, &shnum);
+  if (err != GRUB_ERR_NONE)
+    {
+      grub_free (shdr);
+      return err;
+    }
+
+  for (s = shdr; s < (Elf_Shdr *) ((grub_uint8_t *) shdr + shnum * 
e.e_shentsize);
        s = (Elf_Shdr *) ((grub_uint8_t *) s + e.e_shentsize))
       if (s->sh_type == SHT_SYMTAB)
        break;
-  if (s >= (Elf_Shdr *) ((grub_uint8_t *) shdr + e.e_shnum * e.e_shentsize))
+  if (s >= (Elf_Shdr *) ((char *) shdr + shnum * e.e_shentsize))
     {
       grub_free (shdr);
       return GRUB_ERR_NONE;
@@ -454,7 +484,7 @@ SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator 
*relocator,
 
   chunk_size = ALIGN_UP (symsize, sizeof (grub_freebsd_addr_t))
     + ALIGN_UP (strsize, sizeof (grub_freebsd_addr_t))
-    + sizeof (e) + (grub_uint32_t) e.e_shnum * e.e_shentsize;
+    + sizeof (e) + (grub_uint32_t) shnum * e.e_shentsize;
 
   symtarget = ALIGN_UP (*kern_end, sizeof (grub_freebsd_addr_t));
   {
@@ -482,17 +512,17 @@ SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator 
*relocator,
 
   curload += sizeof (e);
 
-  for (s = shdr; s < (Elf_Shdr *) ((grub_uint8_t *) shdr + e.e_shnum * 
e.e_shentsize);
+  for (s = shdr; s < (Elf_Shdr *) ((grub_uint8_t *) shdr + shnum * 
e.e_shentsize);
        s = (Elf_Shdr *) ((grub_uint8_t *) s + e.e_shentsize))
     {
       Elf_Shdr *s2;
       s2 = (Elf_Shdr *) curload;
       grub_memcpy (curload, s, e.e_shentsize);
       if (s == symsh)
-       s2->sh_offset = sizeof (e) + (grub_uint32_t) e.e_shnum * e.e_shentsize;
+       s2->sh_offset = sizeof (e) + (grub_uint32_t) shnum * e.e_shentsize;
       else if (s == strsh)
        s2->sh_offset = ALIGN_UP (symsize, sizeof (grub_freebsd_addr_t))
-         + sizeof (e) + (grub_uint32_t) e.e_shnum * e.e_shentsize;
+         + sizeof (e) + (grub_uint32_t) shnum * e.e_shentsize;
       else
        s2->sh_offset = 0;
       s2->sh_addr = s2->sh_offset;
@@ -557,6 +587,7 @@ SUFFIX(grub_openbsd_find_ramdisk) (grub_file_t file,
     Elf_Ehdr e;
     Elf_Shdr *s;
     Elf_Shdr *shdr = NULL;
+    Elf_Word shnum;
 
     err = read_headers (file, filename, &e, &shdr);
     if (err)
@@ -565,11 +596,18 @@ SUFFIX(grub_openbsd_find_ramdisk) (grub_file_t file,
        return err;
       }
 
-    for (s = shdr; s < (Elf_Shdr *) ((grub_uint8_t *) shdr + e.e_shnum * 
e.e_shentsize);
+    err = grub_elf_get_shnum (&e, &shnum);
+    if (err != GRUB_ERR_NONE)
+      {
+       grub_free (shdr);
+       return err;
+      }
+
+    for (s = shdr; s < (Elf_Shdr *) ((grub_uint8_t *) shdr + shnum * 
e.e_shentsize);
         s = (Elf_Shdr *) ((grub_uint8_t *) s + e.e_shentsize))
       if (s->sh_type == SHT_SYMTAB)
        break;
-    if (s >= (Elf_Shdr *) ((grub_uint8_t *) shdr + e.e_shnum * e.e_shentsize))
+    if (s >= (Elf_Shdr *) ((grub_uint8_t *) shdr + shnum * e.e_shentsize))
       {
        grub_free (shdr);
        return GRUB_ERR_NONE;
diff --git a/grub-core/loader/multiboot_elfxx.c 
b/grub-core/loader/multiboot_elfxx.c
index 6801f0ddf..1fe9be91b 100644
--- a/grub-core/loader/multiboot_elfxx.c
+++ b/grub-core/loader/multiboot_elfxx.c
@@ -17,19 +17,23 @@
  */
 
 #if defined(MULTIBOOT_LOAD_ELF32)
-# define XX            32
-# define E_MACHINE     MULTIBOOT_ELF32_MACHINE
-# define ELFCLASSXX    ELFCLASS32
-# define Elf_Ehdr      Elf32_Ehdr
-# define Elf_Phdr      Elf32_Phdr
-# define Elf_Shdr      Elf32_Shdr
+# define XX                    32
+# define E_MACHINE             MULTIBOOT_ELF32_MACHINE
+# define ELFCLASSXX            ELFCLASS32
+# define Elf_Ehdr              Elf32_Ehdr
+# define Elf_Phdr              Elf32_Phdr
+# define Elf_Shdr              Elf32_Shdr
+# define Elf_Word              Elf32_Word
+# define grub_elf_get_shnum    grub_elf32_get_shnum
 #elif defined(MULTIBOOT_LOAD_ELF64)
-# define XX            64
-# define E_MACHINE     MULTIBOOT_ELF64_MACHINE
-# define ELFCLASSXX    ELFCLASS64
-# define Elf_Ehdr      Elf64_Ehdr
-# define Elf_Phdr      Elf64_Phdr
-# define Elf_Shdr      Elf64_Shdr
+# define XX                    64
+# define E_MACHINE             MULTIBOOT_ELF64_MACHINE
+# define ELFCLASSXX            ELFCLASS64
+# define Elf_Ehdr              Elf64_Ehdr
+# define Elf_Phdr              Elf64_Phdr
+# define Elf_Shdr              Elf64_Shdr
+# define Elf_Word              Elf64_Word
+# define grub_elf_get_shnum    grub_elf64_get_shnum
 #else
 #error "I'm confused"
 #endif
@@ -58,7 +62,8 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
   grub_err_t err;
   grub_relocator_chunk_t ch;
   grub_uint32_t load_offset = 0, load_size;
-  int i;
+  Elf_Word shnum;
+  unsigned int i;
   void *source = NULL;
 
   if (ehdr->e_ident[EI_MAG0] != ELFMAG0
@@ -75,6 +80,10 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
   if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
     return grub_error (GRUB_ERR_UNKNOWN_OS, N_("this ELF file is not of the 
right type"));
 
+  err = grub_elf_get_shnum (ehdr, &shnum);
+  if (err != GRUB_ERR_NONE)
+    return err;
+
   /* FIXME: Should we support program headers at strange locations?  */
   if (ehdr->e_phoff + (grub_uint32_t) ehdr->e_phnum * ehdr->e_phentsize > 
MULTIBOOT_SEARCH)
     return grub_error (GRUB_ERR_BAD_OS, "program header at a too high offset");
@@ -213,11 +222,11 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
 #error Please complete this
 #endif
 
-  if (ehdr->e_shnum)
+  if (shnum)
     {
       grub_uint8_t *shdr, *shdrptr;
 
-      shdr = grub_calloc (ehdr->e_shnum, ehdr->e_shentsize);
+      shdr = grub_calloc (shnum, ehdr->e_shentsize);
       if (!shdr)
        return grub_errno;
 
@@ -227,8 +236,8 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
          return grub_errno;
        }
 
-      if (grub_file_read (mld->file, shdr, (grub_uint32_t) ehdr->e_shnum * 
ehdr->e_shentsize)
-              != (grub_ssize_t) ehdr->e_shnum * ehdr->e_shentsize)
+      if (grub_file_read (mld->file, shdr, (grub_ssize_t) shnum * 
ehdr->e_shentsize)
+              != (grub_ssize_t) shnum * ehdr->e_shentsize)
        {
          if (!grub_errno)
            grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file 
%s"),
@@ -236,7 +245,7 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
          return grub_errno;
        }
 
-      for (shdrptr = shdr, i = 0; i < ehdr->e_shnum;
+      for (shdrptr = shdr, i = 0; i < shnum;
           shdrptr += ehdr->e_shentsize, i++)
        {
          Elf_Shdr *sh = (Elf_Shdr *) shdrptr;
@@ -281,7 +290,7 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
            }
          sh->sh_addr = target;
        }
-      GRUB_MULTIBOOT (add_elfsyms) (ehdr->e_shnum, ehdr->e_shentsize,
+      GRUB_MULTIBOOT (add_elfsyms) (shnum, ehdr->e_shentsize,
                                    ehdr->e_shstrndx, shdr);
     }
 
@@ -296,3 +305,5 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
 #undef Elf_Ehdr
 #undef Elf_Phdr
 #undef Elf_Shdr
+#undef Elf_Word
+#undef grub_elf_get_shnum
diff --git a/include/grub/elf.h b/include/grub/elf.h
index c478933ee..229efd349 100644
--- a/include/grub/elf.h
+++ b/include/grub/elf.h
@@ -23,6 +23,7 @@
 /* Standard ELF types.  */
 
 #include <grub/types.h>
+#include <grub/err.h>
 
 /* Type for a 16-bit quantity.  */
 typedef grub_uint16_t Elf32_Half;
@@ -2531,6 +2532,10 @@ typedef Elf32_Addr Elf32_Conflict;
 #define R_RISCV_SET32           56
 #define R_RISCV_32_PCREL        57
 
+extern grub_err_t grub_elf32_get_shnum (Elf32_Ehdr *e, Elf32_Word *shnum);
+
+extern grub_err_t grub_elf64_get_shnum (Elf64_Ehdr *e, Elf64_Word *shnum);
+
 #ifdef GRUB_TARGET_WORDSIZE
 #if GRUB_TARGET_WORDSIZE == 32
 
@@ -2557,6 +2562,8 @@ typedef Elf32_Xword Elf_Xword;
 #define ELF_R_TYPE(val)                ELF32_R_TYPE(val)
 #define ELF_R_INFO(sym, type)  ELF32_R_INFO(sym, type)
 
+#define grub_elf_get_shnum     grub_elf32_get_shnum
+
 #elif GRUB_TARGET_WORDSIZE == 64
 
 typedef Elf64_Addr Elf_Addr;
@@ -2581,6 +2588,8 @@ typedef Elf64_Xword Elf_Xword;
 #define ELF_R_TYPE(val)                ELF64_R_TYPE(val)
 #define ELF_R_INFO(sym, type)  ELF64_R_INFO(sym, type)
 
+#define grub_elf_get_shnum     grub_elf64_get_shnum
+
 #endif /* GRUB_TARGET_WORDSIZE == 64 */
 #endif
 
-- 
2.27.0




reply via email to

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