CVE-2023-2610 (published 2023-05-09T22:15Z)

Integer Overflow or Wraparound in GitHub repository vim/vim prior to 9.0.1532.

CVSS v3 base score: 7.8, HIGH (CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-190
cwe_name: Integer Overflow or Wraparound
description: The product performs a calculation that can
         produce an integer overflow or wraparound when the logic
         assumes that the resulting value will always be larger than
         the original value. This occurs when an integer value is
         incremented to a value that is too large to store in the
         associated representation. When this occurs, the value may
         become a very small or negative number.
extended_description: 
            
            
            
            
         
         

Fix information:
repo_url: https://github.com/vim/vim
commit_details: repo_url: https://github.com/vim/vim
author: Bram Moolenaar
author_date: 2023-05-09 21:15:30+01:00
msg: patch 9.0.1532: crash when expanding "~" in substitute causes very long text

Problem:    Crash when expanding "~" in substitute causes very long text.
Solution:   Limit the text length to MAXCOL.
repository: repo_url: https://github.com/vim/vim
repo_name: vim/vim
description: The official Vim repository
repo_language: Vim Script
owner: vim
file_changes: filename: regexp.c
change_type: ModificationType.MODIFY
diff: @@ -1767,10 +1767,7 @@ do_Lower(int *d, int c)
 regtilde(char_u *source, int magic)
 {
     char_u	*newsub = source;
-    char_u	*tmpsub;
     char_u	*p;
-    int		len;
-    int		prevlen;
 
     for (p = newsub; *p; ++p)
     {
@@ -1779,24 +1776,35 @@ regtilde(char_u *source, int magic)
 	    if (reg_prev_sub != NULL)
 	    {
 		// length = len(newsub) - 1 + len(prev_sub) + 1
-		prevlen = (int)STRLEN(reg_prev_sub);
-		tmpsub = alloc(STRLEN(newsub) + prevlen);
+		// Avoid making the text longer than MAXCOL, it will cause
+		// trouble at some point.
+		size_t	prevsublen = STRLEN(reg_prev_sub);
+		size_t  newsublen = STRLEN(newsub);
+		if (prevsublen > MAXCOL || newsublen > MAXCOL
+					    || newsublen + prevsublen > MAXCOL)
+		{
+		    emsg(_(e_resulting_text_too_long));
+		    break;
+		}
+
+		char_u *tmpsub = alloc(newsublen + prevsublen);
 		if (tmpsub != NULL)
 		{
 		    // copy prefix
-		    len = (int)(p - newsub);	// not including ~
-		    mch_memmove(tmpsub, newsub, (size_t)len);
+		    size_t prefixlen = p - newsub;	// not including ~
+		    mch_memmove(tmpsub, newsub, prefixlen);
 		    // interpret tilde
-		    mch_memmove(tmpsub + len, reg_prev_sub, (size_t)prevlen);
+		    mch_memmove(tmpsub + prefixlen, reg_prev_sub,
+							       prevsublen);
 		    // copy postfix
 		    if (!magic)
 			++p;			// back off backslash
-		    STRCPY(tmpsub + len + prevlen, p + 1);
+		    STRCPY(tmpsub + prefixlen + prevsublen, p + 1);
 
-		    if (newsub != source)	// already allocated newsub
+		    if (newsub != source)	// allocated newsub before
 			vim_free(newsub);
 		    newsub = tmpsub;
-		    p = newsub + len + prevlen;
+		    p = newsub + prefixlen + prevsublen;
 		}
 	    }
 	    else if (magic)

programming_language: C
filename: test_substitute.vim
change_type: ModificationType.MODIFY
diff: @@ -1414,6 +1414,20 @@ func Test_substitute_short_cmd()
   bw!
 endfunc
 
+" Check handling expanding "~" resulting in extremely long text.
+func Test_substitute_tilde_too_long()
+  enew!
+
+  s/.*/ixxx
+  s//~~~~~~~~~AAAAAAA@(
+
+  " Either fails with "out of memory" or "text too long".
+  " This can take a long time.
+  call assert_fails('sil! norm &&&&&&&&&', ['E1240:\|E342:'])
+
+  bwipe!
+endfunc
+
 " This should be done last to reveal a memory leak when vim_regsub_both() is
 " called to evaluate an expression but it is not used in a second call.
 func Test_z_substitute_expr_leak()

programming_language: Lua
filename: version.c
change_type: ModificationType.MODIFY
diff: @@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1532,
 /**/
     1531,
 /**/

programming_language: Ruby