aboutsummaryrefslogtreecommitdiff
path: root/bfd/dwarf2.c
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2020-11-26 17:08:33 +0000
committerNick Clifton <nickc@redhat.com>2020-11-26 17:08:33 +0000
commit647cebce12a6b0a26960220caff96ff38978cf24 (patch)
tree79ae8b368be9c2e4fa7c4397f9e8f5216059d96f /bfd/dwarf2.c
parent239ca5e497dda2c151009d664d500086a5c2173a (diff)
downloadgdb-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.c25
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;
}