CVE-2022-3037: Use After Free (CWE-416)
value: Use After Free in GitHub repository vim/vim prior to 9.0.0322.
CWE 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.
CVSS v3 base score: 7.8
Published: 2022-08-30T21:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/quickfix.c, src/testdir/test_quickfix.vim, src/version.c
Commit date: 2022-08-29 20:45:16 +0100
Commit message: patch 9.0.0322: crash when no errors and 'quickfixtextfunc' is set

Problem:    Crash when no errors and 'quickfixtextfunc' is set.
Solution:   Do not handle errors if there aren't any.

Diff: diff --git a/src/quickfix.c b/src/quickfix.c
index 78f6880d8020..ab288e0c4d60 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -4759,11 +4759,11 @@ qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int qf_winid)
 	while ((curbuf->b_ml.ml_flags & ML_EMPTY) == 0)
 	    (void)ml_delete((linenr_T)1);
     }
 
     // Check if there is anything to display
-    if (qfl != NULL)
+    if (qfl != NULL && qfl->qf_start != NULL)
     {
 	char_u		dirname[MAXPATHL];
 	int		invalid_val = FALSE;
 	int		prev_bufnr = -1;
 
diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim
index 31d36ef1d63c..ee43cb685a3f 100644
--- a/src/testdir/test_quickfix.vim
+++ b/src/testdir/test_quickfix.vim
@@ -4105,10 +4105,26 @@ func Xgetlist_empty_tests(cchar)
 		\ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
                 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
   endif
 endfunc
 
+func Test_empty_list_quickfixtextfunc()
+  " This was crashing.  Can only reproduce by running it in a separate Vim
+  " instance.
+  let lines =<< trim END
+      func s:Func(o)
+              cgetexpr '0'
+      endfunc
+      cope
+      let &quickfixtextfunc = 's:Func'
+      cgetfile [ex
+  END
+  call writefile(lines, 'Xquickfixtextfunc')
+  call RunVim([], [], '-e -s -S Xquickfixtextfunc -c qa')
+  call delete('Xquickfixtextfunc')
+endfunc
+
 func Test_getqflist()
   call Xgetlist_empty_tests('c')
   call Xgetlist_empty_tests('l')
 endfunc
 
diff --git a/src/version.c b/src/version.c
index a1fc74f82ba1..be50c4206554 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,10 +705,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    322,
 /**/
     321,
 /**/
     320,
 /**/

Vulnerable code:     if (qfl != NULL)
Fixed code:     if (qfl != NULL && qfl->qf_start != NULL)
func Test_empty_list_quickfixtextfunc()
  " This was crashing.  Can only reproduce by running it in a separate Vim
  " instance.
  let lines =<< trim END
      func s:Func(o)
              cgetexpr '0'
      endfunc
      cope
      let &quickfixtextfunc = 's:Func'
      cgetfile [ex
  END
  call writefile(lines, 'Xquickfixtextfunc')
  call RunVim([], [], '-e -s -S Xquickfixtextfunc -c qa')
  call delete('Xquickfixtextfunc')
endfunc

/**/
    322,