CVE-2023-5441: NULL Pointer Dereference (CWE-476)
value: NULL Pointer Dereference in GitHub repository vim/vim prior to 20d161ace307e28690229b68584f2d84556f8960.
CWE description: The product dereferences a pointer that it expects to be valid but is NULL.
CVSS v3 base score: 5.5
Published: 2023-10-05T21:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/gui.c, src/testdir/crash/crash_scrollbar, src/testdir/test_crash.vim, src/version.c
Commit date: 2023-10-05 22:10:10 +0200
Commit message: patch 9.0.1992: [security] segfault in exmode

Problem:  segfault in exmode when redrawing
Solution: skip gui_scroll when exmode_active

Signed-off-by: Christian Brabandt <cb@256bit.org>

Diff: diff --git a/src/gui.c b/src/gui.c
index 1f546b2a75b5..9c9aa3cbecdc 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -4395,10 +4395,11 @@ gui_do_scrollbar(
 
 /*
  * Scroll a window according to the values set in the globals
  * "current_scrollbar" and "scrollbar_value".
  * Return TRUE if the cursor in the current window moved or FALSE otherwise.
+ * may eventually cause a redraw using updateWindow
  */
     int
 gui_do_scroll(void)
 {
     win_T	*wp, *save_wp;
@@ -4414,10 +4415,13 @@ gui_do_scroll(void)
 	if (wp == NULL)
 	    break;
     if (wp == NULL)
 	// Couldn't find window
 	return FALSE;
+    // don't redraw, LineOffset and similar are not valid!
+    if (exmode_active)
+	return FALSE;
 
     /*
      * Compute number of lines to scroll.  If zero, nothing to do.
      */
     nlines = (long)scrollbar_value + 1 - (long)wp->w_topline;
diff --git a/src/testdir/crash/crash_scrollbar b/src/testdir/crash/crash_scrollbar
new file mode 100644
index 000000000000..1de590522852
--- /dev/null
+++ b/src/testdir/crash/crash_scrollbar
@@ -0,0 +1,2 @@
+" this goes to insert mode and presses key k_VerScrollbar which may cause a redraw in exmode, which used ot crash Vim
+norm oùX
diff --git a/src/testdir/test_crash.vim b/src/testdir/test_crash.vim
index 5c83e3a2f5ff..9a80340c285d 100644
--- a/src/testdir/test_crash.vim
+++ b/src/testdir/test_crash.vim
@@ -70,10 +70,16 @@ func Test_crash1()
   let args = printf(cmn_args, vim, file)
   call term_sendkeys(buf, args ..
     \ '  || echo "crash 8: [OK]" >> X_crash1_result.txt' .. "\<cr>")
   call TermWait(buf, 3000)
 
+  let file = 'crash/crash_scrollbar'
+  let args = printf(cmn_args, vim, file)
+  call term_sendkeys(buf, args ..
+    \ '  && echo "crash 9: [OK]" >> X_crash1_result.txt' .. "\<cr>")
+  call TermWait(buf, 1000)
+
   " clean up
   exe buf .. "bw!"
 
   sp X_crash1_result.txt
 
@@ -84,10 +90,11 @@ func Test_crash1()
       \ 'crash 4: [OK]',
       \ 'crash 5: [OK]',
       \ 'crash 6: [OK]',
       \ 'crash 7: [OK]',
       \ 'crash 8: [OK]',
+      \ 'crash 9: [OK]',
       \ ]
 
   call assert_equal(expected, getline(1, '$'))
   bw!
 
diff --git a/src/version.c b/src/version.c
index 9b1c0b4e9298..2bb134a3b922 100644
--- a/src/version.c
+++ b/src/version.c
@@ -702,10 +702,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1992,
 /**/
     1991,
 /**/
     1990,
 /**/

Fixed code:  * may eventually cause a redraw using updateWindow
    // don't redraw, LineOffset and similar are not valid!
    if (exmode_active)
	return FALSE;
" this goes to insert mode and presses key k_VerScrollbar which may cause a redraw in exmode, which used ot crash Vim
norm oùX
  let file = 'crash/crash_scrollbar'
  let args = printf(cmn_args, vim, file)
  call term_sendkeys(buf, args ..
    \ '  && echo "crash 9: [OK]" >> X_crash1_result.txt' .. "\<cr>")
  call TermWait(buf, 1000)

      \ 'crash 9: [OK]',
/**/
    1992,