NULL Pointer Dereference in function generate_loadvar in vim/vim

Valid

Reported on

Aug 16th 2022


Description

NULL Pointer Dereference in function generate_loadvar at vim9compile.c:1165 allows attackers to cause a denial of service (application crash) via a crafted input.

vim version

git log
commit e1f3fd1d02e3f5fe6d2b6d82687c6846b8e500f8 (HEAD -> master, origin/master, origin/HEAD)
Author: Bram Moolenaar <Bram@vim.org>
Date:   Mon Aug 15 18:51:32 2022 +0100

    Update runtime files

Proof of Concept

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

gdb debug info

[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.
0x0000555555cd8761 in generate_loadvar (cctx=0x7fffffffbda0, dest=dest_local, name=0x602000006270 "l", lvar=0x0, type=0x55555601eb00 <t_any>) at vim9compile.c:1165
1165            if (lvar->lv_from_outer > 0)

[ Legend: Modified register | Code | Heap | Stack | String ]
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$rax   : 0x0               
$rbx   : 0x007fffffffb8c00x0000000041b58ab3
$rcx   : 0x0               
$rdx   : 0x0               
$rsp   : 0x007fffffffb8400x007fffffffb8600x000000ffffb9500x0000000000000000
$rbp   : 0x007fffffffb8700x007fffffffb9500x007fffffffba300x007fffffffba800x007fffffffc0c00x007fffffffc1800x007fffffffc4f00x007fffffffcdf0
$rsi   : 0x7               
$rdi   : 0x007fffffffbda00x006140000004400x0000000000000000
$rip   : 0x00555555cd8761  →  <generate_loadvar+807> mov eax, DWORD PTR [rax+0x14]
$r8    : 0x0055555601eb00  →  <t_any+0> add DWORD PTR [rax], eax
$r9    : 0x0               
$r10   : 0x0               
$r11   : 0x00555555ed2ee00x00000000444e45 ("END"?)
$r12   : 0x007fffffffb9200x000ffffffff76a0x0000000000000000
$r13   : 0x000ffffffff7180x0000000000000000
$r14   : 0x007fffffffb9b00x0000000041b58ab3
$r15   : 0x007fffffffb8c00x0000000041b58ab3
$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 ────
0x007fffffffb840│+0x0000: 0x007fffffffb8600x000000ffffb9500x0000000000000000   ← $rsp
0x007fffffffb848│+0x0008: 0x0055555601eb00  →  <t_any+0> add DWORD PTR [rax], eax
0x007fffffffb850│+0x0010: 0x0000000000000000
0x007fffffffb858│+0x0018: 0x006020000062700x0000000000006c ("l"?)
0x007fffffffb860│+0x0020: 0x000000ffffb9500x0000000000000000
0x007fffffffb868│+0x0028: 0x007fffffffbda00x006140000004400x0000000000000000
0x007fffffffb870│+0x0030: 0x007fffffffb9500x007fffffffba300x007fffffffba800x007fffffffc0c00x007fffffffc1800x007fffffffc4f00x007fffffffcdf0     ← $rbp
0x007fffffffb878│+0x0038: 0x00555555cdd36a  →  <compile_load_lhs+1697> mov r14d, 0x1
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
   0x555555cd8755 <generate_loadvar+795> mov    rdi, rax
   0x555555cd8758 <generate_loadvar+798> call   0x55555568d260 <__asan_report_load4@plt>
   0x555555cd875d <generate_loadvar+803> mov    rax, QWORD PTR [rbp-0x20]
 → 0x555555cd8761 <generate_loadvar+807> mov    eax, DWORD PTR [rax+0x14]
   0x555555cd8764 <generate_loadvar+810> test   eax, eax
   0x555555cd8766 <generate_loadvar+812> jle    0x555555cd87bc <generate_loadvar+898>
   0x555555cd8768 <generate_loadvar+814> mov    rax, QWORD PTR [rbp-0x20]
   0x555555cd876c <generate_loadvar+818> mov    edx, DWORD PTR [rax+0x14]
   0x555555cd876f <generate_loadvar+821> mov    rax, QWORD PTR [rbp-0x20]
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── source:vim9compile.c+1165 ────
   1160         break;
   1161     case dest_vimvar:
   1162         generate_LOADV(cctx, name + 2);
   1163         break;
   1164     case dest_local:
              // lvar=0x007fffffffb8500x00000000000000001165         if (lvar->lv_from_outer > 0)
   1166         generate_LOADOUTER(cctx, lvar->lv_idx, lvar->lv_from_outer,
   1167                                      type);
   1168         else
   1169         generate_LOAD(cctx, ISN_LOAD, lvar->lv_idx, NULL, type);
   1170         break;
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "vim", stopped 0x555555cd8761 in generate_loadvar (), reason: SIGSEGV
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x555555cd8761 → generate_loadvar(cctx=0x7fffffffbda0, dest=dest_local, name=0x602000006270 "l", lvar=0x0, type=0x55555601eb00 <t_any>)
[#1] 0x555555cdd36a → compile_load_lhs(lhs=0x7fffffffbe40, var_start=0x602000006290 "l[0]", rhs_type=0x55555601ed00 <t_string>, cctx=0x7fffffffbda0)
[#2] 0x555555cddb2d → compile_assign_unlet(var_start=0x602000006290 "l[0]", lhs=0x7fffffffbe40, is_assign=0x1, rhs_type=0x55555601ed00 <t_string>, cctx=0x7fffffffbda0)
[#3] 0x555555cd1bde → compile_redir(line=0x6020000062b0 "redi END", eap=0x7fffffffbca0, cctx=0x7fffffffbda0)
[#4] 0x555555ce58ee → compile_def_function(ufunc=0x614000000440, check_return_type=0x0, compile_type=CT_NONE, outer_cctx=0x0)
[#5] 0x555555cbc9b3 → ex_defcompile(eap=0x7fffffffc270)
[#6] 0x555555817444 → do_one_cmd(cmdlinep=0x7fffffffc5d0, flags=0x7, cstack=0x7fffffffc6f0, fgetline=0x555555b33a24 <getsourceline>, cookie=0x7fffffffcfb0)
[#7] 0x55555580e6e7 → do_cmdline(cmdline=0x6110000002c0 "def T()", fgetline=0x555555b33a24 <getsourceline>, cookie=0x7fffffffcfb0, flags=0x7)
[#8] 0x555555b3186d → do_source_ext(fname=0x604000000213 "/home/fuzz/test/poc1_null.dat", check_other=0x0, is_vimrc=0x0, ret_sid=0x0, eap=0x0, clearvars=0x0)
[#9] 0x555555b3299f → do_source(fname=0x604000000213 "/home/fuzz/test/poc1_null.dat", check_other=0x0, is_vimrc=0x0, ret_sid=0x0)
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

poc download: <p><a href="https://github.com/Janette88/vim/blob/main/poc1_null.dat">poc1_null.dat</a></p>

Impact

NULL Pointer Dereference in function generate_loadvar allows attackers to cause a denial of service (application crash) via a crafted input.

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

I can reproduce it. The POC can be simplified by removing a couple of lines that don't matter.

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

Maintainer


Fixed with patch 9.0.0224

Bram Moolenaar confirmed that a fix has been merged on 4875d6 a month ago
Bram Moolenaar has been awarded the fix bounty
to join this conversation