]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.0647: [security] use-after-free in tagstack_clear_entry v9.1.0647
authorChristian Brabandt <cb@256bit.org>
Thu, 1 Aug 2024 18:16:51 +0000 (20:16 +0200)
committerChristian Brabandt <cb@256bit.org>
Thu, 1 Aug 2024 20:35:18 +0000 (22:35 +0200)
Problem:  [security] use-after-free in tagstack_clear_entry
          (Suyue Guo )
Solution: Instead of manually calling vim_free() on each of the tagstack
          entries, let's use tagstack_clear_entry(), which will
          also free the stack, but using the VIM_CLEAR macro,
          which prevents a use-after-free by setting those pointers
          to NULL

This addresses CVE-2024-41957

Github advisory:
https://github.com/vim/vim/security/advisories/GHSA-f9cr-gv85-hcr4

Signed-off-by: Christian Brabandt <cb@256bit.org>
src/testdir/crash/double_free [new file with mode: 0644]
src/testdir/test_crash.vim
src/version.c
src/window.c

diff --git a/src/testdir/crash/double_free b/src/testdir/crash/double_free
new file mode 100644 (file)
index 0000000..895c4a0
Binary files /dev/null and b/src/testdir/crash/double_free differ
index fd786e5d545eefacedef4b5cef66198b3bb4d50f..29061aa4238fdda184e7add8367ef38cb326b76f 100644 (file)
@@ -190,6 +190,12 @@ func Test_crash1_3()
   call term_sendkeys(buf, args)
   call TermWait(buf, 150)
 
+  let file = 'crash/double_free'
+  let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'\<cr>"
+  let args = printf(cmn_args, vim, file)
+  call term_sendkeys(buf, args)
+  call TermWait(buf, 50)
+
   " clean up
   exe buf .. "bw!"
   bw!
index 4dc9948d98e89bdf621b633863b0eeccbc71b9db..0e49ebd7a05f229d58f2099396ad854a3687b52a 100644 (file)
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    647,
 /**/
     646,
 /**/
index 7ca29d46a587667062d9451ad915fa2764d37264..70c72bca751e7bbb265b43fd2a9aeae9147ea1b0 100644 (file)
@@ -5837,10 +5837,7 @@ win_free(
     win_free_lsize(wp);
 
     for (i = 0; i < wp->w_tagstacklen; ++i)
-    {
-       vim_free(wp->w_tagstack[i].tagname);
-       vim_free(wp->w_tagstack[i].user_data);
-    }
+       tagstack_clear_entry(&wp->w_tagstack[i]);
     vim_free(wp->w_localdir);
     vim_free(wp->w_prevdir);