aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlec Brown <alec.r.brown@oracle.com>2022-02-02 19:26:59 -0500
committerDaniel Kiper <daniel.kiper@oracle.com>2022-02-08 16:06:50 +0100
commitaeff4a1dc18420ec2bf15ce8121bac39c28b9357 (patch)
tree4adab52487420b18822832a7ef20899d795e6d90
parentcdb21e0b9cbbde8f60e481f245092c7d61f90905 (diff)
downloadgrub-aeff4a1dc18420ec2bf15ce8121bac39c28b9357.tar.gz
util/grub-module-verifierXX: Validate elf section header table index for section name string table
In grub-module-verifierXX.c, the function find_section() uses the value from grub_target_to_host16 (e->e_shstrndx) to obtain the section header table index of the section name string table, but it wasn't being checked if the value was there. According to the elf(5) manual page, "If the index of section name string table section is larger than or equal to SHN_LORESERVE (0xff00), this member holds SHN_XINDEX (0xffff) and the real index of the section name string table section is held in the sh_link member of the initial entry in section header table. Otherwise, the sh_link member of the initial entry in section header table contains the value zero." Since this check wasn't being made, the function get_shstrndx() is being added to make this check and use e_shstrndx if it doesn't have SHN_XINDEX as a value, else use sh_link. We also need to make sure e_shstrndx isn't greater than or equal to SHN_LORESERVE and sh_link isn't less than SHN_LORESERVE. Note that it may look as though the argument *arch isn't being used, it's actually required in order to use the macros grub_target_to_host*(x) which are unwinded to grub_target_to_host*_real(arch, (x)) based on defines earlier in the file. 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>
-rw-r--r--util/grub-module-verifierXX.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/util/grub-module-verifierXX.c b/util/grub-module-verifierXX.c
index a9fbf3ab6..4e6cf133f 100644
--- a/util/grub-module-verifierXX.c
+++ b/util/grub-module-verifierXX.c
@@ -161,6 +161,29 @@ get_shnum (const struct grub_module_verifier_arch *arch, Elf_Ehdr *e)
return shnum;
}
+static Elf_Word
+get_shstrndx (const struct grub_module_verifier_arch *arch, Elf_Ehdr *e)
+{
+ Elf_Shdr *s;
+ Elf_Word shstrndx;
+
+ shstrndx = grub_target_to_host16 (e->e_shstrndx);
+ if (shstrndx == SHN_XINDEX)
+ {
+ s = get_shdr (arch, e, 0);
+ shstrndx = grub_target_to_host (s->sh_link);
+ if (shstrndx < SHN_LORESERVE)
+ grub_util_error ("Invalid section header table index in sh_link: %d", shstrndx);
+ }
+ else
+ {
+ if (shstrndx >= SHN_LORESERVE)
+ grub_util_error ("Invalid section header table index in e_shstrndx: %d", shstrndx);
+ }
+
+ return shstrndx;
+}
+
static Elf_Shdr *
find_section (const struct grub_module_verifier_arch *arch, Elf_Ehdr *e, const char *name)
{
@@ -168,7 +191,7 @@ find_section (const struct grub_module_verifier_arch *arch, Elf_Ehdr *e, const c
const char *str;
unsigned i;
- s = get_shdr (arch, e, grub_target_to_host16 (e->e_shstrndx));
+ s = get_shdr (arch, e, get_shstrndx (arch, e));
str = (char *) e + grub_target_to_host (s->sh_offset);
for (i = 0, s = get_shdr (arch, e, 0);