CVE-2022-3016 (published 2022-08-28T12:15Z)

Use After Free in GitHub repository vim/vim prior to 9.0.0286.

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-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: Yegappan Lakshmanan
author_date: 2022-08-27 20:59:57+01:00
msg: patch 9.0.0286: using freed memory when location list changed in autocmd

Problem:    Using freed memory when location list changed in autocmd.
Solution:   Return QF_ABORT and handle it. (Yegappan Lakshmanan,
            closes #10993)
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: quickfix.c
change_type: ModificationType.MODIFY
diff: @@ -594,6 +594,7 @@ enum {
     QF_NOMEM = 3,
     QF_IGNORE_LINE = 4,
     QF_MULTISCAN = 5,
+    QF_ABORT = 6
 };
 
 /*
@@ -3153,7 +3154,7 @@ qf_jump_to_usable_window(int qf_fnum, int newwin, int *opened_window)
 /*
  * Edit the selected file or help file.
  * Returns OK if successfully edited the file, FAIL on failing to open the
- * buffer and NOTDONE if the quickfix/location list was freed by an autocmd
+ * buffer and QF_ABORT if the quickfix/location list was freed by an autocmd
  * when opening the buffer.
  */
     static int
@@ -3199,14 +3200,14 @@ qf_jump_edit_buffer(
 	{
 	    emsg(_(e_current_window_was_closed));
 	    *opened_window = FALSE;
-	    return NOTDONE;
+	    return QF_ABORT;
 	}
     }
 
     if (qfl_type == QFLT_QUICKFIX && !qflist_valid(NULL, save_qfid))
     {
 	emsg(_(e_current_quickfix_list_was_changed));
-	return NOTDONE;
+	return QF_ABORT;
     }
 
     // Check if the list was changed.  The pointers may happen to be identical,
@@ -3219,7 +3220,7 @@ qf_jump_edit_buffer(
 	    emsg(_(e_current_quickfix_list_was_changed));
 	else
 	    emsg(_(e_current_location_list_was_changed));
-	return NOTDONE;
+	return QF_ABORT;
     }
 
     return retval;
@@ -3317,7 +3318,8 @@ qf_jump_print_msg(
  * a new window.
  * Returns OK if successfully jumped or opened a window. Returns FAIL if not
  * able to jump/open a window.  Returns NOTDONE if a file is not associated
- * with the entry.
+ * with the entry.  Returns QF_ABORT if the quickfix/location list was modified
+ * by an autocmd.
  */
     static int
 qf_jump_open_window(
@@ -3344,7 +3346,7 @@ qf_jump_open_window(
 	    emsg(_(e_current_quickfix_list_was_changed));
 	else
 	    emsg(_(e_current_location_list_was_changed));
-	return FAIL;
+	return QF_ABORT;
     }
 
     // If currently in the quickfix window, find another window to show the
@@ -3368,7 +3370,7 @@ qf_jump_open_window(
 	    emsg(_(e_current_quickfix_list_was_changed));
 	else
 	    emsg(_(e_current_location_list_was_changed));
-	return FAIL;
+	return QF_ABORT;
     }
 
     return OK;
@@ -3379,7 +3381,7 @@ qf_jump_open_window(
  * particular line/column, adjust the folds and display a message about the
  * jump.
  * Returns OK on success and FAIL on failing to open the file/buffer.  Returns
- * NOTDONE if the quickfix/location list is freed by an autocmd when opening
+ * QF_ABORT if the quickfix/location list is freed by an autocmd when opening
  * the file.
  */
     static int
@@ -3508,14 +3510,20 @@ qf_jump_newwin(qf_info_T	*qi,
     retval = qf_jump_open_window(qi, qf_ptr, newwin, &opened_window);
     if (retval == FAIL)
 	goto failed;
+    if (retval == QF_ABORT)
+    {
+	qi = NULL;
+	qf_ptr = NULL;
+	goto theend;
+    }
     if (retval == NOTDONE)
 	goto theend;
 
     retval = qf_jump_to_buffer(qi, qf_index, qf_ptr, forceit, prev_winid,
 				  &opened_window, old_KeyTyped, print_message);
-    if (retval == NOTDONE)
+    if (retval == QF_ABORT)
     {
-	// Quickfix/location list is freed by an autocmd
+	// Quickfix/location list was modified by an autocmd
 	qi = NULL;
 	qf_ptr = NULL;
     }

programming_language: C
filename: test_quickfix.vim
change_type: ModificationType.MODIFY
diff: @@ -6363,5 +6363,22 @@ func Test_quickfixtextfunc_recursive()
   cclose
 endfunc
 
+" Test for replacing the location list from an autocmd. This used to cause a
+" read from freed memory.
+func Test_loclist_replace_autocmd()
+  %bw!
+  call setloclist(0, [], 'f')
+  let s:bufnr = bufnr()
+  cal setloclist(0, [{'0': 0, '': ''}])
+  au BufEnter * cal setloclist(1, [{'t': ''}, {'bufnr': s:bufnr}], 'r')
+  lopen
+  try
+    exe "norm j\<CR>"
+  catch
+  endtry
+  lnext
+  %bw!
+  call setloclist(0, [], 'f')
+endfunc
 
 " vim: shiftwidth=2 sts=2 expandtab

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

programming_language: Ruby