Infinite recursive function calls result in stack overflow in vim/vim

Valid

Reported on

May 16th 2022


Description

When providing certain input, the program will enter an infinite loop where it continually calls:

get_expr_register ->

cmdline_handle_backslash_key ->

getcmdline ->

getcmdline_int ->

cmdline_handle_backslash_key ->

get_expr_register ->

etc.

GDB

[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.
0x00005555556284c5 in getcmdline_int (firstc=61, count=0, indent=0, clear_ccline=1) at ex_getln.c:1618
1618            save_cmdline(&save_ccline);
#0  0x00005555556284c5 in getcmdline_int (firstc=61, count=0, indent=0, clear_ccline=1) at ex_getln.c:1618
#1  0x000055555562842d in getcmdline (firstc=61, count=0, indent=0, do_concat=GETLINE_NONE) at ex_getln.c:1574
#2  0x000055555572ef97 in get_expr_register () at register.c:104
#3  0x00005555556270cc in cmdline_handle_backslash_key (c=101, gotesc=0x7fffff7ff408) at ex_getln.c:850
#4  0x0000555555628c8f in getcmdline_int (firstc=61, count=0, indent=0, clear_ccline=1) at ex_getln.c:1925
#5  0x000055555562842d in getcmdline (firstc=61, count=0, indent=0, do_concat=GETLINE_NONE) at ex_getln.c:1574
#6  0x000055555572ef97 in get_expr_register () at register.c:104
#7  0x00005555556270cc in cmdline_handle_backslash_key (c=101, gotesc=0x7fffff7ff688) at ex_getln.c:850
#8  0x0000555555628c8f in getcmdline_int (firstc=61, count=0, indent=0, clear_ccline=1) at ex_getln.c:1925
#9  0x000055555562842d in getcmdline (firstc=61, count=0, indent=0, do_concat=GETLINE_NONE) at ex_getln.c:1574
#10 0x000055555572ef97 in get_expr_register () at register.c:104

...

#2052 0x000055555572ef97 in get_expr_register () at register.c:104                                                                  
#2053 0x00005555556270cc in cmdline_handle_backslash_key (c=101, gotesc=0x7fffff84f138) at ex_getln.c:850                           
#2054 0x0000555555628c8f in getcmdline_int (firstc=61, count=0, indent=0, clear_ccline=1) at ex_getln.c:1925                        
#2055 0x000055555562842d in getcmdline (firstc=61, count=0, indent=0, do_concat=GETLINE_NONE) at ex_getln.c:1574                    
#2056 0x000055555572ef97 in get_expr_register () at register.c:104                                                                  
#2057 0x00005555556270cc in cmdline_handle_backslash_key (c=101, gotesc=0x7fffff84f3b8) at ex_getln.c:850                           
#2058 0x0000555555628c8f in getcmdline_int (firstc=61, count=0, indent=0, clear_ccline=1) at ex_getln.c:1925                        
#2059 0x000055555562842d in getcmdline (firstc=61, count=0, indent=0, do_concat=GETLINE_NONE) at ex_getln.c:1574                    
#2060 0x000055555572ef97 in get_expr_register () at register.c:104                                                                  
#2061 0x00005555556270cc in cmdline_handle_backslash_key (c=101, gotesc=0x7fffff84f638) at ex_getln.c:850                           
#2062 0x0000555555628c8f in getcmdline_int (firstc=61, count=0, indent=0, clear_ccline=1) at ex_getln.c:1925                        
#2063 0x000055555562842d in getcmdline (firstc=61, count=0, indent=0, do_concat=GETLINE_NONE) at ex_getln.c:1574                    
#2064 0x000055555572ef97 in get_expr_register () at register.c:104                                                                  
#2065 0x00005555556270cc in cmdline_handle_backslash_key (c=101, gotesc=0x7fffff84f8b8) at ex_getln.c:850                           
#2066 0x0000555555628c8f in getcmdline_int (firstc=61, count=0, indent=0, clear_ccline=1) at ex_getln.c:1925                        
#2067 0x000055555562842d in getcmdline (firstc=61, count=0, indent=0, do_concat=GETLINE_NONE) at ex_getln.c:1574                    
#2068 0x000055555572ef97 in get_expr_register () at register.c:104                                                                  
#2069 0x00005555556270cc in cmdline_handle_backslash_key (c=101, gotesc=0x7fffff84fb38) at ex_getln.c:850                           
#2070 0x0000555555628c8f in getcmdline_int (firstc=61, count=0, indent=0, clear_ccline=1) at ex_getln.c:1925                        
#2071 0x000055555562842d in getcmdline (firstc=61, count=0, indent=0, do_concat=GETLINE_NONE) at ex_getln.c:1574                    
#2072 0x000055555572ef97 in get_expr_register () at register.c:104                                            

Valgrind

==99366== Memcheck, a memory error detector
==99366== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==99366== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==99366== Command: ./vim -u NONE -X -Z -e -s -S id:000000,sig:11,src:013242+022204,time:17320933,execs:2959795,op:splice,rep:2 -c :qa!
==99366== 
==99366== Stack overflow in thread #1: can't grow stack to 0x1ffe801000
==99366== 
==99366== Process terminating with default action of signal 11 (SIGSEGV)
==99366==    at 0x4E31A97: kill (syscall-template.S:78)
==99366==    by 0x28B7C9: may_core_dump (os_unix.c:3529)
==99366==    by 0x28B781: mch_exit (os_unix.c:3495)
==99366==    by 0x3FADEC: getout (main.c:1726)
==99366==    by 0x24F54D: preserve_exit (misc1.c:2217)
==99366==    by 0x289482: deathtrap (os_unix.c:1175)
==99366==    by 0x4E3183F: ??? (in /usr/lib/x86_64-linux-gnu/libc-2.28.so)
==99366==    by 0x483573D: malloc (vg_replace_malloc.c:299)

Proof of Concept

./vim -u NONE -e -s -S crash_input
Segmentation fault

https://github.com/GreaterGoodest/vim-pocs/blob/master/crash_input

Impact

This could cause a denial of service due to crashing the process.

We are processing your report and will contact the vim team within 24 hours. 2 years ago
Ryan Good modified the report
2 years ago
Ryan Good modified the report
2 years ago
Ryan Good modified the report
2 years ago
Ryan Good modified the report
2 years ago
Ryan Good modified the report
2 years ago
We have contacted a member of the vim team and are waiting to hear back 2 years ago
Ryan Good modified the report
2 years ago
Ryan Good
2 years ago

Researcher


Note: I have this set to "stack based buffer overflow" due to the lack of an appropriate option. It should really be Uncontrolled Recursion (https://cwe.mitre.org/data/definitions/674.html)

Bram Moolenaar validated this vulnerability 2 years ago

I can reproduce the problem. The POC can be used for a regression test.

Ryan Good 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 8.2 with commit 51f0bf 2 years ago
Bram Moolenaar has been awarded the fix bounty
This vulnerability will not receive a CVE
Bram Moolenaar
2 years ago

Maintainer


Fixed in patch 8.2.4975

Jamie Slome
2 years ago

Admin


I have updated the report to CWE-674 as requested by the researcher above, as this CWE was missing from our weakness selection at the point of submission 👍

to join this conversation