]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.0.1857: [security] heap-use-after-free in is_qf_win() v9.0.1857
authorChristian Brabandt <cb@256bit.org>
Sun, 3 Sep 2023 18:20:52 +0000 (20:20 +0200)
committerChristian Brabandt <cb@256bit.org>
Sun, 3 Sep 2023 18:20:52 +0000 (20:20 +0200)
Problem:  heap-use-after-free in is_qf_win()
Solution: Check buffer is valid before accessing it

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

index cca53fe256d522fe8bbec6581c81db9d15623a97..a40c3a66606ea0ece2d6028cc46de82667378486 100644 (file)
@@ -1646,7 +1646,7 @@ getout(int exitval)
            next_tp = tp->tp_next;
            FOR_ALL_WINDOWS_IN_TAB(tp, wp)
            {
-               if (wp->w_buffer == NULL)
+               if (wp->w_buffer == NULL || !buf_valid(wp->w_buffer))
                    // Autocmd must have close the buffer already, skip.
                    continue;
                buf = wp->w_buffer;
index aa431ea10578ec162e9f286546e640aba5538cdb..a3d3e8fb7914e4b4c3649e5529d18f955d3c24b4 100644 (file)
@@ -4492,7 +4492,7 @@ is_qf_win(win_T *win, qf_info_T *qi)
     // set to NULL.
     // A window displaying a location list buffer will have the w_llist_ref
     // pointing to the location list.
-    if (bt_quickfix(win->w_buffer))
+    if (buf_valid(win->w_buffer) && bt_quickfix(win->w_buffer))
        if ((IS_QF_STACK(qi) && win->w_llist_ref == NULL)
                || (IS_LL_STACK(qi) && win->w_llist_ref == qi))
            return TRUE;
diff --git a/src/testdir/crash/bt_quickfix_poc b/src/testdir/crash/bt_quickfix_poc
new file mode 100644 (file)
index 0000000..bf02b4d
--- /dev/null
@@ -0,0 +1,9 @@
+comman!-narg=* Xexpr <mods>lex<args>
+auto BufReadPre * exe"sn" ..expand("<abuf>") 
+fu Xautocmd_changelist()
+cal writefile(['Xtestfile2:4:4'],'Xerr')
+  sil! edi Xerr
+Xexpr 'Xtestfile:4:4'
+endf
+call Xautocmd_changelist()
+call Xautocmd_changelist()
\ No newline at end of file
index eb3c0a37fbc6bf1ca521b421d1d34a90309cadbd..516d991939620d76c7a7b0ad5bcedbccfca17cb6 100644 (file)
@@ -5,38 +5,58 @@ source screendump.vim
 CheckScreendump
 
 func Test_crash1()
+  if !executable('sh')
+    throw 'Skipped: sh not executable!'
+  endif
   " The following used to crash Vim
-  " let opts = #{wait_for_ruler: 0, rows: 20, cmd: 'sh'}
   let opts = #{cmd: 'sh'}
-  let args = 'bash'
   let vim  = GetVimProg()
 
-  let buf = RunVimInTerminal(args, opts)
+  let buf = RunVimInTerminal('sh', opts)
 
   let file = 'crash/poc_huaf1'
   let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'"
   let args = printf(cmn_args, vim, file)
   call term_sendkeys(buf, args ..
-    \ '  && echo "crash 1: [OK]" >> X_crash1_result.txt' .. "\<cr>")
+    \ '  && echo "crash 1: [OK]" > X_crash1_result.txt' .. "\<cr>")
+  call TermWait(buf, 50)
 
   let file = 'crash/poc_huaf2'
   let args = printf(cmn_args, vim, file)
   call term_sendkeys(buf, args ..
     \ '  && echo "crash 2: [OK]" >> X_crash1_result.txt' .. "\<cr>")
+  call TermWait(buf, 50)
 
   let file = 'crash/poc_huaf3'
   let args = printf(cmn_args, vim, file)
   call term_sendkeys(buf, args ..
     \ '  && echo "crash 3: [OK]" >> X_crash1_result.txt' .. "\<cr>")
+  call TermWait(buf, 100)
 
-  call TermWait(buf, 50)
+  let file = 'crash/bt_quickfix_poc'
+  let args = printf(cmn_args, vim, file)
+  call term_sendkeys(buf, args ..
+    \ '  && echo "crash 4: [OK]" >> X_crash1_result.txt' .. "\<cr>")
+  " clean up
+  call delete('Xerr')
+
+  " This test takes a bit longer
+  call TermWait(buf, 200)
 
   " clean up
+  call delete('Xerr')
   exe buf .. "bw!"
 
   sp X_crash1_result.txt
-  call assert_equal(['crash 1: [OK]', 'crash 2: [OK]', 'crash 3: [OK]'],
-    \ getline(1, '$'))
+
+  let expected = [
+      \ 'crash 1: [OK]',
+      \ 'crash 2: [OK]',
+      \ 'crash 3: [OK]',
+      \ 'crash 4: [OK]',
+      \ ]
+
+  call assert_equal(expected, getline(1, '$'))
   bw!
 
   call delete('X_crash1_result.txt')
index 98964fbbd17972050150fedd46420eef402708a6..13d5d695a69fc91f664526a725ce1fa3f55ca56f 100644 (file)
@@ -699,6 +699,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1857,
 /**/
     1856,
 /**/