From ba2a7f4fa5f453c2b0a729bf519240a8f66a1867 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Sat, 4 Aug 2018 20:36:09 +0200 Subject: [PATCH] backends: Always use elf_getshdrstrndx in check_special_symbol. The check_special_symbol backend functions used the Ehdr e_shstrndx field to get at the name of sections. This is not correct if there are more than SHN_LORESERVE sections. Always use elf_getshdrstrndx to get the shstrtab section. And drop the Ehdr argument that isn't necessary anymore. Signed-off-by: Mark Wielaard --- backends/ChangeLog | 10 ++++++++++ backends/aarch64_symbol.c | 9 ++++++--- backends/alpha_symbol.c | 1 - backends/ppc64_symbol.c | 7 +++++-- backends/ppc_symbol.c | 7 +++++-- backends/riscv_symbol.c | 7 +++++-- libebl/ChangeLog | 7 +++++++ libebl/ebl-hooks.h | 2 +- libebl/ebl_check_special_symbol.c | 4 ++-- libebl/eblopenbackend.c | 3 +-- libebl/libebl.h | 2 +- src/ChangeLog | 5 +++++ src/elflint.c | 4 ++-- 13 files changed, 50 insertions(+), 18 deletions(-) diff --git a/backends/ChangeLog b/backends/ChangeLog index 5214948..ada349f 100644 --- a/backends/ChangeLog +++ b/backends/ChangeLog @@ -1,3 +1,13 @@ +2018-09-12 Mark Wielaard + + * aarch64_symbol.c (aarch64_check_special_symbol): Drop ehdr argument, + use elf_getshdrstrndx. + * alpha_symbol.c (alpha_check_special_symbol): Drop ehdr argument. + * ppc64_symbol.c (ppc64_check_special_symbol): Likewise and use + elf_getshdrstrndx. + * ppc_symbol.c (ppc_check_special_symbol): Likewise. + * riscv_symbol.c (riscv_check_special_symbol): Likewise. + 2018-07-21 Andreas Schwab * Makefile.am (m68k_SRCS): Add m68k_cfi.c and m68k_initreg.c. diff --git a/backends/aarch64_symbol.c b/backends/aarch64_symbol.c index da3382e..dfd755a 100644 --- a/backends/aarch64_symbol.c +++ b/backends/aarch64_symbol.c @@ -62,13 +62,16 @@ aarch64_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type) https://bugzilla.redhat.com/show_bug.cgi?id=1201778 */ bool -aarch64_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr, const GElf_Sym *sym, +aarch64_check_special_symbol (Elf *elf, const GElf_Sym *sym, const char *name, const GElf_Shdr *destshdr) { if (name != NULL && strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0) { - const char *sname = elf_strptr (elf, ehdr->e_shstrndx, destshdr->sh_name); + size_t shstrndx; + if (elf_getshdrstrndx (elf, &shstrndx) != 0) + return false; + const char *sname = elf_strptr (elf, shstrndx, destshdr->sh_name); if (sname != NULL && (strcmp (sname, ".got") == 0 || strcmp (sname, ".got.plt") == 0)) { @@ -79,7 +82,7 @@ aarch64_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr, const GElf_Sym *sym, GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); if (shdr != NULL) { - sname = elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name); + sname = elf_strptr (elf, shstrndx, shdr->sh_name); if (sname != NULL && strcmp (sname, ".got") == 0) return (sym->st_value >= shdr->sh_addr && sym->st_value < shdr->sh_addr + shdr->sh_size); diff --git a/backends/alpha_symbol.c b/backends/alpha_symbol.c index 657d9ee..b7f7c17 100644 --- a/backends/alpha_symbol.c +++ b/backends/alpha_symbol.c @@ -130,7 +130,6 @@ alpha_check_special_section (Ebl *ebl, normal checks. */ bool alpha_check_special_symbol (Elf *elf __attribute__ ((unused)), - GElf_Ehdr *ehdr __attribute__ ((unused)), const GElf_Sym *sym __attribute__ ((unused)), const char *name, const GElf_Shdr *destshdr __attribute__ ((unused))) diff --git a/backends/ppc64_symbol.c b/backends/ppc64_symbol.c index 0feddce..40ba4f7 100644 --- a/backends/ppc64_symbol.c +++ b/backends/ppc64_symbol.c @@ -94,12 +94,15 @@ ppc64_dynamic_tag_check (int64_t tag) /* Check whether given symbol's st_value and st_size are OK despite failing normal checks. */ bool -ppc64_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr, +ppc64_check_special_symbol (Elf *elf, const GElf_Sym *sym __attribute__ ((unused)), const char *name __attribute__ ((unused)), const GElf_Shdr *destshdr) { - const char *sname = elf_strptr (elf, ehdr->e_shstrndx, destshdr->sh_name); + size_t shstrndx; + if (elf_getshdrstrndx (elf, &shstrndx) != 0) + return false; + const char *sname = elf_strptr (elf, shstrndx, destshdr->sh_name); if (sname == NULL) return false; return strcmp (sname, ".opd") == 0; diff --git a/backends/ppc_symbol.c b/backends/ppc_symbol.c index 4b32003..35b1431 100644 --- a/backends/ppc_symbol.c +++ b/backends/ppc_symbol.c @@ -135,7 +135,7 @@ find_dyn_got (Elf *elf, GElf_Addr *addr) /* Check whether given symbol's st_value and st_size are OK despite failing normal checks. */ bool -ppc_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr, const GElf_Sym *sym, +ppc_check_special_symbol (Elf *elf, const GElf_Sym *sym, const char *name, const GElf_Shdr *destshdr) { if (name == NULL) @@ -152,7 +152,10 @@ ppc_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr, const GElf_Sym *sym, return true; } - const char *sname = elf_strptr (elf, ehdr->e_shstrndx, destshdr->sh_name); + size_t shstrndx; + if (elf_getshdrstrndx (elf, &shstrndx) != 0) + return false; + const char *sname = elf_strptr (elf, shstrndx, destshdr->sh_name); if (sname == NULL) return false; diff --git a/backends/riscv_symbol.c b/backends/riscv_symbol.c index dce8e35..866a2d7 100644 --- a/backends/riscv_symbol.c +++ b/backends/riscv_symbol.c @@ -64,13 +64,16 @@ riscv_machine_flag_check (GElf_Word flags) /* Check whether given symbol's st_value and st_size are OK despite failing normal checks. */ bool -riscv_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr, const GElf_Sym *sym, +riscv_check_special_symbol (Elf *elf, const GElf_Sym *sym, const char *name, const GElf_Shdr *destshdr) { if (name == NULL) return false; - const char *sname = elf_strptr (elf, ehdr->e_shstrndx, destshdr->sh_name); + size_t shstrndx; + if (elf_getshdrstrndx (elf, &shstrndx) != 0) + return false; + const char *sname = elf_strptr (elf, shstrndx, destshdr->sh_name); if (sname == NULL) return false; diff --git a/libebl/ChangeLog b/libebl/ChangeLog index f76afd1..574aae6 100644 --- a/libebl/ChangeLog +++ b/libebl/ChangeLog @@ -1,3 +1,10 @@ +2018-09-12 Mark Wielaard + + * ebl-hooks.h (check_special_symbol): Drop ehdr argument. + * ebl_check_special_symbol.c (ebl_check_special_symbol): Likewise. + * eblopenbackend.c (default_check_special_symbol): Likewise. + * libebl.h (ebl_check_special_symbol): Likewise. + 2018-07-04 Ross Burton * eblopenbackend.c: Remove error.h include. diff --git a/libebl/ebl-hooks.h b/libebl/ebl-hooks.h index f3a0e64..7a355cd 100644 --- a/libebl/ebl-hooks.h +++ b/libebl/ebl-hooks.h @@ -118,7 +118,7 @@ bool EBLHOOK(none_reloc_p) (int); bool EBLHOOK(relative_reloc_p) (int); /* Check whether given symbol's value is ok despite normal checks. */ -bool EBLHOOK(check_special_symbol) (Elf *, GElf_Ehdr *, const GElf_Sym *, +bool EBLHOOK(check_special_symbol) (Elf *, const GElf_Sym *, const char *, const GElf_Shdr *); /* Check if this is a data marker symbol. e.g. '$d' symbols for ARM. */ diff --git a/libebl/ebl_check_special_symbol.c b/libebl/ebl_check_special_symbol.c index bdcb026..1f60c3f 100644 --- a/libebl/ebl_check_special_symbol.c +++ b/libebl/ebl_check_special_symbol.c @@ -35,11 +35,11 @@ bool -ebl_check_special_symbol (Ebl *ebl, GElf_Ehdr *ehdr, const GElf_Sym *sym, +ebl_check_special_symbol (Ebl *ebl, const GElf_Sym *sym, const char *name, const GElf_Shdr *destshdr) { if (ebl == NULL) return false; - return ebl->check_special_symbol (ebl->elf, ehdr, sym, name, destshdr); + return ebl->check_special_symbol (ebl->elf, sym, name, destshdr); } diff --git a/libebl/eblopenbackend.c b/libebl/eblopenbackend.c index 1962e60..f5b3de2 100644 --- a/libebl/eblopenbackend.c +++ b/libebl/eblopenbackend.c @@ -181,7 +181,7 @@ static bool default_debugscn_p (const char *name); static bool default_copy_reloc_p (int reloc); static bool default_none_reloc_p (int reloc); static bool default_relative_reloc_p (int reloc); -static bool default_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr, +static bool default_check_special_symbol (Elf *elf, const GElf_Sym *sym, const char *name, const GElf_Shdr *destshdr); @@ -673,7 +673,6 @@ strong_alias (default_copy_reloc_p, default_relative_reloc_p) static bool default_check_special_symbol (Elf *elf __attribute__ ((unused)), - GElf_Ehdr *ehdr __attribute__ ((unused)), const GElf_Sym *sym __attribute__ ((unused)), const char *name __attribute__ ((unused)), const GElf_Shdr *destshdr __attribute__ ((unused))) diff --git a/libebl/libebl.h b/libebl/libebl.h index 882bdb9..0e1f41b 100644 --- a/libebl/libebl.h +++ b/libebl/libebl.h @@ -152,7 +152,7 @@ extern bool ebl_dynamic_tag_check (Ebl *ebl, int64_t tag); /* Check whether given symbol's st_value and st_size are OK despite failing normal checks. */ -extern bool ebl_check_special_symbol (Ebl *ebl, GElf_Ehdr *ehdr, +extern bool ebl_check_special_symbol (Ebl *ebl, const GElf_Sym *sym, const char *name, const GElf_Shdr *destshdr); diff --git a/src/ChangeLog b/src/ChangeLog index 29d3644..a118519 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2018-09-12 Mark Wielaard + + * elflint.c (check_symtab): Call ebl_check_special_symbol without + ehdr. + 2018-07-30 Mark Wielaard * strip.c (handle_elf): Track allocated/unallocated sections seen. Set diff --git a/src/elflint.c b/src/elflint.c index 90e8fed..b49436c 100644 --- a/src/elflint.c +++ b/src/elflint.c @@ -796,7 +796,7 @@ section [%2d] '%s': symbol %zu: function in COMMON section is nonsense\n"), st_value = sym->st_value; if (GELF_ST_TYPE (sym->st_info) != STT_TLS) { - if (! ebl_check_special_symbol (ebl, ehdr, sym, name, + if (! ebl_check_special_symbol (ebl, sym, name, destshdr)) { if (st_value - sh_addr > destshdr->sh_size) @@ -997,7 +997,7 @@ section [%2d] '%s'\n"), if (destshdr != NULL) { /* Found it. */ - if (!ebl_check_special_symbol (ebl, ehdr, sym, name, + if (!ebl_check_special_symbol (ebl, sym, name, destshdr)) { if (ehdr->e_type != ET_REL -- 2.7.4