Headline
CVE-2020-20703: UAF: Access violation near NULL on destination operand · Issue #5041 · vim/vim
Buffer Overflow vulnerability in VIM v.8.1.2135 allows a remote attacker to execute arbitrary code via the operand parameter.
VIM Version:
$ ./vim --version
VIM - Vi IMproved 8.1 (2018 May 18, compiled Oct 10 2019 22:18:57)
Included patches: 1-2133
Compiled by input0@zero
Huge version without GUI. Features included (+) or not (-):
+acl -farsi -mouse_sysmouse -tag_any_white
+arabic +file_in_path +mouse_urxvt -tcl
+autocmd +find_in_path +mouse_xterm +termguicolors
+autochdir +float +multi_byte +terminal
-autoservername +folding +multi_lang +terminfo
-balloon_eval -footer -mzscheme +termresponse
+balloon_eval_term +fork() +netbeans_intg +textobjects
-browse +gettext +num64 +textprop
++builtin_terms -hangul_input +packages +timers
+byte_offset +iconv +path_extra +title
+channel +insert_expand -perl -toolbar
+cindent +job +persistent_undo +user_commands
+clientserver +jumplist +postscript +vartabs
+clipboard +keymap +printer +vertsplit
+cmdline_compl +lambda +profile +virtualedit
+cmdline_hist +langmap -python +visual
+cmdline_info +libcall -python3 +visualextra
+comments +linebreak +quickfix +viminfo
+conceal +lispindent +reltime +vreplace
+cryptv +listcmds +rightleft +wildignore
+cscope +localmap -ruby +wildmenu
+cursorbind -lua +scrollbind +windows
+cursorshape +menu +signs +writebackup
+dialog_con +mksession +smartindent +X11
+diff +modify_fname -sound +xfontset
+digraphs +mouse +spell -xim
-dnd -mouseshape +startuptime -xpm
-ebcdic +mouse_dec +statusline +xsmp_interact
+emacs_tags -mouse_gpm -sun_workshop +xterm_clipboard
+eval -mouse_jsbterm +syntax -xterm_save
+ex_extra +mouse_netterm +tag_binary
+extra_search +mouse_sgr -tag_old_static
system vimrc file: "$VIM/vimrc"
user vimrc file: "$HOME/.vimrc"
2nd user vimrc file: "~/.vim/vimrc"
user exrc file: "$HOME/.exrc"
defaults file: "$VIMRUNTIME/defaults.vim"
fall-back for $VIM: "/usr/local/share/vim"
Compilation: afl-clang-fast -c -I. -Iproto -DHAVE_CONFIG_H -g -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1
Linking: afl-clang-fast -L/usr/local/lib -Wl,--as-needed -o vim -lSM -lICE -lXpm -lXt -lX11 -lXdmcp -lSM -lICE -lm -ltinfo -lelf -lnsl -ldl
MData:
While fuzzing VIM with enabling different mode an use-after-free was observed. This is
likely a write access violation, which means the attacker may have control over the
write address and value.
GDB BT:
(gdb) run -u NONE -X -Z -e -s -S out/id\:000001\,sig\:11\,src\:018487\,time\:45124324+017124\,op\:splice\,rep\:8 -c ':qa!'
Starting program: /home/input0/nvim/vim/src/vim -u NONE -X -Z -e -s -S out/id\:000001\,sig\:11\,src\:018487\,time\:45124324+017124\,op\:splice\,rep\:8 -c ':qa!'
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x000000000041adeb in bt_terminal (buf=0x7ffff6c3fca0 <main_arena+96>) at buffer.c:5307
5307 return buf != NULL && buf->b_p_bt[0] == 't';
(gdb) bt
#0 0x000000000041adeb in bt_terminal (buf=0x7ffff6c3fca0 <main_arena+96>) at buffer.c:5307
#1 0x00000000008ed15d in win_enter_ext (wp=<optimized out>, undo_sync=<optimized out>, curwin_invalid=0,
trigger_new_autocmds=<optimized out>, trigger_enter_autocmds=<optimized out>, trigger_leave_autocmds=<optimized out>) at window.c:4658
#2 0x00000000008e8b02 in win_split_ins (size=<optimized out>, flags=<optimized out>, new_wp=<optimized out>, dir=<optimized out>)
at window.c:1326
#3 0x00000000008e0f1f in win_split (size=0, flags=0) at window.c:812
#4 0x0000000000409e23 in do_argfile (eap=0x7fffffffa890, argn=0) at arglist.c:662
#5 0x00000000005214bd in do_one_cmd (sourcing=<optimized out>, cstack=<optimized out>, cmdlinep=<optimized out>, fgetline=<optimized out>,
cookie=<optimized out>) at ex_docmd.c:2470
#6 do_cmdline (cmdline=<optimized out>, fgetline=<optimized out>, cookie=<optimized out>, flags=<optimized out>) at ex_docmd.c:966
#7 0x00000000007a0b32 in do_source (fname=<optimized out>, check_other=<optimized out>, is_vimrc=<optimized out>) at scriptfile.c:1214
#8 0x000000000079f5b9 in cmd_source (fname=0xc4f583 "out/id:000001,sig:11,src:018487,time:45124324+017124,op:splice,rep:8",
eap=<optimized out>) at scriptfile.c:805
#9 0x00000000005214bd in do_one_cmd (sourcing=<optimized out>, cstack=<optimized out>, cmdlinep=<optimized out>, fgetline=<optimized out>,
cookie=<optimized out>) at ex_docmd.c:2470
#10 do_cmdline (cmdline=<optimized out>, fgetline=<optimized out>, cookie=<optimized out>, flags=<optimized out>) at ex_docmd.c:966
#11 0x000000000096e6c9 in exe_commands (parmp=<optimized out>) at main.c:3133
#12 vim_main2 () at main.c:795
#13 0x000000000096b597 in main (argc=<optimized out>, argv=<optimized out>) at main.c:444
(gdb) i r
rax 0xfffffffffffffffc -4
rbx 0xc6dae0 13032160
rcx 0x0 0
rdx 0xc27900 12744960
rsi 0x0 0
rdi 0x7ffff6c3fca0 140737333427360
rbp 0xc6dae8 0xc6dae8
rsp 0x7fffffff96c8 0x7fffffff96c8
r8 0x5f 95
r9 0x1 1
r10 0x7fffffff8c60 140737488325728
r11 0x0 0
r12 0x1 1
r13 0x0 0
r14 0xfffffffffffffffc -4
r15 0x1 1
rip 0x41adeb 0x41adeb <bt_terminal+75>
eflags 0x10206 [ PF IF RF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
(gdb)
ASAN BT:
==14666==ERROR: AddressSanitizer: heap-use-after-free on address 0x62500000f108 at pc 0x000000db2301 bp 0x7ffcbdb68e70 sp 0x7ffcbdb68e68
READ of size 8 at 0x62500000f108 thread T0
#0 0xdb2300 in win_enter_ext /home/input0/vim/src/window.c:4658:25
#1 0xda89af in win_split_ins /home/input0/vim/src/window.c:1326:5
#2 0xd9b007 in win_split /home/input0/vim/src/window.c:812:12
#3 0x516344 in do_argfile /home/input0/vim/src/arglist.c:662:10
#4 0x7120d0 in do_one_cmd /home/input0/vim/src/ex_docmd.c:2470:2
#5 0x7120d0 in do_cmdline /home/input0/vim/src/ex_docmd.c:966
#6 0xb60432 in do_source /home/input0/vim/src/scriptfile.c:1214:5
#7 0xb5e5bf in cmd_source /home/input0/vim/src/scriptfile.c:805:14
#8 0x7120d0 in do_one_cmd /home/input0/vim/src/ex_docmd.c:2470:2
#9 0x7120d0 in do_cmdline /home/input0/vim/src/ex_docmd.c:966
#10 0xe9998f in exe_commands /home/input0/vim/src/main.c:3133:2
#11 0xe9998f in vim_main2 /home/input0/vim/src/main.c:795
#12 0xe94b2c in main /home/input0/vim/src/main.c:444:12
#13 0x7f32b72bbb96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#14 0x41ff49 in _start (/home/input0/vim/src/vim+0x41ff49)
0x62500000f108 is located 8 bytes inside of 8664-byte region [0x62500000f100,0x6250000112d8)
freed by thread T0 here:
#0 0x4d53e8 in __interceptor_free.localalias.0 (/home/input0/vim/src/vim+0x4d53e8)
#1 0x8f411e in vim_free /home/input0/vim/src/misc2.c:1802:2
#2 0x5270ea in apply_autocmds /home/input0/vim/src/autocmd.c:1607:12
#3 0xda89af in win_split_ins /home/input0/vim/src/window.c:1326:5
#4 0xd9b007 in win_split /home/input0/vim/src/window.c:812:12
previously allocated by thread T0 here:
#0 0x4d55a0 in malloc (/home/input0/vim/src/vim+0x4d55a0)
#1 0x8ef102 in lalloc /home/input0/vim/src/misc2.c:924:11
#2 0xd9b007 in win_split /home/input0/vim/src/window.c:812:12
SUMMARY: AddressSanitizer: heap-use-after-free /home/input0/vim/src/window.c:4658:25 in win_enter_ext
Shadow bytes around the buggy address:
0x0c4a7fff9dd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c4a7fff9de0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c4a7fff9df0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c4a7fff9e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c4a7fff9e10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c4a7fff9e20: fd[fd]fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c4a7fff9e30: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c4a7fff9e40: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c4a7fff9e50: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c4a7fff9e60: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c4a7fff9e70: 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
==14666==ABORTING
To Reproduce: vim -u NONE -X -Z -e -s -S $POC -c ‘:qa!’