Bug 24039

Summary: integer overflow in libiberty, heap overflow will be triggered
Product: binutils Reporter: tfx <tfx_sec>
Component: binutilsAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED MOVED    
Severity: critical CC: nickc, rschiron, tfx_sec, zhuyan34
Priority: P2    
Version: 2.32   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed:
Attachments: nm -C POC
fix CVE-2018-20673

Description tfx 2018-12-27 14:08:36 UTC
Created attachment 11495 [details]
nm -C POC

I use 32bit binutils in 64bit Ubuntu 16.04.4 LTS.

The trigger command is ./nm -C POC

The source Code show as follow in cplus-dem.c

>2246      work->tmpl_argvec = XNEWVEC (char *, r);  //sizeof(char*) * r
>2247      work->ntmpl_args = r;
>2248      for (i = 0; i < r; i++)
>2249   	work->tmpl_argvec[i] = 0;


Integer overflow when r > 0x40000000 in line 2246, that will trigger heap overflow in in line 2249. 
There are several similar problems in libiberty.

The part of crash output show as follow.
=================================================================
==17964==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xf44fea80 at pc 0x08837adf bp 0xffaceb68 sp 0xffaceb60
WRITE of size 4 at 0xf44fea80 thread T0
    #0 0x8837ade  (./nm-new+0x8837ade)
    #1 0x881916b  (./nm-new+0x881916b)
    #2 0x880ad63  (./nm-new+0x880ad63)
    #3 0x88029fe  (./nm-new+0x88029fe)
    #4 0x8185166  (./nm-new+0x8185166)
    #5 0x81472ea  (./nm-new+0x81472ea)
    #6 0x815268b  (./nm-new+0x815268b)
    #7 0x814d966  (./nm-new+0x814d966)
    #8 0x8146040  (./nm-new+0x8146040)
    #9 0x81441aa  (./nm-new+0x81441aa)
    #10 0xf7c8e636  (/lib/i386-linux-gnu/libc.so.6+0x18636)
    #11 0x8069dfc  (./nm-new+0x8069dfc)

0xf44fea80 is located 0 bytes to the right of 251581056-byte region [0xe5511800,0xf44fea80)
allocated by thread T0 here:
    #0 0x8115823  (./nm-new+0x8115823)
    #1 0x89e6bd9  (./nm-new+0x89e6bd9)
    #2 0x881916b  (./nm-new+0x881916b)
    #3 0x880ad63  (./nm-new+0x880ad63)
    #4 0x88029fe  (./nm-new+0x88029fe)
    #5 0x8185166  (./nm-new+0x8185166)

SUMMARY: AddressSanitizer: heap-buffer-overflow (./nm-new+0x8837ade)
Shadow bytes around the buggy address:
  0x3e89fd00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x3e89fd10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x3e89fd20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x3e89fd30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x3e89fd40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x3e89fd50:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e89fd60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e89fd70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e89fd80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e89fd90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e89fda0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==17964==ABORTING
00000000 AAborted
Comment 1 tfx 2019-01-05 01:50:44 UTC
I use latest binutils with debug info.
crash output show as follow.


binutils/nm-new -C POC
=================================================================
==9029==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xf3bfea80 at pc 0x083ba887 bp 0xffabcac8 sp 0xffabcac0
WRITE of size 4 at 0xf3bfea80 thread T0
    #0 0x83ba886 in demangle_template ./binutils-gdb/libiberty/./cplus-dem.c:2249:23
    #1 0x83b8c2e in demangle_signature ./binutils-gdb/libiberty/./cplus-dem.c:1709:18
    #2 0x83b62da in internal_cplus_demangle ./binutils-gdb/libiberty/./cplus-dem.c:1258:14
    #3 0x83b5143 in cplus_demangle ./binutils-gdb/libiberty/./cplus-dem.c:919:9
    #4 0x815d092 in bfd_demangle ./binutils-gdb/bfd/bfd.c:2254:9
    #5 0x81460a0 in print_symname ./binutils-gdb/binutils/nm.c:423:19
    #6 0x8145035 in print_symbol_info_bsd ./binutils-gdb/binutils/nm.c:1565:3
    #7 0x8149d87 in print_symbol ./binutils-gdb/binutils/nm.c:903:3
    #8 0x8148828 in print_symbols ./binutils-gdb/binutils/nm.c:1102:7
    #9 0x8146fdb in display_rel_file ./binutils-gdb/binutils/nm.c:1215:5
    #10 0x8144a11 in display_file ./binutils-gdb/binutils/nm.c:1335:7
    #11 0x814424f in main ./binutils-gdb/binutils/nm.c:1816:12
    #12 0xf7d3f636 in __libc_start_main (/lib/i386-linux-gnu/libc.so.6+0x18636)
    #13 0x806be08 in _start (./binutils-gdb/binutils/nm-new+0x806be08)

0xf3bfea80 is located 0 bytes to the right of 251581056-byte region [0xe4c11800,0xf3bfea80)
allocated by thread T0 here:
    #0 0x8112215 in malloc  asan_malloc_linux.cc:146:3
    #1 0x83e6659 in xmalloc ./binutils-gdb/libiberty/./xmalloc.c:147:12
    #2 0x83b8c2e in demangle_signature ./binutils-gdb/libiberty/./cplus-dem.c:1709:18
    #3 0x83b62da in internal_cplus_demangle ./binutils-gdb/libiberty/./cplus-dem.c:1258:14
    #4 0x83b5143 in cplus_demangle ./binutils-gdb/libiberty/./cplus-dem.c:919:9
    #5 0x815d092 in bfd_demangle ./binutils-gdb/bfd/bfd.c:2254:9

SUMMARY: AddressSanitizer: heap-buffer-overflow ./binutils-gdb/libiberty/./cplus-dem.c:2249:23 in demangle_template
Shadow bytes around the buggy address:
  0x3e77fd00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x3e77fd10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x3e77fd20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x3e77fd30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x3e77fd40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x3e77fd50:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e77fd60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e77fd70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e77fd80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e77fd90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e77fda0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==9029==ABORTING
Comment 2 Nick Clifton 2019-01-09 16:25:39 UTC
Hi tfx,

  Thanks for reporting this problem.  Unfortunately the cplus-dem.c
  source file is part of the libiberty library, which is maintained
  by gcc rather than the binutils.  (It is used by the binutils, but
  not maintained by us).  Please could you report this problem here:

https://gcc.gnu.org/bugzilla/enter_bug.cgi?product=gcc

Cheers
  Nick
Comment 3 rschiron 2019-01-14 14:02:47 UTC
New bug was created in gcc project: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88783
Comment 4 Yan Zhu 2019-09-12 07:54:04 UTC
Created attachment 11991 [details]
fix CVE-2018-20673

Add a check before using the variable r
Comment 5 Yan Zhu 2019-09-12 07:55:29 UTC
Comment on attachment 11991 [details]
fix CVE-2018-20673

the binutils version is 2.31.1