mirror of
https://git.savannah.gnu.org/git/grub.git
synced 2026-10-21 06:49:35 +00:00
elf: Validate number of elf program header table entries
In bsdXX.c and multiboot_elfxx.c, e_phnum is used to obtain the number of program 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 program header table is larger than or equal to PN_XNUM (0xffff), this member holds PN_XNUM (0xffff) and the real number of entries in the program header table is held in the sh_info member of the initial entry in section header table. Otherwise, the sh_info member of the initial entry contains the value zero." Since this check wasn't being made, grub_elfXX_get_phnum() is being added to elfXX.c to make this check and use e_phnum if it doesn't have PN_XNUM as a value, else use sh_info. We also need to make sure e_phnum isn't greater than PN_XNUM and sh_info isn't less than PN_XNUM. 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. Also, changed casts of phnum to match variables being set as well as dropped casts when unnecessary. Signed-off-by: Alec Brown <alec.r.brown@oracle.com> Reviewed-by: Darren Kenny <darren.kenny@oracle.com> Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This commit is contained in:
1 parent
385d906007
commit
ddb6c1bafb
5 files changed
+63
-9
No files matched your search
@@ -183,6 +183,7 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator *relocator,
|
||||
Elf_Ehdr e;
|
||||
Elf_Shdr *s, *shdr = NULL;
|
||||
Elf_Shnum shnum;
|
||||
Elf_Word phnum;
|
||||
grub_addr_t curload, module;
|
||||
grub_err_t err;
|
||||
grub_size_t chunk_size = 0;
|
||||
@@ -198,6 +199,10 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator *relocator,
|
||||
if (err != GRUB_ERR_NONE)
|
||||
goto out;
|
||||
|
||||
err = grub_elf_get_phnum (&e, &phnum);
|
||||
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))
|
||||
{
|
||||
@@ -212,7 +217,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_size_t) phnum * e.e_phentsize;
|
||||
chunk_size += (grub_size_t) shnum * e.e_shentsize;
|
||||
|
||||
{
|
||||
@@ -269,9 +274,9 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator *relocator,
|
||||
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);
|
||||
(grub_size_t) phnum * e.e_phentsize);
|
||||
e.e_phoff = curload - module;
|
||||
curload += (grub_uint32_t) e.e_phnum * e.e_phentsize;
|
||||
curload += (grub_addr_t) phnum * e.e_phentsize;
|
||||
|
||||
*kern_end = curload;
|
||||
|
||||
|
||||
Reference in new issue
Block a user