division zero in vim/vim


Reported on

Feb 19th 2023


division by zero in fuction scrolldown at move.c:1739


git log
commit ea62cee85e9e77ec86edd9843926dadb69978753 (HEAD -> master, tag: v9.0.1327, origin/master, origin/HEAD)
Author: Bram Moolenaar <Bram@vim.org>
Date:   Sun Feb 19 18:36:41 2023 +0000

    patch 9.0.1327: cursor in wrong position below line with virtual text below

    Problem:    Cursor in wrong position below line with virtual text below ending
                in multi-byte character.
    Solution:   When checking for last character take care of multi-byte

Proof of Concept

./vim -u NONE -i NONE -n -m -X -Z -e -s -S poc
Floating point exception


gdb --args ./vim -u NONE -i NONE -n -m -X -Z -e -s -S poc
GNU gdb (Ubuntu 12.0.90-0ubuntu1) 12.0.90
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
Find the GDB manual and other documentation resources online at:

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./vim...
gdb-peda$ r
Starting program: /home/user/vim/src/vim -u NONE -i NONE -n -m -X -Z -e -s -S poc
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGFPE, Arithmetic exception.
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: 0x8
RBX: 0x7fffffff57c0 --> 0x1
RCX: 0xfffffff8 --> 0x0
RDX: 0x0
RSI: 0x1
RDI: 0x62500001e100 --> 0x3eb
RBP: 0x7fffffff5c00 --> 0x7fffffff5d50 --> 0x7fffffff6010 --> 0x7fffffff62f0 --> 0x7fffffff6c30 --> 0x7fffffff6c60 (--> ...)
RSP: 0x7fffffff5780 --> 0x41b58ab3
RIP: 0x555555c052fa (<scrolldown+7594>: idiv   DWORD PTR [rbx+0x3dc])
R8 : 0x10007fff68ef --> 0x0
R9 : 0x2
R10: 0xffffffffffffffff
R11: 0x6c ('l')
R12: 0x7fffffffdf78 --> 0x7fffffffe321 ("/home/user/vim/src/vim")
R13: 0x555556219fb0 (<main>:    push   rbp)
R14: 0x55555634bae8 --> 0x5555557e16b0 (<asan.module_dtor>: push   rbp)
R15: 0x7ffff7ffd040 --> 0x7ffff7ffe2e0 --> 0x555555554000 --> 0x10102464c457f
EFLAGS: 0x10202 (carry parity adjust zero sign trap INTERRUPT direction overflow)
   0x555555c052ed <scrolldown+7581>:    jle    0x555555c0531f <scrolldown+7631>
   0x555555c052f3 <scrolldown+7587>:    mov    eax,DWORD PTR [rbx+0x3c0]
   0x555555c052f9 <scrolldown+7593>:    cdq
=> 0x555555c052fa <scrolldown+7594>:    idiv   DWORD PTR [rbx+0x3dc]
   0x555555c05300 <scrolldown+7600>:    add    eax,DWORD PTR [rbx+0x3bc]
   0x555555c05306 <scrolldown+7606>:    mov    DWORD PTR [rbx+0x3bc],eax
   0x555555c0530c <scrolldown+7612>:    mov    eax,DWORD PTR [rbx+0x3c0]
   0x555555c05312 <scrolldown+7618>:    cdq
0000| 0x7fffffff5780 --> 0x41b58ab3
0008| 0x7fffffff5788 --> 0x55555628b24c ("1 32 8 10 first:1599")
0016| 0x7fffffff5790 --> 0x555555c03550 (<scrolldown>:  push   rbp)
0024| 0x7fffffff5798 --> 0x100000000 --> 0x0
0032| 0x7fffffff57a0 --> 0x62500000a420 --> 0x1
0040| 0x7fffffff57a8 --> 0x0
0048| 0x7fffffff57b0 --> 0x62500000a428 --> 0x0
0056| 0x7fffffff57b8 --> 0x5555561388be (<may_trigger_win_scrolled_resized+2510>:   lea    rsp,[rbp-0x8])
Legend: code, data, rodata, value
Stopped reason: SIGFPE
0x0000555555c052fa in scrolldown (line_count=0x0, byfold=0x0) at move.c:1739
1739            row += col / width2;
gdb-peda$ p width2
$1 = 0x0
gdb-peda$ bt
#0  0x0000555555c052fa in scrolldown (line_count=0x0, byfold=0x0) at move.c:1739
#1  0x0000555555c20b33 in check_scrollbind (topline_diff=0x0, leftcol_diff=0x0) at normal.c:1943
#2  0x00005555562238b2 in main_loop (cmdwin=0x1, noexmode=0x0) at main.c:1390
#3  0x0000555555a4c17a in open_cmdwin () at ex_getln.c:4549
#4  0x0000555555a3bfd2 in getcmdline_int (firstc=0x3a, count=0x1, indent=0x0, clear_ccline=0x1) at ex_getln.c:1938
#5  0x0000555555a38809 in getcmdline (firstc=0x3a, count=0x1, indent=0x0, do_concat=GETLINE_CONCAT_CONT) at ex_getln.c:1554
#6  0x0000555555a4101d in getexline (c=0x3a, cookie=0x0, indent=0x0, options=GETLINE_CONCAT_CONT) at ex_getln.c:2843
#7  0x00005555559e2bc3 in do_cmdline (cmdline=0x0, fgetline=0x555555a40f90 <getexline>, cookie=0x0, flags=0x0) at ex_docmd.c:876
#8  0x0000555555c30b82 in nv_colon (cap=0x7fffffff7e60) at normal.c:3176
#9  0x0000555555c1478b in normal_cmd (oap=0x7fffffff8440, toplevel=0x1) at normal.c:938
#10 0x0000555555a14a8d in exec_normal (was_typed=0x0, use_vpeekc=0x0, may_use_terminal_loop=0x0) at ex_docmd.c:8887
#11 0x0000555555a146b4 in exec_normal_cmd (cmd=0x611000000a48 "\\fn0ndwPPPP\\021\\rWPP0rm0<", '0' <repeats 13 times>, remap=0x0, silent=0x0)
    at ex_docmd.c:8850
#12 0x0000555555a14422 in ex_normal (eap=0x7fffffff89a0) at ex_docmd.c:8768
#13 0x00005555559ef8b0 in do_one_cmd (cmdlinep=0x7fffffff9e40, flags=0x7, cstack=0x7fffffff9e60, fgetline=0x555555e0e7b0 <getsourceline>,
    cookie=0x7fffffffae60) at ex_docmd.c:2580
#14 0x00005555559e3675 in do_cmdline (cmdline=0x611000000540 "noaoco\\001\\rr\\027\\027normnorm:", fgetline=0x555555e0e7b0 <getsourceline>,
    cookie=0x7fffffffae60, flags=0x7) at ex_docmd.c:993
#15 0x0000555555e0c5a4 in do_source_ext (fname=0x602000006153 "poc", check_other=0x0, is_vimrc=0x0, ret_sid=0x0, eap=0x0, clearvars=0x0)
    at scriptfile.c:1759
#16 0x0000555555e0a0d1 in do_source (fname=0x602000006153 "poc", check_other=0x0, is_vimrc=0x0, ret_sid=0x0) at scriptfile.c:1905
#17 0x0000555555e09c20 in cmd_source (fname=0x602000006153 "poc", eap=0x7fffffffb820) at scriptfile.c:1250
#18 0x0000555555e0971e in ex_source (eap=0x7fffffffb820) at scriptfile.c:1276
#19 0x00005555559ef8b0 in do_one_cmd (cmdlinep=0x7fffffffccc0, flags=0xb, cstack=0x7fffffffcce0, fgetline=0x0, cookie=0x0) at ex_docmd.c:2580
#20 0x00005555559e3675 in do_cmdline (cmdline=0x602000002710 "so poc", fgetline=0x0, cookie=0x0, flags=0xb) at ex_docmd.c:993
#21 0x00005555559e6771 in do_cmdline_cmd (cmd=0x602000002710 "so poc") at ex_docmd.c:587
#22 0x0000555556222b5d in exe_commands (parmp=0x555556e0ac00 <params>) at main.c:3146
#23 0x000055555622095b in vim_main2 () at main.c:782
#24 0x000055555621a56f in main (argc=0xd, argv=0x7fffffffdf78) at main.c:433
#25 0x00007ffff7c45d90 in __libc_start_call_main (main=main@entry=0x555556219fb0 <main>, argc=argc@entry=0xd, argv=argv@entry=0x7fffffffdf78)
    at ../sysdeps/nptl/libc_start_call_main.h:58
#26 0x00007ffff7c45e40 in __libc_start_main_impl (main=0x555556219fb0 <main>, argc=0xd, argv=0x7fffffffdf78, init=<optimized out>, fini=<optimized out>,
    rtld_fini=<optimized out>, stack_end=0x7fffffffdf68) at ../csu/libc-start.c:392
#27 0x0000555555721a75 in _start ()
gdb-peda$ list
1734            col -= width1;
1735            ++row;
1736        }
1737        if (col > width2)
1738        {
1739            row += col / width2;
1740            col = col % width2;
1741        }
1742        if (row >= curwin->w_height)
1743        {



it can lead to DoS, modify memory, possibly remote execution

We are processing your report and will contact the vim team within 24 hours. 9 months ago
We have contacted a member of the vim team and are waiting to hear back 9 months ago
9 months ago


@admin do I just have to wait for the maintainer's response? or was it not verification as a vulnerability?

Bram Moolenaar
9 months ago


The POC is very long, with many control characters. I very much doubt all of this is needed to reproduce the problem. Please try to reduce the POC to the minimum needed to trigger the issue. Then hopefully it can be used as a regression test.

9 months ago


I see. I've shortened it. If the poc is still too long, could you tell me again? I'll try harder to find shortest poc. poc2

9 months ago


more trimmed version poc poc3 If you don't like it, I'll try again i checked this poc at version 9.0.1363

Bram Moolenaar
9 months ago


Thanks, that is much better. The main remaining one is using ":set no<CTRL-A>", which sets lots of options. Only two actually matter. I'll use the further simplified POC in the regression test, see the patch that is soon coming.

Bram Moolenaar validated this vulnerability 9 months ago

I can reproduce the problem.

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.1367 with commit e0f869 9 months ago
Bram Moolenaar has been awarded the fix bounty
This vulnerability has been assigned a CVE
Bram Moolenaar published this vulnerability 9 months ago
to join this conversation