Bug 24360 - Integer-Truncation / heap-overflow in objdump.c caused by commit-7a6e0d89
Summary: Integer-Truncation / heap-overflow in objdump.c caused by commit-7a6e0d89
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: binutils (show other bugs)
Version: 2.32
: P2 critical
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-03-19 07:18 UTC by tfx
Modified: 2019-03-19 13:42 UTC (History)
2 users (show)

See Also:
Host: Ubuntu 16.04 LTS
Target:
Build: clang -m32
Last reconfirmed:


Attachments
objdump -g heap overflow (2.61 KB, application/octet-stream)
2019-03-19 07:25 UTC, tfx
Details

Note You need to log in before you can comment on or make changes to this bug.
Description tfx 2019-03-19 07:18:14 UTC

    
Comment 1 tfx 2019-03-19 07:25:15 UTC
Created attachment 11687 [details]
objdump -g  heap overflow
Comment 2 tfx 2019-03-19 07:56:03 UTC
I use 32bit objdump which build by commit-4faa59bb.

./objdump -g poc

The part of crash output show as follow.

*** Error in `../../binutils-gdb/binutils/objdump': malloc(): memory corruption (fast): 0x09846880 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x67377)[0xf7dce377]
/lib/i386-linux-gnu/libc.so.6(+0x6d2f7)[0xf7dd42f7]
/lib/i386-linux-gnu/libc.so.6(+0x6f7cc)[0xf7dd67cc]
/lib/i386-linux-gnu/libc.so.6(__libc_malloc+0xc5)[0xf7dd7fc5]
/lib/i386-linux-gnu/libc.so.6(+0x29171)[0xf7d90171]
/lib/i386-linux-gnu/libc.so.6(+0x270a2)[0xf7d8e0a2]
/lib/i386-linux-gnu/libc.so.6(+0x26a20)[0xf7d8da20]
/lib/i386-linux-gnu/libc.so.6(dcgettext+0x26)[0xf7d8c8b6]
/lib/i386-linux-gnu/libc.so.6(gettext+0x10)[0xf7d8c8f0]
../../binutils-gdb/binutils/objdump[0x804f259]
../../binutils-gdb/binutils/objdump[0x804f6fe]
../../binutils-gdb/binutils/objdump[0x80a6f34]
../../binutils-gdb/binutils/objdump[0x804f869]
../../binutils-gdb/binutils/objdump[0x8051b10]
../../binutils-gdb/binutils/objdump[0x8051bfd]
../../binutils-gdb/binutils/objdump[0x8051e6d]
../../binutils-gdb/binutils/objdump[0x8051eda]
../../binutils-gdb/binutils/objdump[0x8052847]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf7)[0xf7d7f637]
../../binutils-gdb/binutils/objdump[0x8049af1]
======= Memory map: ========

gdb output:
gef➤  bt
#0  0xf7fd7dc9 in __kernel_vsyscall ()
#1  0xf7e1dea9 in raise () from /lib/i386-linux-gnu/libc.so.6
#2  0xf7e1f407 in abort () from /lib/i386-linux-gnu/libc.so.6
#3  0xf7e5937c in ?? () from /lib/i386-linux-gnu/libc.so.6
#4  0xf7e5f2f7 in ?? () from /lib/i386-linux-gnu/libc.so.6
#5  0xf7e617cc in ?? () from /lib/i386-linux-gnu/libc.so.6
#6  0xf7e62fc5 in malloc () from /lib/i386-linux-gnu/libc.so.6
#7  0xf7e1b171 in ?? () from /lib/i386-linux-gnu/libc.so.6
#8  0xf7e190a2 in ?? () from /lib/i386-linux-gnu/libc.so.6
#9  0xf7e18a20 in ?? () from /lib/i386-linux-gnu/libc.so.6
#10 0xf7e178b6 in dcgettext () from /lib/i386-linux-gnu/libc.so.6
#11 0xf7e178f0 in gettext () from /lib/i386-linux-gnu/libc.so.6
#12 0x0804f259 in load_specific_debug_section (debug=eh_frame, sec=0x824c54c, file=0x824aa08) at ./objdump.c:2712
#13 0x0804f6fe in dump_dwarf_section (abfd=0x824aa08, section=0x824c54c, arg=0x0) at ./objdump.c:2888
#14 0x080a6f34 in bfd_map_over_sections (abfd=0x824aa08, operation=0x804f5fb <dump_dwarf_section>, user_storage=0x0) at section.c:1374
#15 0x0804f869 in dump_dwarf (abfd=0x824aa08) at ./objdump.c:2963
#16 0x08051b10 in dump_bfd (abfd=0x824aa08, is_mainfile=0x1) at ./objdump.c:3903
#17 0x08051bfd in display_object_bfd (abfd=0x824aa08) at ./objdump.c:3940
#18 0x08051e6d in display_any_bfd (file=0x824aa08, level=0x0) at ./objdump.c:4030
#19 0x08051eda in display_file (filename=0xffffd046 "crashes20190319/id:000006,sig:06,src:002800+001543,op:splice,rep:16", target=0x0, last_file=0x1) at ./objdump.c:4051
#20 0x08052847 in main (argc=0x3, argv=0xffffcde4) at ./objdump.c:4361




objdump.c --> load_specific_debug_section

>2696
  section->size = bfd_get_section_size (sec);
  amt = section->size + 1;
  if (amt == 0)
    {
      section->start = NULL;
      free_debug_section (debug);
      printf (_("\nSection '%s' has an invalid size: %#llx.\n"),
	      sanitize_string (section->name),
	      (unsigned long long) section->size);
      return FALSE;
    }
  section->start = contents = malloc (amt);
  if (section->start == NULL
      || !bfd_get_full_section_contents (abfd, sec, &contents))
    {
      free_debug_section (debug);
      printf (_("\nCan't get contents for section '%s'.\n"),
	      sanitize_string (section->name));
      return FALSE;
    }

if section->size == 0xFFFFFFFF
amt = 0x100000000 
malloc(0)  // Integer overflow

Finally it will trigger heap overflow in bfd_get_full_section_contents.


I go back to the git log and find this bug is caused by commit-7a6e0d89. 
The commit cause PR24005 to reappear.
Comment 3 Sourceware Commits 2019-03-19 13:40:56 UTC
The master branch has been updated by Nick Clifton <nickc@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=634557801d909982b47b1723f4216ebe8bc784aa

commit 634557801d909982b47b1723f4216ebe8bc784aa
Author: Nick Clifton <nickc@redhat.com>
Date:   Tue Mar 19 13:39:30 2019 +0000

    Prevent an illegal memory access by objdump when parsing a corrupt file on a 32-bit host.
    
    	PR 24360
    	* objdump.c (load_specific_debug_section): Check that the amount
    	of memory to be allocated matches the size of the section.
Comment 4 Nick Clifton 2019-03-19 13:42:58 UTC
Hi tfx,

  Thanks for reporting this problem.  I have checked in a new patch which
  tests to make sure that the amount being malloc'ed is non-zero, and that
  it matches the size of the section (plus one).

Cheers
  Nick