diff options
author | Roland McGrath <roland@redhat.com> | 2014-01-17 17:11:39 +0100 |
---|---|---|
committer | Mark Wielaard <mjw@redhat.com> | 2014-01-23 11:31:53 +0100 |
commit | 7d5b301cc33252a24f287ce41a400b262bbad8d8 (patch) | |
tree | 633a675f37bbbb4cbb3e5ba93b69ccec21b853d3 | |
parent | 71c1534c9c7a0652fb6c5f9295baa08f32b0b166 (diff) | |
download | elfutils-7d5b301cc33252a24f287ce41a400b262bbad8d8.tar.gz |
robustify: readelf.
Signed-off-by: Mark Wielaard <mjw@redhat.com>
-rw-r--r-- | src/ChangeLog | 6 | ||||
-rw-r--r-- | src/readelf.c | 80 |
2 files changed, 60 insertions, 26 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 9fdc9f91..0f8a1c3f 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2014-01-17 Roland McGrath <roland@redhat.com> + + * readelf.c (handle_dynamic, handle_symtab): Check for bogus sh_link. + (handle_verneed, handle_verdef, handle_versym, handle_hash): Likewise. + (handle_scngrp): Check for bogus sh_info. + 2014-01-17 Jakub Jelinek <jakub@redhat.com> * elflint.c (section_name): Return "<invalid>" instead of diff --git a/src/readelf.c b/src/readelf.c index a6376087..5c5ad3d8 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -1364,6 +1364,8 @@ handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) Elf32_Word *grpref = (Elf32_Word *) data->d_buf; GElf_Sym sym_mem; + GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem); + printf ((grpref[0] & GRP_COMDAT) ? ngettext ("\ \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n", @@ -1376,8 +1378,8 @@ handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) data->d_size / sizeof (Elf32_Word) - 1), elf_ndxscn (scn), elf_strptr (ebl->elf, shstrndx, shdr->sh_name), - elf_strptr (ebl->elf, symshdr->sh_link, - gelf_getsym (symdata, shdr->sh_info, &sym_mem)->st_name) + (sym == NULL ? NULL + : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name)) ?: gettext ("<INVALID SYMBOL>"), data->d_size / sizeof (Elf32_Word) - 1); @@ -1528,7 +1530,8 @@ static void handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) { int class = gelf_getclass (ebl->elf); - GElf_Shdr glink; + GElf_Shdr glink_mem; + GElf_Shdr *glink; Elf_Data *data; size_t cnt; size_t shstrndx; @@ -1560,9 +1563,7 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, shdr->sh_offset, (int) shdr->sh_link, - elf_strptr (ebl->elf, shstrndx, - gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), - &glink)->sh_name)); + elf_strptr (ebl->elf, shstrndx, glink->sh_name)); fputs_unlocked (gettext (" Type Value\n"), stdout); for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt) @@ -2149,6 +2150,13 @@ handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) error (EXIT_FAILURE, 0, gettext ("cannot get section header string table index")); + GElf_Shdr glink_mem; + GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), + &glink_mem); + if (glink == NULL) + error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"), + elf_ndxscn (scn)); + /* Now we can compute the number of entries in the section. */ unsigned int nsyms = data->d_size / (class == ELFCLASS32 ? sizeof (Elf32_Sym) @@ -2159,15 +2167,12 @@ handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) nsyms), (unsigned int) elf_ndxscn (scn), elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms); - GElf_Shdr glink; printf (ngettext (" %lu local symbol String table: [%2u] '%s'\n", " %lu local symbols String table: [%2u] '%s'\n", shdr->sh_info), (unsigned long int) shdr->sh_info, (unsigned int) shdr->sh_link, - elf_strptr (ebl->elf, shstrndx, - gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), - &glink)->sh_name)); + elf_strptr (ebl->elf, shstrndx, glink->sh_name)); fputs_unlocked (class == ELFCLASS32 ? gettext ("\ @@ -2403,7 +2408,13 @@ handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) error (EXIT_FAILURE, 0, gettext ("cannot get section header string table index")); - GElf_Shdr glink; + GElf_Shdr glink_mem; + GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), + &glink_mem); + if (glink == NULL) + error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"), + elf_ndxscn (scn)); + printf (ngettext ("\ \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", "\ @@ -2414,9 +2425,7 @@ handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, shdr->sh_offset, (unsigned int) shdr->sh_link, - elf_strptr (ebl->elf, shstrndx, - gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), - &glink)->sh_name)); + elf_strptr (ebl->elf, shstrndx, glink->sh_name)); unsigned int offset = 0; for (int cnt = shdr->sh_info; --cnt >= 0; ) @@ -2469,8 +2478,14 @@ handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) error (EXIT_FAILURE, 0, gettext ("cannot get section header string table index")); + GElf_Shdr glink_mem; + GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), + &glink_mem); + if (glink == NULL) + error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %Zu"), + elf_ndxscn (scn)); + int class = gelf_getclass (ebl->elf); - GElf_Shdr glink; printf (ngettext ("\ \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", "\ @@ -2482,9 +2497,7 @@ handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, shdr->sh_offset, (unsigned int) shdr->sh_link, - elf_strptr (ebl->elf, shstrndx, - gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), - &glink)->sh_name)); + elf_strptr (ebl->elf, shstrndx, glink->sh_name)); unsigned int offset = 0; for (int cnt = shdr->sh_info; --cnt >= 0; ) @@ -2755,7 +2768,6 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) elf_ndxscn (scn)); /* Print the header. */ - GElf_Shdr glink; printf (ngettext ("\ \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'", "\ @@ -2767,9 +2779,7 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, shdr->sh_offset, (unsigned int) shdr->sh_link, - elf_strptr (ebl->elf, shstrndx, - gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), - &glink)->sh_name)); + elf_strptr (ebl->elf, shstrndx, glink->sh_name)); /* Now we can finally look at the actual contents of this section. */ for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt) @@ -2821,7 +2831,17 @@ print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx, for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt) ++counts[lengths[cnt]]; - GElf_Shdr glink; + GElf_Shdr glink_mem; + GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, + shdr->sh_link), + &glink_mem); + if (glink == NULL) + { + error (0, 0, gettext ("invalid sh_link value in section %Zu"), + elf_ndxscn (scn)); + return; + } + printf (ngettext ("\ \nHistogram for bucket list length in section [%2u] '%s' (total of %d bucket):\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", "\ @@ -2834,9 +2854,7 @@ print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx, shdr->sh_addr, shdr->sh_offset, (unsigned int) shdr->sh_link, - elf_strptr (ebl->elf, shstrndx, - gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), - &glink)->sh_name)); + elf_strptr (ebl->elf, shstrndx, glink->sh_name)); if (extrastr != NULL) fputs (extrastr, stdout); @@ -4417,6 +4435,16 @@ print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, return; } + GElf_Shdr glink_mem; + GElf_Shdr *glink; + glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem); + if (glink == NULL) + { + error (0, 0, gettext ("invalid sh_link value in section %Zu"), + elf_ndxscn (scn)); + return; + } + printf (ngettext ("\ \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n", "\ |