diff options
author | Alan Modra <amodra@gmail.com> | 2024-05-10 22:15:06 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2024-05-10 23:17:03 +0930 |
commit | ad658482c1e4feec4ac99c8e7df17ff78d0c2996 (patch) | |
tree | 05bae4a8580a86967362d2e304508c98075d7abb /binutils | |
parent | a4f76c0765a0b9c643dc91d5a398a1cd9519572b (diff) | |
download | gdb-ad658482c1e4feec4ac99c8e7df17ff78d0c2996.zip gdb-ad658482c1e4feec4ac99c8e7df17ff78d0c2996.tar.gz gdb-ad658482c1e4feec4ac99c8e7df17ff78d0c2996.tar.bz2 |
Re: PR31692, objdump fails .debug_info size check
The fuzzers found a hole. bfd_section_size_insane doesn't check
!SEC_HAS_CONTENTS sections against file size for obvious reasons,
which allows fuzzed debug sections to be stupidly large. Real debug
sections of course always have contents.
PR 31692
* objdump.c (load_specific_debug_section): Don't allow sections
without contents.
Diffstat (limited to 'binutils')
-rw-r--r-- | binutils/objdump.c | 58 |
1 files changed, 31 insertions, 27 deletions
diff --git a/binutils/objdump.c b/binutils/objdump.c index 3d70df4..7182abd 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -4307,41 +4307,45 @@ load_specific_debug_section (enum dwarf_section_display_enum debug, return false; } - section->start = contents = xmalloc (alloced); - /* Ensure any string section has a terminating NUL. */ - section->start[section->size] = 0; - - if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 - && debug_displays [debug].relocate) - { - ret = bfd_simple_get_relocated_section_contents (abfd, - sec, - section->start, - syms) != NULL; - if (ret) - { - long reloc_size = bfd_get_reloc_upper_bound (abfd, sec); + ret = false; + if ((sec->flags & SEC_HAS_CONTENTS) != 0) + { + section->start = contents = xmalloc (alloced); + /* Ensure any string section has a terminating NUL. */ + section->start[section->size] = 0; - if (reloc_size > 0) + if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 + && debug_displays [debug].relocate) + { + ret = bfd_simple_get_relocated_section_contents (abfd, + sec, + section->start, + syms) != NULL; + if (ret) { - long reloc_count; - arelent **relocs; + long reloc_size = bfd_get_reloc_upper_bound (abfd, sec); - relocs = (arelent **) xmalloc (reloc_size); - - reloc_count = bfd_canonicalize_reloc (abfd, sec, relocs, syms); - if (reloc_count <= 0) - free (relocs); - else + if (reloc_size > 0) { - section->reloc_info = relocs; - section->num_relocs = reloc_count; + long reloc_count; + arelent **relocs; + + relocs = (arelent **) xmalloc (reloc_size); + + reloc_count = bfd_canonicalize_reloc (abfd, sec, relocs, syms); + if (reloc_count <= 0) + free (relocs); + else + { + section->reloc_info = relocs; + section->num_relocs = reloc_count; + } } } } + else + ret = bfd_get_full_section_contents (abfd, sec, &contents); } - else - ret = bfd_get_full_section_contents (abfd, sec, &contents); if (!ret) { |