]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.0017: [security]: use-after-free in eval1_emsg() v9.1.0017
authorYegappan Lakshmanan <yegappan@yahoo.com>
Fri, 12 Jan 2024 16:21:55 +0000 (17:21 +0100)
committerChristian Brabandt <cb@256bit.org>
Fri, 12 Jan 2024 16:27:02 +0000 (17:27 +0100)
Problem:  use-after-free in eval1_emsg() when an empty
          line follows a lambda (by @yu3s)
Solution: only set evalarg->eval_using_cmdline = FALSE when
          the *arg pointer is not null

fixes: #13833
closes: #13841

Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/eval.c
src/testdir/test_vim9_script.vim
src/version.c

index 815d13d42aa9384f6bc60021a6152fc6aaba3459..bf053dfb69494a057c3d36c4d40bfb7cd65f22a5 100644 (file)
@@ -2699,6 +2699,9 @@ eval_next_non_blank(char_u *arg, evalarg_T *evalarg, int *getnext)
 /*
  * To be called after eval_next_non_blank() sets "getnext" to TRUE.
  * Only called for Vim9 script.
+ *
+ * If "arg" is not NULL, then the caller should assign the return value to
+ * "arg".
  */
     char_u *
 eval_next_line(char_u *arg, evalarg_T *evalarg)
@@ -2747,8 +2750,12 @@ eval_next_line(char_u *arg, evalarg_T *evalarg)
     }
 
     // Advanced to the next line, "arg" no longer points into the previous
-    // line.
-    evalarg->eval_using_cmdline = FALSE;
+    // line.  The caller assigns the return value to "arg".
+    // If "arg" is NULL, then the return value is discarded.  In that case,
+    // "arg" still points to the previous line.  So don't reset
+    // "eval_using_cmdline".
+    if (arg != NULL)
+       evalarg->eval_using_cmdline = FALSE;
     return skipwhite(line);
 }
 
index 7ae4d553e3c02de869ce6203f09fa302be879a5f..77b8831d45be5fc1b3500293a24a5920b93e125c 100644 (file)
@@ -4906,6 +4906,31 @@ def Test_for_stmt_space_before_type()
   v9.CheckSourceFailure(lines, 'E1059: No white space allowed before colon: :number in range(10)', 2)
 enddef
 
+" This test used to cause an use-after-free memory access
+def Test_for_empty_line_after_lambda()
+  var lines =<< trim END
+    vim9script
+    echomsg range(0, 2)->map((_, v) => {
+      return 1
+    })
+
+    assert_equal('[1, 1, 1]', v:statusmsg)
+  END
+  v9.CheckSourceSuccess(lines)
+
+  lines =<< trim END
+    vim9script
+    echomsg range(0, 1)->map((_, v) => {
+      return 1
+    }) range(0, 1)->map((_, v) => {
+      return 2
+    }) # comment
+
+    assert_equal('[1, 1] [2, 2]', v:statusmsg)
+  END
+  v9.CheckSourceSuccess(lines)
+enddef
+
 " Keep this last, it messes up highlighting.
 def Test_substitute_cmd()
   new
index 2e178f3bb35a2ee33c0946c723e058ce98f33a86..f440140a4b2596e4b84d518fc736aabc47b3c3bc 100644 (file)
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    17,
 /**/
     16,
 /**/