Dear all, The following bug was found with AFLFast, a fork of AFL, in a 24 hour fuzzing session on Binutils. Thanks also to Van-Thuan Pham. The linker crashes with an invalid write of size 1 for the following execution on 14.04 x86_64 for Binutils v2.24 and trunk. It does not crash on Ubuntu 16.04 x86_64 Binutils v2.26.1 or trunk but the invalid write is still there. $ printf "\x6b\x22\x17\x1d\x00\x7f\x00\x00\x00\x00\x00\x52\x6e\x71\x1d\x00\x00\x01\x00\x00\x00\x00\x00\x00\x52\x6b\x22\x00\xdf\x12\xef\x17\x66\x52\x6b\x22\x17\x1d\x00\x6b\x22\x00\xdf\x2e\xef\x00\x69" > test $ ./ld test *** Error in `/home/ubuntu/subjects/binutils-gdb/ld/ld-new': malloc(): memory corruption: 0x000000000188a6e0 *** Aborted ASAN reports it sometimes as use-after-free and sometimes as heap-based buffer overflow: ================================================================= ==8360==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000c828 at pc 0x000000413f9e bp 0x7ffd709c9a00 sp 0x7ffd709c99f8 WRITE of size 1 at 0x60200000c828 thread T0 #0 0x413f9d in yylex /home/ubuntu/subjects/binutils-gdb/obj-asan/ld/ldlex.l:420 #1 0x404901 in yyparse /home/ubuntu/subjects/binutils-gdb/obj-asan/ld/ldgram.c:2298 #2 0x43845e in load_symbols ../../ld/ldlang.c:2818 #3 0x43c299 in open_input_bfds ../../ld/ldlang.c:3346 #4 0x4568f7 in lang_process ../../ld/ldlang.c:6871 #5 0x465a39 in main ../../ld/ldmain.c:428 #6 0x7fdb8cba8f44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21f44) #7 0x403968 (/home/ubuntu/subjects/binutils-gdb/obj-asan/ld/ld-new+0x403968) 0x60200000c828 is located 8 bytes to the left of 2-byte region [0x60200000c830,0x60200000c832) allocated by thread T0 here: #0 0x7fdb8df293a8 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.3+0xc23a8) #1 0x92547b in xmalloc ../../libiberty/xmalloc.c:148 #2 0x92571a in xstrdup ../../libiberty/xstrdup.c:34 #3 0x413ba4 in yylex /home/ubuntu/subjects/binutils-gdb/obj-asan/ld/ldlex.l:379 #4 0x404901 in yyparse /home/ubuntu/subjects/binutils-gdb/obj-asan/ld/ldgram.c:2298 #5 0x43845e in load_symbols ../../ld/ldlang.c:2818 #6 0x43c299 in open_input_bfds ../../ld/ldlang.c:3346 #7 0x4568f7 in lang_process ../../ld/ldlang.c:6871 #8 0x465a39 in main ../../ld/ldmain.c:428 #9 0x7fdb8cba8f44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21f44) SUMMARY: AddressSanitizer: heap-buffer-overflow /home/ubuntu/subjects/binutils-gdb/obj-asan/ld/ldlex.l:420 in yylex The stacktraces vary significantly for different fuzzing inputs but it is always the call to yyparse that crashes the linker. Best regards, - Marcel
The master branch has been updated by Nick Clifton <nickc@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=406bd128dba2a59d0736839fc87a59bce319076c commit 406bd128dba2a59d0736839fc87a59bce319076c Author: Nick Clifton <nickc@redhat.com> Date: Mon Dec 5 16:00:43 2016 +0000 Fix seg-fault in linker when passed a bogus input script. PR ld/20906 * ldlex.l: Check for bogus strings in linker scripts.
Hi Marcel, Thanks for reporting this bug. I have checked in a small patch to the linker script parser which should fix the problem. Cheers Nick
This is CVE-2017-7227
The master branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=6ef4fa071e2c25b71e81a91646b43378cf957388 commit 6ef4fa071e2c25b71e81a91646b43378cf957388 Author: Alan Modra <amodra@gmail.com> Date: Wed Nov 3 16:21:42 2021 +1030 asan: dlltool buffer overflow: embedded NUL in string yyleng gives the pattern length, xstrdup just copies up to the NUL. So it is quite possible writing at an index of yyleng-2 overflows the xstrdup allocated string buffer. xmemdup quite handily avoids this problem, even writing the terminating NUL over the trailing quote. Use it in ldlex.l too where we'd already had a report of this problem and fixed it by hand, and to implement xmemdup0 in gas. binutils/ * deflex.l (single and double quote strings): Use xmemdup. gas/ * as.h (xmemdup0): Use xmemdup. ld/ PR 20906 * ldlex.l (double quote string): Use xmemdup.