Bug 25307 - Heap-buffer-overflow in bfd/pef.c:bfd_pef_parse_function_stubs()
Summary: Heap-buffer-overflow in bfd/pef.c:bfd_pef_parse_function_stubs()
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: binutils (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-12-21 18:54 UTC by Nguyễn Đức Mạnh
Modified: 2020-01-03 16:19 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
PoC (4.23 KB, application/x-pef-executable)
2019-12-21 18:54 UTC, Nguyễn Đức Mạnh
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Nguyễn Đức Mạnh 2019-12-21 18:54:33 UTC
Created attachment 12140 [details]
PoC

Hello,
There is a heap-buffer-overflow in bfd/pef.c:bfd_pef_parse_function_stubs()

## Analysis
Look at the following code:
----------Code-----------
802:    if ((codepos + 4) > codelen)
803:	   break;
804:
805:    ret = bfd_pef_parse_function_stub (abfd, codebuf + codepos, 24, &sym_index);
--------------------------
At line 802, it checks if codepos + 4 < codelen. But at line 805, bfd_pef_parse_function_stub reads (codebuf + codepos) with size 24. This could pass the end of codebuf.

## Reproduction
The attachment makes objdump crash provided objdump is built with address sanitizer.
----------Version--------------
Tested with version 39aa149769fd05fb6fade43bd41c1d7b6d63d06b of github.com/bminor/binutils-gdb
----------Compilation----------
root@manh-ubuntu16:~/fuzz/fuzz_binutils# ./configure --disable-gdb --enable-targets=all CC=gcc CXX=g++ CFLAGS='-fsanitize=address -O0 -ggdb3' CXXFLAGS='-fsanitize=address -O0 -ggdb3' && make -j4
--------Log Crash--------------
root@manh-ubuntu16:~/fuzz/fuzz_binutils# ./binutils-gdb-asan-64-O0/binutils/objdump -x crash-objdump3

crash-objdump3:     file format pef
crash-objdump3
architecture: powerpc:common64, flags 0x000001ff:
HAS_RELOC, EXEC_P, HAS_LINENO, HAS_DEBUG, HAS_SYMS, HAS_LOCALS, DYNAMIC, WP_TEXT, D_PAGED
start address 0x00000000000001c0

=================================================================
==32000==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62500000e9e4 at pc 0x000000837265 bp 0x7ffea4e6cf30 sp 0x7ffea4e6cf20
READ of size 1 at 0x62500000e9e4 thread T0
    #0 0x837264 in bfd_getb32 /root/fuzz/fuzz_binutils/binutils-gdb-asan-64-O0/bfd/libbfd.c:682
    #1 0x12a204b in bfd_pef_parse_function_stub /root/fuzz/fuzz_binutils/binutils-gdb-asan-64-O0/bfd/pef.c:709
    #2 0x12a256a in bfd_pef_parse_function_stubs /root/fuzz/fuzz_binutils/binutils-gdb-asan-64-O0/bfd/pef.c:805
    #3 0x12a2f9a in bfd_pef_parse_symbols /root/fuzz/fuzz_binutils/binutils-gdb-asan-64-O0/bfd/pef.c:929
    #4 0x12a30ba in bfd_pef_count_symbols /root/fuzz/fuzz_binutils/binutils-gdb-asan-64-O0/bfd/pef.c:951
    #5 0x12a30d4 in bfd_pef_get_symtab_upper_bound /root/fuzz/fuzz_binutils/binutils-gdb-asan-64-O0/bfd/pef.c:957
    #6 0x4058a9 in slurp_symtab objdump.c:705
    #7 0x414e52 in dump_bfd objdump.c:4037
    #8 0x41557a in display_object_bfd objdump.c:4165
    #9 0x41587a in display_any_bfd objdump.c:4255
    #10 0x4158ef in display_file objdump.c:4276
    #11 0x416a93 in main objdump.c:4603
    #12 0x7f6f3f94382f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #13 0x403838 in _start (/root/fuzz/fuzz_binutils/binutils-gdb-asan-64-O0/binutils/objdump+0x403838)

0x62500000e9e4 is located 0 bytes to the right of 8420-byte region [0x62500000c900,0x62500000e9e4)
allocated by thread T0 here:
    #0 0x7f6f3ff89602 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x98602)
    #1 0x8366e0 in bfd_malloc /root/fuzz/fuzz_binutils/binutils-gdb-asan-64-O0/bfd/libbfd.c:275
    #2 0x12a2d32 in bfd_pef_parse_symbols /root/fuzz/fuzz_binutils/binutils-gdb-asan-64-O0/bfd/pef.c:899
    #3 0x12a30ba in bfd_pef_count_symbols /root/fuzz/fuzz_binutils/binutils-gdb-asan-64-O0/bfd/pef.c:951
    #4 0x12a30d4 in bfd_pef_get_symtab_upper_bound /root/fuzz/fuzz_binutils/binutils-gdb-asan-64-O0/bfd/pef.c:957
    #5 0x4058a9 in slurp_symtab objdump.c:705
    #6 0x414e52 in dump_bfd objdump.c:4037
    #7 0x41557a in display_object_bfd objdump.c:4165
    #8 0x41587a in display_any_bfd objdump.c:4255
    #9 0x4158ef in display_file objdump.c:4276
    #10 0x416a93 in main objdump.c:4603
    #11 0x7f6f3f94382f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

SUMMARY: AddressSanitizer: heap-buffer-overflow /root/fuzz/fuzz_binutils/binutils-gdb-asan-64-O0/bfd/libbfd.c:682 bfd_getb32
Shadow bytes around the buggy address:
  0x0c4a7fff9ce0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c4a7fff9cf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c4a7fff9d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c4a7fff9d10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c4a7fff9d20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c4a7fff9d30: 00 00 00 00 00 00 00 00 00 00 00 00[04]fa fa fa
  0x0c4a7fff9d40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c4a7fff9d50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c4a7fff9d60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c4a7fff9d70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c4a7fff9d80: 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
==32000==ABORTING
-----------------------

--
Thanks & Regards,
Nguyen Duc Manh
VinCSS (a member of Vingroup)
[M] (+84) 346136886
[E] v.manhnd@vincss.net
[W] www.vincss.net
Comment 1 Nick Clifton 2020-01-03 14:56:09 UTC
Hi Nguyễn,

  Thanks for reporting this bug, and providing such a helpful analysis
  and reproducer.  I have checked in a patch that increases the test at
  line 802 so that it checks that at least 24 bytes are remaining.

Cheers
  Nick
Comment 2 Sourceware Commits 2020-01-03 16:19:30 UTC
The master branch has been updated by Nick Clifton <nickc@sourceware.org>:

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

commit f2a3559d54602cecfec6d90f792be4a70ad918ab
Author: Nick Clifton <nickc@redhat.com>
Date:   Fri Jan 3 16:17:53 2020 +0000

    Fix potential illegal memory access when parsing a corrupt PEF format file.
    
    	PR 25307
    	(bfd_pef_parse_function_stubs): Correct the test that ensures that
    	there is enough data remaining in the code buffer before
    	attempting to read a function stub.