CVE-2023-48232: Improper Handling of Exceptional Conditions (CWE-755)
value: Vim is an open source command line text editor. A floating point exception may occur when calculating the line offset for overlong lines and smooth scrolling is enabled and the cpo-settings include the 'n' flag. This may happen when a window border is present and when the wrapped line continues on the next physical line directly in the window border because the 'cpo' setting includes the 'n' flag. Only users with non-default settings are affected and the exception should only result in a crash. This issue has been addressed in commit `cb0b99f0` which has been included in release version 9.0.2107. Users are advised to upgrade. There are no known workarounds for this vulnerability.
CWE description: The product does not handle or incorrectly handles an exceptional condition.
CVSS v3 base score: 4.3
Published: 2023-11-16T23:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/move.c, src/testdir/test_scroll_opt.vim, src/version.c
Commit date: 2023-11-16 22:04:37 +0100
Commit message: patch 9.0.2107: [security]: FPE in adjust_plines_for_skipcol

Problem:  [security]: FPE in adjust_plines_for_skipcol
Solution: don't divide by zero, return zero

Prevent a floating point exception when calculating w_skipcol (which can
happen with a small window when the number option is set and cpo+=n).

Add a test to verify

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

Diff: diff --git a/src/move.c b/src/move.c
index ce06dc339468..fbb352a32e15 100644
--- a/src/move.c
+++ b/src/move.c
@@ -43,12 +43,13 @@ adjust_plines_for_skipcol(win_T *wp)
 {
     if (wp->w_skipcol == 0)
 	return 0;
 
     int width = wp->w_width - win_col_off(wp);
-    if (wp->w_skipcol >= width)
-	return (wp->w_skipcol - width) / (width + win_col_off2(wp)) + 1;
+    int w2 = width + win_col_off2(wp);
+    if (wp->w_skipcol >= width && w2 > 0)
+	return (wp->w_skipcol - width) / w2 + 1;
 
     return 0;
 }
 
 /*
diff --git a/src/testdir/test_scroll_opt.vim b/src/testdir/test_scroll_opt.vim
index d5d08a24c20d..342d382c20a5 100644
--- a/src/testdir/test_scroll_opt.vim
+++ b/src/testdir/test_scroll_opt.vim
@@ -924,6 +924,25 @@ func Test_smoothscroll_cursor_top()
   call VerifyScreenDump(buf, 'Test_smoothscroll_cursor_top', {})
 
   call StopVimInTerminal(buf)
 endfunc
 
+" Division by zero, shouldn't crash
+func Test_smoothscroll_crash()
+  CheckScreendump
+
+  let lines =<< trim END
+      20 new
+      vsp
+      put =repeat('aaaa', 20)
+      set nu fdc=1  smoothscroll cpo+=n
+      vert resize 0
+      exe "norm! 0\<c-e>"
+  END
+  call writefile(lines, 'XSmoothScrollCrash', 'D')
+  let buf = RunVimInTerminal('-u NONE -S XSmoothScrollCrash', #{rows: 12, cols:40})
+  call term_sendkeys(buf, "2\<C-E>\<C-L>")
+
+  call StopVimInTerminal(buf)
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index ec021985f258..684f3acf4c0f 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 */
+/**/
+    2107,
 /**/
     2106,
 /**/
     2105,
 /**/

Vulnerable code:     if (wp->w_skipcol >= width)
	return (wp->w_skipcol - width) / (width + win_col_off2(wp)) + 1;
Fixed code:     int w2 = width + win_col_off2(wp);
    if (wp->w_skipcol >= width && w2 > 0)
	return (wp->w_skipcol - width) / w2 + 1;
" Division by zero, shouldn't crash
func Test_smoothscroll_crash()
  CheckScreendump

  let lines =<< trim END
      20 new
      vsp
      put =repeat('aaaa', 20)
      set nu fdc=1  smoothscroll cpo+=n
      vert resize 0
      exe "norm! 0\<c-e>"
  END
  call writefile(lines, 'XSmoothScrollCrash', 'D')
  let buf = RunVimInTerminal('-u NONE -S XSmoothScrollCrash', #{rows: 12, cols:40})
  call term_sendkeys(buf, "2\<C-E>\<C-L>")

  call StopVimInTerminal(buf)
endfunc

/**/
    2107,