aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2017-12-06 17:32:48 +1030
committerAlan Modra <amodra@gmail.com>2017-12-06 18:05:18 +1030
commit9c1ce1085070f42718e341d89a28881edd96161f (patch)
tree1c2d97c4b9386682093093afd318bdc71f4a792f
parent07d6d2b8345ef3dc82eab49635acac9ee67dbb18 (diff)
downloadfsf-binutils-gdb-9c1ce1085070f42718e341d89a28881edd96161f.zip
fsf-binutils-gdb-9c1ce1085070f42718e341d89a28881edd96161f.tar.gz
fsf-binutils-gdb-9c1ce1085070f42718e341d89a28881edd96161f.tar.bz2
PR22552, readelf heap buffer overflow in load_debug_section
PR 22552 * readelf.c (process_file_header): Don't assume XINDEX case value for e_shstrndx is within bounds. (load_debug_section): Sanity test e_shstrndx before attempting to read .shstrtab. Wrap long lines.
-rw-r--r--binutils/ChangeLog8
-rw-r--r--binutils/readelf.c15
2 files changed, 17 insertions, 6 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 5139c6b..cf0df39 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,11 @@
+2017-12-06 Alan Modra <amodra@gmail.com>
+
+ PR 22552
+ * readelf.c (process_file_header): Don't assume XINDEX case
+ value for e_shstrndx is within bounds.
+ (load_debug_section): Sanity test e_shstrndx before attempting
+ to read .shstrtab. Wrap long lines.
+
2017-12-01 Oleksandr Pikozh <o.pikozh@gmail.com>
* doc/binutils.texi: Add --strip-unneeded to objcopy synopsis.
diff --git a/binutils/readelf.c b/binutils/readelf.c
index e0230c7..8a31ebb 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -4761,7 +4761,7 @@ process_file_header (Filedata * filedata)
header->e_shnum = filedata->section_headers[0].sh_size;
if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
header->e_shstrndx = filedata->section_headers[0].sh_link;
- else if (header->e_shstrndx >= header->e_shnum)
+ if (header->e_shstrndx >= header->e_shnum)
header->e_shstrndx = SHN_UNDEF;
free (filedata->section_headers);
filedata->section_headers = NULL;
@@ -13578,7 +13578,9 @@ load_debug_section (enum dwarf_section_display_enum debug, void * data)
if (filedata->section_headers == NULL)
return FALSE;
- if (filedata->string_table == NULL)
+ if (filedata->string_table == NULL
+ && filedata->file_header.e_shstrndx != SHN_UNDEF
+ && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
{
Elf_Internal_Shdr * strs;
@@ -13587,11 +13589,12 @@ load_debug_section (enum dwarf_section_display_enum debug, void * data)
if (strs != NULL && strs->sh_size != 0)
{
- filedata->string_table = (char *) get_data (NULL, filedata, strs->sh_offset,
- 1, strs->sh_size,
- _("string table"));
+ filedata->string_table
+ = (char *) get_data (NULL, filedata, strs->sh_offset,
+ 1, strs->sh_size, _("string table"));
- filedata->string_table_length = filedata->string_table != NULL ? strs->sh_size : 0;
+ filedata->string_table_length
+ = filedata->string_table != NULL ? strs->sh_size : 0;
}
}