From 3e413c19cf004ed91b28adff5e2c4baef8e4a167 Mon Sep 17 00:00:00 2001 From: wangjiang Date: Wed, 22 Nov 2023 10:04:09 +0800 Subject: [PATCH] fix CVE-2023-48231 CVE-2023-48233 CVE-2023-48234 CVE-2023-48235 CVE-2023-48236 CVE-2023-48237 (cherry picked from commit 1af01b9e738648ca3206f1873ba703f897a7b947) --- backport-CVE-2023-48231.patch | 32 +++++ backport-CVE-2023-48233.patch | 112 ++++++++++++++++++ backport-CVE-2023-48234.patch | 50 ++++++++ backport-CVE-2023-48235.patch | 50 ++++++++ backport-CVE-2023-48236.patch | 53 +++++++++ backport-CVE-2023-48237.patch | 97 +++++++++++++++ ...tion-not-accurate-when-adding-digits.patch | 94 +++++++++++++++ vim.spec | 15 ++- 8 files changed, 502 insertions(+), 1 deletion(-) create mode 100644 backport-CVE-2023-48231.patch create mode 100644 backport-CVE-2023-48233.patch create mode 100644 backport-CVE-2023-48234.patch create mode 100644 backport-CVE-2023-48235.patch create mode 100644 backport-CVE-2023-48236.patch create mode 100644 backport-CVE-2023-48237.patch create mode 100644 backport-patch-9.0.2114-overflow-detection-not-accurate-when-adding-digits.patch diff --git a/backport-CVE-2023-48231.patch b/backport-CVE-2023-48231.patch new file mode 100644 index 0000000..09aa539 --- /dev/null +++ b/backport-CVE-2023-48231.patch @@ -0,0 +1,32 @@ +From 25aabc2b8ee1e19ced6f4da9d866cf9378fc4c5a Mon Sep 17 00:00:00 2001 +From: Christian Brabandt +Date: Tue, 14 Nov 2023 19:31:34 +0100 +Subject: [PATCH] patch 9.0.2106: [security]: Use-after-free in win_close() + +Problem: [security]: Use-after-free in win_close() +Solution: Check window is valid, before accessing it + +If the current window structure is no longer valid (because a previous +autocommand has already freed this window), fail and return before +attempting to set win->w_closing variable. + +Add a test to trigger ASAN in CI + +Signed-off-by: Christian Brabandt +--- + src/window.c | 2 ++ + 1 files changed, 2 insertions(+) + +diff --git a/src/window.c b/src/window.c +index f77ede330d304..55ce31c886437 100644 +--- a/src/window.c ++++ b/src/window.c +@@ -2606,6 +2606,8 @@ win_close(win_T *win, int free_buf) + reset_VIsual_and_resel(); // stop Visual mode + + other_buffer = TRUE; ++ if (!win_valid(win)) ++ return FAIL; + win->w_closing = TRUE; + apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf); + if (!win_valid(win)) diff --git a/backport-CVE-2023-48233.patch b/backport-CVE-2023-48233.patch new file mode 100644 index 0000000..5872aa8 --- /dev/null +++ b/backport-CVE-2023-48233.patch @@ -0,0 +1,112 @@ +From ac63787734fda2e294e477af52b3bd601517fa78 Mon Sep 17 00:00:00 2001 +From: Christian Brabandt +Date: Tue, 14 Nov 2023 20:45:48 +0100 +Subject: [PATCH] patch 9.0.2108: [security]: overflow with count for :s + command + +Problem: [security]: overflow with count for :s command +Solution: Abort the :s command if the count is too large + +If the count after the :s command is larger than what fits into a +(signed) long variable, abort with e_value_too_large. + +Adds a test with INT_MAX as count and verify it correctly fails. + +It seems the return value on Windows using mingw compiler wraps around, +so the initial test using :s/./b/9999999999999999999999999990 doesn't +fail there, since the count is wrapping around several times and finally +is no longer larger than 2147483647. So let's just use 2147483647 in the +test, which hopefully will always cause a failure + +Signed-off-by: Christian Brabandt +--- + runtime/doc/change.txt | 8 ++++---- + runtime/doc/cmdline.txt | 3 ++- + runtime/doc/tags | 1 + + src/ex_cmds.c | 7 +++++++ + src/testdir/test_substitute.vim | 1 + + 5 files changed, 15 insertions(+), 5 deletions(-) + +diff --git a/runtime/doc/change.txt b/runtime/doc/change.txt +index 65da9a7c6b92b..dccaa44c89922 100644 +--- a/runtime/doc/change.txt ++++ b/runtime/doc/change.txt +@@ -1,4 +1,4 @@ +-*change.txt* For Vim version 9.0. Last change: 2022 May 26 ++*change.txt* For Vim version 9.0. Last change: 2023 Nov 15 + + + VIM REFERENCE MANUAL by Bram Moolenaar +@@ -635,9 +635,9 @@ For other systems the tmpnam() library function is used. + current line only. When [count] is given, replace in + [count] lines, starting with the last line in [range]. + When [range] is omitted start in the current line. +- *E939* +- [count] must be a positive number. Also see +- |cmdline-ranges|. ++ *E939* *E1510* ++ [count] must be a positive number (max 2147483647) ++ Also see |cmdline-ranges|. + + See |:s_flags| for [flags]. + The delimiter doesn't need to be /, see +diff --git a/runtime/doc/cmdline.txt b/runtime/doc/cmdline.txt +index c5d0096ddb74c..cbcf0ad274fe2 100644 +--- a/runtime/doc/cmdline.txt ++++ b/runtime/doc/cmdline.txt +@@ -1,4 +1,4 @@ +-*cmdline.txt* For Vim version 9.0. Last change: 2022 Jun 16 ++*cmdline.txt* For Vim version 9.0. Last change: 2023 Nov 15 + + + VIM REFERENCE MANUAL by Bram Moolenaar +@@ -359,6 +359,7 @@ terminals) + A positive number represents the absolute index of an entry + as it is given in the first column of a :history listing. + This number remains fixed even if other entries are deleted. ++ (see |E1510|) + + A negative number means the relative position of an entry, + counted from the newest entry (which has index -1) backwards. +diff --git a/runtime/doc/tags b/runtime/doc/tags +index f49061aa21064..0021ddb127793 100644 +--- a/runtime/doc/tags ++++ b/runtime/doc/tags +@@ -4300,6 +4300,7 @@ E149 helphelp.txt /*E149* + E15 eval.txt /*E15* + E150 helphelp.txt /*E150* + E151 helphelp.txt /*E151* ++E1510 change.txt /*E1510* + E152 helphelp.txt /*E152* + E153 helphelp.txt /*E153* + E154 helphelp.txt /*E154* +diff --git a/src/ex_cmds.c b/src/ex_cmds.c +index 3544092d65b11..c5f912e7ee57f 100644 +--- a/src/ex_cmds.c ++++ b/src/ex_cmds.c +@@ -3940,6 +3940,13 @@ ex_substitute(exarg_T *eap) + emsg(_(e_positive_count_required)); + return; + } ++ else if (i >= INT_MAX) ++ { ++ char buf[20]; ++ vim_snprintf(buf, sizeof(buf), "%ld", i); ++ semsg(_(e_val_too_large), buf); ++ return; ++ } + eap->line1 = eap->line2; + eap->line2 += i - 1; + if (eap->line2 > curbuf->b_ml.ml_line_count) +diff --git a/src/testdir/test_substitute.vim b/src/testdir/test_substitute.vim +index b99d0e0058270..3ed159799f5cc 100644 +--- a/src/testdir/test_substitute.vim ++++ b/src/testdir/test_substitute.vim +@@ -205,6 +205,7 @@ func Test_substitute_count() + call assert_equal(['foo foo', 'foo foo', 'foo foo', 'bar foo', 'bar foo'], + \ getline(1, '$')) + ++ call assert_fails('s/./b/2147483647', 'E1510:') + bwipe! + endfunc + diff --git a/backport-CVE-2023-48234.patch b/backport-CVE-2023-48234.patch new file mode 100644 index 0000000..9822968 --- /dev/null +++ b/backport-CVE-2023-48234.patch @@ -0,0 +1,50 @@ +From 58f9befca1fa172068effad7f2ea5a9d6a7b0cca Mon Sep 17 00:00:00 2001 +From: Christian Brabandt +Date: Tue, 14 Nov 2023 21:02:30 +0100 +Subject: [PATCH] patch 9.0.2109: [security]: overflow in nv_z_get_count + +Problem: [security]: overflow in nv_z_get_count +Solution: break out, if count is too large + +When getting the count for a normal z command, it may overflow for large +counts given. So verify, that we can safely store the result in a long. + +Signed-off-by: Christian Brabandt +--- + src/normal.c | 7 +++++++ + src/testdir/test_normal.vim | 5 +++++ + 2 files changed, 12 insertions(+) + +diff --git a/src/normal.c b/src/normal.c +index a06d61e6fce7d..16b4b45069329 100644 +--- a/src/normal.c ++++ b/src/normal.c +@@ -2567,7 +2567,14 @@ nv_z_get_count(cmdarg_T *cap, int *nchar_arg) + if (nchar == K_DEL || nchar == K_KDEL) + n /= 10; + else if (VIM_ISDIGIT(nchar)) ++ { ++ if (n > LONG_MAX / 10) ++ { ++ clearopbeep(cap->oap); ++ break; ++ } + n = n * 10 + (nchar - '0'); ++ } + else if (nchar == CAR) + { + #ifdef FEAT_GUI +diff --git a/src/testdir/test_normal.vim b/src/testdir/test_normal.vim +index c7d37f066f208..6b889f46b3dd7 100644 +--- a/src/testdir/test_normal.vim ++++ b/src/testdir/test_normal.vim +@@ -3757,4 +3757,9 @@ func Test_normal33_g_cmd_nonblank() + bwipe! + endfunc + ++func Test_normal34_zet_large() ++ " shouldn't cause overflow ++ norm! z9765405999999999999 ++endfunc ++ + " vim: shiftwidth=2 sts=2 expandtab diff --git a/backport-CVE-2023-48235.patch b/backport-CVE-2023-48235.patch new file mode 100644 index 0000000..3c56681 --- /dev/null +++ b/backport-CVE-2023-48235.patch @@ -0,0 +1,50 @@ +From 060623e4a3bc72b011e7cd92bedb3bfb64e06200 Mon Sep 17 00:00:00 2001 +From: Christian Brabandt +Date: Tue, 14 Nov 2023 21:33:29 +0100 +Subject: [PATCH] patch 9.0.2110: [security]: overflow in ex address parsing + +Problem: [security]: overflow in ex address parsing +Solution: Verify that lnum is positive, before substracting from + LONG_MAX + +[security]: overflow in ex address parsing + +When parsing relative ex addresses one may unintentionally cause an +overflow (because LONG_MAX - lnum will overflow for negative addresses). + +So verify that lnum is actually positive before doing the overflow +check. + +Signed-off-by: Christian Brabandt +--- + src/ex_docmd.c | 2 +- + src/testdir/test_excmd.vim | 4 ++++ + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/ex_docmd.c b/src/ex_docmd.c +index 06837ac92c55c..01d411a632ccf 100644 +--- a/src/ex_docmd.c ++++ b/src/ex_docmd.c +@@ -4603,7 +4603,7 @@ get_address( + lnum -= n; + else + { +- if (n >= LONG_MAX - lnum) ++ if (lnum >= 0 && n >= LONG_MAX - lnum) + { + emsg(_(e_line_number_out_of_range)); + goto error; +diff --git a/src/testdir/test_excmd.vim b/src/testdir/test_excmd.vim +index 3637351f636c0..47fc26726d5e6 100644 +--- a/src/testdir/test_excmd.vim ++++ b/src/testdir/test_excmd.vim +@@ -725,5 +725,9 @@ func Test_write_after_rename() + bwipe! + endfunc + ++" catch address lines overflow ++func Test_ex_address_range_overflow() ++ call assert_fails(':--+foobar', 'E492:') ++endfunc + + " vim: shiftwidth=2 sts=2 expandtab diff --git a/backport-CVE-2023-48236.patch b/backport-CVE-2023-48236.patch new file mode 100644 index 0000000..82651d8 --- /dev/null +++ b/backport-CVE-2023-48236.patch @@ -0,0 +1,53 @@ +From 73b2d3790cad5694fc0ed0db2926e4220c48d968 Mon Sep 17 00:00:00 2001 +From: Christian Brabandt +Date: Tue, 14 Nov 2023 21:58:26 +0100 +Subject: [PATCH] patch 9.0.2111: [security]: overflow in get_number + +Problem: [security]: overflow in get_number +Solution: Return 0 when the count gets too large + +[security]: overflow in get_number + +When using the z= command, we may overflow the count with values larger +than MAX_INT. So verify that we do not overflow and in case when an +overflow is detected, simply return 0 + +Signed-off-by: Christian Brabandt +--- + src/misc1.c | 2 ++ + src/testdir/test_spell.vim | 9 +++++++++ + 2 files changed, 11 insertions(+) + +diff --git a/src/misc1.c b/src/misc1.c +index 5b008c614a9bb..5f9828ebe9544 100644 +--- a/src/misc1.c ++++ b/src/misc1.c +@@ -951,6 +951,8 @@ get_number( + c = safe_vgetc(); + if (VIM_ISDIGIT(c)) + { ++ if (n > INT_MAX / 10) ++ return 0; + n = n * 10 + c - '0'; + msg_putchar(c); + ++typed; +diff --git a/src/testdir/test_spell.vim b/src/testdir/test_spell.vim +index be0bc55810f0e..1ddcd83d5117e 100644 +--- a/src/testdir/test_spell.vim ++++ b/src/testdir/test_spell.vim +@@ -965,6 +965,15 @@ func Test_spell_screendump() + call delete('XtestSpell') + endfunc + ++func Test_z_equal_with_large_count() ++ split ++ set spell ++ call setline(1, "ff") ++ norm 0z=337203685477580 ++ set nospell ++ bwipe! ++endfunc ++ + let g:test_data_aff1 = [ + \"SET ISO8859-1", + \"TRY esianrtolcdugmphbyfvkwjkqxz-\xEB\xE9\xE8\xEA\xEF\xEE\xE4\xE0\xE2\xF6\xFC\xFB'ESIANRTOLCDUGMPHBYFVKWJKQXZ", diff --git a/backport-CVE-2023-48237.patch b/backport-CVE-2023-48237.patch new file mode 100644 index 0000000..076523c --- /dev/null +++ b/backport-CVE-2023-48237.patch @@ -0,0 +1,97 @@ +From 6bf131888a3d1de62bbfa8a7ea03c0ddccfd496e Mon Sep 17 00:00:00 2001 +From: Christian Brabandt +Date: Tue, 14 Nov 2023 22:42:59 +0100 +Subject: [PATCH] patch 9.0.2112: [security]: overflow in shift_line + +Problem: [security]: overflow in shift_line +Solution: allow a max indent of INT_MAX + +[security]: overflow in shift_line + +When shifting lines in operator pending mode and using a very large +value, we may overflow the size of integer. Fix this by using a long +variable, testing if the result would be larger than INT_MAX and if so, +indent by INT_MAX value. + +Special case: We cannot use long here, since on 32bit architectures (or +on Windows?), it typically cannot take larger values than a plain int, +so we have to use long long count, decide whether the resulting +multiplication of the shiftwidth value * amount is larger than INT_MAX +and if so, we will store INT_MAX as possible larges value in the long +long count variable. + +Then we can safely cast it back to int when calling the functions to set +the indent (set_indent() or change_indent()). So this should be safe. + +Add a test that when using a huge value in operator pending mode for +shifting, we will shift by INT_MAX + +closes: #13535 + +Signed-off-by: Christian Brabandt +--- + src/ops.c | 15 ++++++++++----- + src/testdir/test_indent.vim | 11 +++++++++++ + 2 files changed, 21 insertions(+), 5 deletions(-) + +diff --git a/src/ops.c b/src/ops.c +index c0a2981d68770..ecd7fc2170c58 100644 +--- a/src/ops.c ++++ b/src/ops.c +@@ -226,11 +226,11 @@ shift_line( + int amount, + int call_changed_bytes) // call changed_bytes() + { +- int count; ++ long long count; + int i, j; + int sw_val = (int)get_sw_value_indent(curbuf); + +- count = get_indent(); // get current indent ++ count = (long long)get_indent(); // get current indent + + if (round) // round off indent + { +@@ -257,14 +257,19 @@ shift_line( + count = 0; + } + else +- count += sw_val * amount; ++ { ++ if ((long long)sw_val * (long long)amount > INT_MAX - count) ++ count = INT_MAX; ++ else ++ count += (long long)sw_val * (long long)amount; ++ } + } + + // Set new indent + if (State & VREPLACE_FLAG) +- change_indent(INDENT_SET, count, FALSE, NUL, call_changed_bytes); ++ change_indent(INDENT_SET, (int)count, FALSE, NUL, call_changed_bytes); + else +- (void)set_indent(count, call_changed_bytes ? SIN_CHANGED : 0); ++ (void)set_indent((int)count, call_changed_bytes ? SIN_CHANGED : 0); + } + + /* +diff --git a/src/testdir/test_indent.vim b/src/testdir/test_indent.vim +index 96e9d2300883c..217a7ae625072 100644 +--- a/src/testdir/test_indent.vim ++++ b/src/testdir/test_indent.vim +@@ -276,4 +276,15 @@ func Test_formatting_keeps_first_line_indent() + bwipe! + endfunc + ++" Test for indenting with large amount, causes overflow ++func Test_indent_overflow_count() ++ new ++ setl sw=8 ++ call setline(1, "abc") ++ norm! V2147483647> ++ " indents by INT_MAX ++ call assert_equal(2147483647, indent(1)) ++ close! ++endfunc ++ + " vim: shiftwidth=2 sts=2 expandtab diff --git a/backport-patch-9.0.2114-overflow-detection-not-accurate-when-adding-digits.patch b/backport-patch-9.0.2114-overflow-detection-not-accurate-when-adding-digits.patch new file mode 100644 index 0000000..a720778 --- /dev/null +++ b/backport-patch-9.0.2114-overflow-detection-not-accurate-when-adding-digits.patch @@ -0,0 +1,94 @@ +From 22cbc8a4e17ce61aa460c451a26e1bff2c3d2af9 Mon Sep 17 00:00:00 2001 +From: Christian Brabandt +Date: Sun, 19 Nov 2023 10:47:21 +0100 +Subject: [PATCH] patch 9.0.2114: overflow detection not accurate when adding + digits + +Problem: overflow detection not accurate when adding digits +Solution: Use a helper function + +Use a helper function to better detect overflows before adding integer +digits to a long or an integer variable respectively. Signal the +overflow to the caller function. + +closes: #13539 + +Signed-off-by: Christian Brabandt +Signed-off-by: Michael Henry +Signed-off-by: Ernie Rael +--- + src/misc1.c | 25 +++++++++++++++++++++++-- + src/normal.c | 3 +-- + src/proto/misc1.pro | 2 ++ + 3 files changed, 26 insertions(+), 4 deletions(-) + +diff --git a/src/misc1.c b/src/misc1.c +index 5f9828ebe9544..dc0deae67af93 100644 +--- a/src/misc1.c ++++ b/src/misc1.c +@@ -951,9 +951,8 @@ get_number( + c = safe_vgetc(); + if (VIM_ISDIGIT(c)) + { +- if (n > INT_MAX / 10) ++ if (vim_append_digit_int(&n, c - '0') == FAIL) + return 0; +- n = n * 10 + c - '0'; + msg_putchar(c); + ++typed; + } +@@ -2755,3 +2754,25 @@ may_trigger_modechanged(void) + restore_v_event(v_event, &save_v_event); + #endif + } ++ ++// For overflow detection, add a digit safely to an int value. ++ int ++vim_append_digit_int(int *value, int digit) ++{ ++ int x = *value; ++ if (x > ((INT_MAX - digit) / 10)) ++ return FAIL; ++ *value = x * 10 + digit; ++ return OK; ++} ++ ++// For overflow detection, add a digit safely to a long value. ++ int ++vim_append_digit_long(long *value, int digit) ++{ ++ long x = *value; ++ if (x > ((LONG_MAX - (long)digit) / 10)) ++ return FAIL; ++ *value = x * 10 + (long)digit; ++ return OK; ++} +diff --git a/src/normal.c b/src/normal.c +index 16b4b45069329..61a19c13a43c9 100644 +--- a/src/normal.c ++++ b/src/normal.c +@@ -2568,12 +2568,11 @@ nv_z_get_count(cmdarg_T *cap, int *nchar_arg) + n /= 10; + else if (VIM_ISDIGIT(nchar)) + { +- if (n > LONG_MAX / 10) ++ if (vim_append_digit_long(&n, nchar - '0') == FAIL) + { + clearopbeep(cap->oap); + break; + } +- n = n * 10 + (nchar - '0'); + } + else if (nchar == CAR) + { +diff --git a/src/proto/misc1.pro b/src/proto/misc1.pro +index b87b7ea747576..2b8e9d8f264cb 100644 +--- a/src/proto/misc1.pro ++++ b/src/proto/misc1.pro +@@ -52,4 +52,6 @@ int path_with_url(char_u *fname); + dict_T *get_v_event(save_v_event_T *sve); + void restore_v_event(dict_T *v_event, save_v_event_T *sve); + void may_trigger_modechanged(void); ++int vim_append_digit_int(int *value, int digit); ++int vim_append_digit_long(long *value, int digit); + /* vim: set ft=c : */ diff --git a/vim.spec b/vim.spec index 2896776..689564c 100644 --- a/vim.spec +++ b/vim.spec @@ -12,7 +12,7 @@ Name: vim Epoch: 2 Version: 9.0 -Release: 21 +Release: 22 Summary: Vim is a highly configurable text editor for efficiently creating and changing any kind of text. License: Vim and MIT URL: http://www.vim.org @@ -111,6 +111,13 @@ Patch6081: backport-CVE-2023-5441.patch Patch6082: backport-CVE-2023-5535.patch Patch6083: backport-CVE-2023-46246.patch Patch6084: backport-patch-improve-the-error-detection.patch +patch6085: backport-CVE-2023-48231.patch +patch6086: backport-CVE-2023-48233.patch +patch6087: backport-CVE-2023-48234.patch +patch6088: backport-CVE-2023-48235.patch +patch6089: backport-CVE-2023-48236.patch +patch6090: backport-CVE-2023-48237.patch +patch6091: backport-patch-9.0.2114-overflow-detection-not-accurate-when-adding-digits.patch Patch9000: bugfix-rm-modify-info-version.patch Patch9001: vim-Add-sw64-architecture.patch @@ -519,6 +526,12 @@ LANG=en_US.UTF-8 make -j1 test %{_mandir}/man1/evim.* %changelog +* Wed Nov 22 2023 wangjiang - 2:9.0-22 +- Type:CVE +- ID:CVE-2023-48231 CVE-2023-48233 CVE-2023-48234 CVE-2023-48235 CVE-2023-48236 CVE-2023-48237 +- SUG:NA +- DESC:fix CVE-2023-48231 CVE-2023-48233 CVE-2023-48234 CVE-2023-48235 CVE-2023-48236 CVE-2023-48237 + * Mon Nov 06 2023 wangjiang - 2:9.0-21 - Type:bugfix - ID:NA -- Gitee