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
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
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.