CVE-2023-46246 (published 2023-10-27T19:15Z)

Vim is an improved version of the good old UNIX editor Vi. Heap-use-after-free in memory allocated in the function `ga_grow_inner` in in the file `src/alloc.c` at line 748, which is freed in the file `src/ex_docmd.c` in the function `do_cmdline` at line 1010 and then used again in `src/cmdhist.c` at line 759. When using the `:history` command, it's possible that the provided argument overflows the accepted value. Causing an Integer Overflow and potentially later an use-after-free. This vulnerability has been patched in version 9.0.2068.\n

CVSS v3 base score: 5.5, MEDIUM (CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/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: 
            
            
            
            
         
         
cwe_id: CWE-416
cwe_name: Use After Free
description: The product reuses or references memory after it has been freed. At some point afterward, the memory may be allocated again and saved in another pointer, while the original pointer references a location somewhere within the new allocation. Any operations using the original pointer are no longer valid because the memory "belongs" to the code that operates on the new pointer.
extended_description: 
             
             
             
			 
             
             
         
         

Fix information:
repo_url: https://github.com/vim/vim
commit_details: repo_url: https://github.com/vim/vim
author: Christian Brabandt
author_date: 2023-10-26 21:29:32+02:00
msg: patch 9.0.2068: [security] overflow in :history

Problem:  [security] overflow in :history
Solution: Check that value fits into int

The get_list_range() function, used to parse numbers for the :history
and :clist command internally uses long variables to store the numbers.
However function arguments are integer pointers, which can then
overflow.

Check that the return value from the vim_str2nr() function is not larger
than INT_MAX and if yes, bail out with an error. I guess nobody uses a
cmdline/clist history that needs so many entries... (famous last words).

It is only a moderate vulnerability, so impact should be low.

Github Advisory:
https://github.com/vim/vim/security/advisories/GHSA-q22m-h7m2-9mgm

Signed-off-by: Christian Brabandt <cb@256bit.org>
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: cmdhist.c
change_type: ModificationType.MODIFY
diff: @@ -742,7 +742,10 @@ ex_history(exarg_T *eap)
 	end = arg;
     if (!get_list_range(&end, &hisidx1, &hisidx2) || *end != NUL)
     {
-	semsg(_(e_trailing_characters_str), end);
+	if (*end != NUL)
+	    semsg(_(e_trailing_characters_str), end);
+	else
+	    semsg(_(e_val_too_large), arg);
 	return;
     }
 

programming_language: C
filename: errors.h
change_type: ModificationType.MODIFY
diff: @@ -3560,3 +3560,5 @@ EXTERN char e_xattr_e2big[]
 	INIT(= N_("E1508: Size of the extended attribute value is larger than the maximum size allowed"));
 EXTERN char e_xattr_other[]
 	INIT(= N_("E1509: Error occurred when reading or writing extended attribute"));
+EXTERN char e_val_too_large[]
+	INIT(= N_("E1510: Value too large: %s"));

programming_language: C
filename: ex_getln.c
change_type: ModificationType.MODIFY
diff: @@ -4377,6 +4377,10 @@ get_list_range(char_u **str, int *num1, int *num2)
     {
 	vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0, FALSE, NULL);
 	*str += len;
+	// overflow
+	if (num > INT_MAX)
+	    return FAIL;
+
 	*num1 = (int)num;
 	first = TRUE;
     }
@@ -4387,8 +4391,12 @@ get_list_range(char_u **str, int *num1, int *num2)
 	vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0, FALSE, NULL);
 	if (len > 0)
 	{
-	    *num2 = (int)num;
 	    *str = skipwhite(*str + len);
+	    // overflow
+	    if (num > INT_MAX)
+		return FAIL;
+
+	    *num2 = (int)num;
 	}
 	else if (!first)		// no number given at all
 	    return FAIL;

programming_language: C
filename: test_history.vim
change_type: ModificationType.MODIFY
diff: @@ -254,4 +254,12 @@ func Test_history_crypt_key()
   set key& bs& ts&
 endfunc
 
+" The following used to overflow and causing an use-after-free
+func Test_history_max_val()
+
+  set history=10
+  call assert_fails(':history 2147483648', 'E1510:')
+  set history&
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab

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

programming_language: Ruby