diff options
author | Nick Clifton <nickc@redhat.com> | 2020-11-26 17:08:33 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2020-11-26 17:08:33 +0000 |
commit | 647cebce12a6b0a26960220caff96ff38978cf24 (patch) | |
tree | 79ae8b368be9c2e4fa7c4397f9e8f5216059d96f /bfd/dwarf2.c | |
parent | 239ca5e497dda2c151009d664d500086a5c2173a (diff) | |
download | gdb-647cebce12a6b0a26960220caff96ff38978cf24.zip gdb-647cebce12a6b0a26960220caff96ff38978cf24.tar.gz gdb-647cebce12a6b0a26960220caff96ff38978cf24.tar.bz2 |
Prevent a memory allocation failure when parsing corrupt DWARF debug sections.
PR 26946
* dwarf2.c (read_section): Check for debug sections with excessive
sizes.
Diffstat (limited to 'bfd/dwarf2.c')
-rw-r--r-- | bfd/dwarf2.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c index 977bf43..8bbfc81 100644 --- a/bfd/dwarf2.c +++ b/bfd/dwarf2.c @@ -531,22 +531,24 @@ read_section (bfd * abfd, bfd_byte ** section_buffer, bfd_size_type * section_size) { - asection *msec; const char *section_name = sec->uncompressed_name; bfd_byte *contents = *section_buffer; - bfd_size_type amt; /* The section may have already been read. */ if (contents == NULL) { + bfd_size_type amt; + asection *msec; + ufile_ptr filesize; + msec = bfd_get_section_by_name (abfd, section_name); - if (! msec) + if (msec == NULL) { section_name = sec->compressed_name; if (section_name != NULL) msec = bfd_get_section_by_name (abfd, section_name); } - if (! msec) + if (msec == NULL) { _bfd_error_handler (_("DWARF error: can't find %s section."), sec->uncompressed_name); @@ -554,12 +556,23 @@ read_section (bfd * abfd, return FALSE; } - *section_size = msec->rawsize ? msec->rawsize : msec->size; + amt = bfd_get_section_limit_octets (abfd, msec); + filesize = bfd_get_file_size (abfd); + if (amt >= filesize) + { + /* PR 26946 */ + _bfd_error_handler (_("DWARF error: section %s is larger than its filesize! (0x%lx vs 0x%lx)"), + section_name, (long) amt, (long) filesize); + bfd_set_error (bfd_error_bad_value); + return FALSE; + } + *section_size = amt; /* Paranoia - alloc one extra so that we can make sure a string section is NUL terminated. */ - amt = *section_size + 1; + amt += 1; if (amt == 0) { + /* Paranoia - this should never happen. */ bfd_set_error (bfd_error_no_memory); return FALSE; } |