This is the mail archive of the
binutils-cvs@sourceware.org
mailing list for the binutils project.
[binutils-gdb] Fix seg fault objdumping a corrupt binary with an invalid sh_link field.
- From: Nick Clifton <nickc at sourceware dot org>
- To: bfd-cvs at sourceware dot org
- Date: 9 May 2016 16:31:57 -0000
- Subject: [binutils-gdb] Fix seg fault objdumping a corrupt binary with an invalid sh_link field.
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=315350be6598235df12a0190a5a4c21447eead36
commit 315350be6598235df12a0190a5a4c21447eead36
Author: Nick Clifton <nickc@redhat.com>
Date: Mon May 9 17:31:07 2016 +0100
Fix seg fault objdumping a corrupt binary with an invalid sh_link field.
PR binutils/20063
* elf.c (bfd_elf_get_elf_syms): Check for out of range sh_link
field before accessing sections array.
* readelf.c (get_32bit_section_headers): Warn if an out of range
sh_link or sh_info field is encountered.
(get_64bit_section_headers): Likewise.
Diff:
---
bfd/ChangeLog | 6 ++++++
bfd/elf.c | 16 +++++++++++-----
binutils/ChangeLog | 7 +++++++
binutils/readelf.c | 8 ++++++++
4 files changed, 32 insertions(+), 5 deletions(-)
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index d5edec4..29dad01 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,9 @@
+2016-05-09 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/20063
+ * elf.c (bfd_elf_get_elf_syms): Check for out of range sh_link
+ field before accessing sections array.
+
2016-05-09 Christophe Monat <christophe.monat@st.com>
PR ld/20030
diff --git a/bfd/elf.c b/bfd/elf.c
index 4be7d73..1592183 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -407,11 +407,17 @@ bfd_elf_get_elf_syms (bfd *ibfd,
/* Find an index section that is linked to this symtab section. */
for (entry = elf_symtab_shndx_list (ibfd); entry != NULL; entry = entry->next)
- if (sections[entry->hdr.sh_link] == symtab_hdr)
- {
- shndx_hdr = & entry->hdr;
- break;
- };
+ {
+ /* PR 20063. */
+ if (entry->hdr.sh_link >= elf_numsections (ibfd))
+ continue;
+
+ if (sections[entry->hdr.sh_link] == symtab_hdr)
+ {
+ shndx_hdr = & entry->hdr;
+ break;
+ };
+ }
if (shndx_hdr == NULL)
{
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 12e8bb2..89ebe15 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,10 @@
+2016-05-09 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/20063
+ * readelf.c (get_32bit_section_headers): Warn if an out of range
+ sh_link or sh_info field is encountered.
+ (get_64bit_section_headers): Likewise.
+
2016-05-04 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
* testsuite/lib/binutils-common.exp (is_elf_format): Add avr-*-*.
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 3d31b38..13e7751 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -5059,6 +5059,10 @@ get_32bit_section_headers (FILE * file, bfd_boolean probe)
internal->sh_info = BYTE_GET (shdrs[i].sh_info);
internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
+ if (!probe && internal->sh_link > num)
+ warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
+ if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
+ warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
}
free (shdrs);
@@ -5117,6 +5121,10 @@ get_64bit_section_headers (FILE * file, bfd_boolean probe)
internal->sh_info = BYTE_GET (shdrs[i].sh_info);
internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
+ if (!probe && internal->sh_link > num)
+ warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
+ if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
+ warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
}
free (shdrs);