diff options
author | Alan Modra <amodra@gmail.com> | 2021-05-11 17:57:59 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2021-05-11 19:07:02 +0930 |
commit | f2f9554bf0d15a5b93289ebfef7e04d0aeb51a60 (patch) | |
tree | 9b5c2f55a9402ff12ebbde7f3da756918ae4ed4f /binutils/dwarf.c | |
parent | 2005aa0281fccd53ad867ead783aa417516cf39c (diff) | |
download | gdb-f2f9554bf0d15a5b93289ebfef7e04d0aeb51a60.zip gdb-f2f9554bf0d15a5b93289ebfef7e04d0aeb51a60.tar.gz gdb-f2f9554bf0d15a5b93289ebfef7e04d0aeb51a60.tar.bz2 |
PR27845, readelf heap-buffer-overflow
PR 27845
* dwarf.c (process_abbrev_set): Replace start and end parameters
with section, abbrev_base, abbrev_size, abbrev_offset. Update
all callers. Sanity check parameters correctly and emit warnings
here rather than..
(process_debug_info): ..here.
Diffstat (limited to 'binutils/dwarf.c')
-rw-r--r-- | binutils/dwarf.c | 80 |
1 files changed, 42 insertions, 38 deletions
diff --git a/binutils/dwarf.c b/binutils/dwarf.c index c584f5b..aa48f69 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -1059,10 +1059,34 @@ add_abbrev_attr (unsigned long attribute, an abbreviation set was found. */ static unsigned char * -process_abbrev_set (unsigned char * start, - const unsigned char * end, - abbrev_list * list) +process_abbrev_set (struct dwarf_section *section, + dwarf_vma abbrev_base, + dwarf_vma abbrev_size, + dwarf_vma abbrev_offset, + abbrev_list *list) { + if (abbrev_base >= section->size + || abbrev_size > section->size - abbrev_base) + { + /* PR 17531: file:4bcd9ce9. */ + warn (_("Debug info is corrupted, abbrev size (%lx) is larger than " + "abbrev section size (%lx)\n"), + (unsigned long) abbrev_base + abbrev_size, + (unsigned long) section->size); + return NULL; + } + if (abbrev_offset >= abbrev_size) + { + warn (_("Debug info is corrupted, abbrev offset (%lx) is larger than " + "abbrev section size (%lx)\n"), + (unsigned long) abbrev_offset, + (unsigned long) abbrev_size); + return NULL; + } + + unsigned char *start = section->start + abbrev_base; + unsigned char *end = start + abbrev_size; + start += abbrev_offset; while (start < end) { unsigned long entry; @@ -3679,12 +3703,9 @@ process_debug_info (struct dwarf_section * section, list = new_abbrev_list (abbrev_base, compunit.cu_abbrev_offset); - next = process_abbrev_set - (((unsigned char *) debug_displays [abbrev_sec].section.start - + abbrev_base + compunit.cu_abbrev_offset), - ((unsigned char *) debug_displays [abbrev_sec].section.start - + abbrev_base + abbrev_size), - list); + next = process_abbrev_set (&debug_displays[abbrev_sec].section, + abbrev_base, abbrev_size, + compunit.cu_abbrev_offset, list); list->start_of_next_abbrevs = next; } @@ -3905,34 +3926,18 @@ process_debug_info (struct dwarf_section * section, } /* Process the abbrevs used by this compilation unit. */ - if (compunit.cu_abbrev_offset >= abbrev_size) - warn (_("Debug info is corrupted, abbrev offset (%lx) is larger than abbrev section size (%lx)\n"), - (unsigned long) compunit.cu_abbrev_offset, - (unsigned long) abbrev_size); - /* PR 17531: file:4bcd9ce9. */ - else if ((abbrev_base + abbrev_size) - > debug_displays [abbrev_sec].section.size) - warn (_("Debug info is corrupted, abbrev size (%lx) is larger than abbrev section size (%lx)\n"), - (unsigned long) abbrev_base + abbrev_size, - (unsigned long) debug_displays [abbrev_sec].section.size); - else + list = find_abbrev_list_by_abbrev_offset (abbrev_base, + compunit.cu_abbrev_offset); + if (list == NULL) { - list = find_abbrev_list_by_abbrev_offset (abbrev_base, - compunit.cu_abbrev_offset); - if (list == NULL) - { - unsigned char * next; - - list = new_abbrev_list (abbrev_base, - compunit.cu_abbrev_offset); - next = process_abbrev_set - (((unsigned char *) debug_displays [abbrev_sec].section.start - + abbrev_base + compunit.cu_abbrev_offset), - ((unsigned char *) debug_displays [abbrev_sec].section.start - + abbrev_base + abbrev_size), - list); - list->start_of_next_abbrevs = next; - } + unsigned char *next; + + list = new_abbrev_list (abbrev_base, + compunit.cu_abbrev_offset); + next = process_abbrev_set (&debug_displays[abbrev_sec].section, + abbrev_base, abbrev_size, + compunit.cu_abbrev_offset, list); + list->start_of_next_abbrevs = next; } level = 0; @@ -6326,7 +6331,6 @@ display_debug_abbrev (struct dwarf_section *section, { abbrev_entry *entry; unsigned char *start = section->start; - const unsigned char *end = start + section->size; introduce (section, false); @@ -6340,7 +6344,7 @@ display_debug_abbrev (struct dwarf_section *section, if (list == NULL) { list = new_abbrev_list (0, offset); - start = process_abbrev_set (start, end, list); + start = process_abbrev_set (section, 0, section->size, offset, list); list->start_of_next_abbrevs = start; } else |