diff options
author | Alan Modra <amodra@gmail.com> | 2017-12-06 17:32:48 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2017-12-06 18:05:18 +1030 |
commit | 9c1ce1085070f42718e341d89a28881edd96161f (patch) | |
tree | 1c2d97c4b9386682093093afd318bdc71f4a792f /binutils/readelf.c | |
parent | 07d6d2b8345ef3dc82eab49635acac9ee67dbb18 (diff) | |
download | gdb-9c1ce1085070f42718e341d89a28881edd96161f.zip gdb-9c1ce1085070f42718e341d89a28881edd96161f.tar.gz 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.
Diffstat (limited to 'binutils/readelf.c')
-rw-r--r-- | binutils/readelf.c | 15 |
1 files changed, 9 insertions, 6 deletions
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; } } |