From b1edc024503854514826d10863382dd6aae1c55f Mon Sep 17 00:00:00 2001 From: dongyuzhen Date: Mon, 17 Oct 2022 17:56:31 +0800 Subject: [PATCH] fix CVE-2022-3278 CVE-2022-3297 CVE-2022-3324 --- ...r-for-incsearch-fails-at-end-of-line.patch | 28 +++ backport-CVE-2022-3278.patch | 56 ++++++ backport-CVE-2022-3297.patch | 162 ++++++++++++++++++ backport-CVE-2022-3324.patch | 70 ++++++++ vim.spec | 12 +- 5 files changed, 327 insertions(+), 1 deletion(-) create mode 100644 backport-9.0.0581-adding-a-character-for-incsearch-fails-at-end-of-line.patch create mode 100644 backport-CVE-2022-3278.patch create mode 100644 backport-CVE-2022-3297.patch create mode 100644 backport-CVE-2022-3324.patch diff --git a/backport-9.0.0581-adding-a-character-for-incsearch-fails-at-end-of-line.patch b/backport-9.0.0581-adding-a-character-for-incsearch-fails-at-end-of-line.patch new file mode 100644 index 0000000..a14c367 --- /dev/null +++ b/backport-9.0.0581-adding-a-character-for-incsearch-fails-at-end-of-line.patch @@ -0,0 +1,28 @@ +From d4566c14e71c55dcef05fb34ea94eba835831527 Mon Sep 17 00:00:00 2001 +From: Bram Moolenaar +Date: Sat, 24 Sep 2022 21:06:39 +0100 +Subject: [PATCH] patch 9.0.0581: adding a character for incsearch fails at end + of line + +Problem: Adding a character for incsearch fails at end of line. +Solution: Only check cursor line number. +--- + src/move.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/move.c b/src/move.c +index 6c654ac..4123ca8 100644 +--- a/src/move.c ++++ b/src/move.c +@@ -652,7 +652,7 @@ cursor_valid(void) + void + validate_cursor(void) + { +- check_cursor(); ++ check_cursor_lnum(); + check_cursor_moved(curwin); + if ((curwin->w_valid & (VALID_WCOL|VALID_WROW)) != (VALID_WCOL|VALID_WROW)) + curs_columns(TRUE); +-- +2.27.0 + diff --git a/backport-CVE-2022-3278.patch b/backport-CVE-2022-3278.patch new file mode 100644 index 0000000..67255d2 --- /dev/null +++ b/backport-CVE-2022-3278.patch @@ -0,0 +1,56 @@ +From 69082916c8b5d321545d60b9f5facad0a2dd5a4e Mon Sep 17 00:00:00 2001 +From: Bram Moolenaar +Date: Thu, 22 Sep 2022 21:35:19 +0100 +Subject: [PATCH] patch 9.0.0552: crash when using NUL in buffer that uses + :source + +Problem: Crash when using NUL in buffer that uses :source. +Solution: Don't get a next line when skipping over NL. +--- + src/eval.c | 2 +- + src/testdir/test_source.vim | 17 +++++++++++++++++ + 2 files changed, 18 insertions(+), 1 deletion(-) + +diff --git a/src/eval.c b/src/eval.c +index 60daca5..8df374a 100644 +--- a/src/eval.c ++++ b/src/eval.c +@@ -2278,7 +2278,7 @@ eval_next_non_blank(char_u *arg, evalarg_T *evalarg, int *getnext) + + if (next != NULL) + { +- *getnext = TRUE; ++ *getnext = *p != NL; + return skipwhite(next); + } + } +diff --git a/src/testdir/test_source.vim b/src/testdir/test_source.vim +index 4736e93..d6aed57 100644 +--- a/src/testdir/test_source.vim ++++ b/src/testdir/test_source.vim +@@ -665,5 +665,22 @@ func Test_source_buffer_long_line() + call delete('Xtest.vim') + endfunc + ++func Test_source_buffer_with_NUL_char() ++ " This was trying to use a line below the buffer. ++ let lines =<< trim END ++ if !exists('g:loaded') ++ let g:loaded = 1 ++ source ++ endif ++ END ++ " Can't have a NL in heredoc ++ let lines += ["silent! vim9 echo [0 \ ? 'a' : 'b']"] ++ call writefile(lines, 'XsourceNul', '') ++ edit XsourceNul ++ source ++ ++ bwipe! ++endfunc ++ + + " vim: shiftwidth=2 sts=2 expandtab +-- +2.27.0 + diff --git a/backport-CVE-2022-3297.patch b/backport-CVE-2022-3297.patch new file mode 100644 index 0000000..c80ef13 --- /dev/null +++ b/backport-CVE-2022-3297.patch @@ -0,0 +1,162 @@ +From 0ff01835a40f549c5c4a550502f62a2ac9ac447c Mon Sep 17 00:00:00 2001 +From: Bram Moolenaar +Date: Sat, 24 Sep 2022 19:20:30 +0100 +Subject: [PATCH] patch 9.0.0579: using freed memory when 'tagfunc' wipes out + buffer + +Problem: Using freed memory when 'tagfunc' wipes out buffer that holds + 'complete'. +Solution: Make a copy of the option. Make sure cursor position is valid. +--- + src/insexpand.c | 40 ++++++++++++++++++++++++------- + src/move.c | 1 + + src/testdir/test_ins_complete.vim | 20 ++++++++++++++-- + 3 files changed, 50 insertions(+), 11 deletions(-) + +diff --git a/src/insexpand.c b/src/insexpand.c +index 24308e6..3585ef2 100644 +--- a/src/insexpand.c ++++ b/src/insexpand.c +@@ -2485,7 +2485,8 @@ ins_compl_next_buf(buf_T *buf, int flag) + + if (flag == 'w') // just windows + { +- if (buf == curbuf || wp == NULL) // first call for this flag/expansion ++ if (buf == curbuf || !win_valid(wp)) ++ // first call for this flag/expansion or window was closed + wp = curwin; + while ((wp = (wp->w_next != NULL ? wp->w_next : firstwin)) != curwin + && wp->w_buffer->b_scanned) +@@ -3188,9 +3189,10 @@ enum + */ + typedef struct + { +- char_u *e_cpt; // current entry in 'complete' ++ char_u *e_cpt_copy; // copy of 'complete' ++ char_u *e_cpt; // current entry in "e_cpt_copy" + buf_T *ins_buf; // buffer being scanned +- pos_T *cur_match_pos; // current match position ++ pos_T *cur_match_pos; // current match position + pos_T prev_match_pos; // previous match position + int set_match_pos; // save first_match_pos/last_match_pos + pos_T first_match_pos; // first match position +@@ -3257,7 +3259,8 @@ process_next_cpt_value( + st->set_match_pos = TRUE; + } + else if (vim_strchr((char_u *)"buwU", *st->e_cpt) != NULL +- && (st->ins_buf = ins_compl_next_buf(st->ins_buf, *st->e_cpt)) != curbuf) ++ && (st->ins_buf = ins_compl_next_buf( ++ st->ins_buf, *st->e_cpt)) != curbuf) + { + // Scan a buffer, but not the current one. + if (st->ins_buf->b_ml.ml_mfp != NULL) // loaded buffer +@@ -3756,19 +3759,30 @@ get_next_completion_match(int type, ins_compl_next_state_T *st, pos_T *ini) + static int + ins_compl_get_exp(pos_T *ini) + { +- static ins_compl_next_state_T st; ++ static ins_compl_next_state_T st; ++ static int st_cleared = FALSE; + int i; + int found_new_match; + int type = ctrl_x_mode; + + if (!compl_started) + { +- FOR_ALL_BUFFERS(st.ins_buf) +- st.ins_buf->b_scanned = 0; ++ buf_T *buf; ++ ++ FOR_ALL_BUFFERS(buf) ++ buf->b_scanned = 0; ++ if (!st_cleared) ++ { ++ CLEAR_FIELD(st); ++ st_cleared = TRUE; ++ } + st.found_all = FALSE; + st.ins_buf = curbuf; +- st.e_cpt = (compl_cont_status & CONT_LOCAL) +- ? (char_u *)"." : curbuf->b_p_cpt; ++ vim_free(st.e_cpt_copy); ++ // Make a copy of 'complete', if case the buffer is wiped out. ++ st.e_cpt_copy = vim_strsave((compl_cont_status & CONT_LOCAL) ++ ? (char_u *)"." : curbuf->b_p_cpt); ++ st.e_cpt = st.e_cpt_copy == NULL ? (char_u *)"" : st.e_cpt_copy; + st.last_match_pos = st.first_match_pos = *ini; + } + else if (st.ins_buf != curbuf && !buf_valid(st.ins_buf)) +@@ -4112,6 +4126,7 @@ ins_compl_next( + int todo = count; + int advance; + int started = compl_started; ++ buf_T *orig_curbuf = curbuf; + + // When user complete function return -1 for findstart which is next + // time of 'always', compl_shown_match become NULL. +@@ -4144,6 +4159,13 @@ ins_compl_next( + &num_matches) == -1) + return -1; + ++ if (curbuf != orig_curbuf) ++ { ++ // In case some completion function switched buffer, don't want to ++ // insert the completion elsewhere. ++ return -1; ++ } ++ + // Insert the text of the new completion, or the compl_leader. + if (compl_no_insert && !started) + { +diff --git a/src/move.c b/src/move.c +index b061a75..6c654ac 100644 +--- a/src/move.c ++++ b/src/move.c +@@ -652,6 +652,7 @@ cursor_valid(void) + void + validate_cursor(void) + { ++ check_cursor(); + check_cursor_moved(curwin); + if ((curwin->w_valid & (VALID_WCOL|VALID_WROW)) != (VALID_WCOL|VALID_WROW)) + curs_columns(TRUE); +diff --git a/src/testdir/test_ins_complete.vim b/src/testdir/test_ins_complete.vim +index b303993..702a87c 100644 +--- a/src/testdir/test_ins_complete.vim ++++ b/src/testdir/test_ins_complete.vim +@@ -628,9 +628,8 @@ func Test_pum_with_preview_win() + + call writefile(lines, 'Xpreviewscript') + let buf = RunVimInTerminal('-S Xpreviewscript', #{rows: 12}) +- call TermWait(buf, 50) + call term_sendkeys(buf, "Gi\\") +- call TermWait(buf, 100) ++ call TermWait(buf, 200) + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_pum_with_preview_win', {}) + +@@ -2233,4 +2232,21 @@ func Test_ins_complete_end_of_line() + bwipe! + endfunc + ++func s:Tagfunc(t,f,o) ++ bwipe! ++ return [] ++endfunc ++ ++" This was using freed memory, since 'complete' was in a wiped out buffer. ++" Also using a window that was closed. ++func Test_tagfunc_wipes_out_buffer() ++ new ++ set complete=.,t,w,b,u,i ++ se tagfunc=s:Tagfunc ++ sil norm i ++ ++ bwipe! ++endfunc ++ ++ + " vim: shiftwidth=2 sts=2 expandtab +-- +2.27.0 + diff --git a/backport-CVE-2022-3324.patch b/backport-CVE-2022-3324.patch new file mode 100644 index 0000000..0c49cf4 --- /dev/null +++ b/backport-CVE-2022-3324.patch @@ -0,0 +1,70 @@ +From 8279af514ca7e5fd3c31cf13b0864163d1a0bfeb Mon Sep 17 00:00:00 2001 +From: Bram Moolenaar +Date: Mon, 26 Sep 2022 23:08:22 +0100 +Subject: [PATCH] patch 9.0.0598: using negative array index with negative + width window + +Problem: Using negative array index with negative width window. +Solution: Make sure the window width does not become negative. +--- + src/testdir/test_cmdline.vim | 22 ++++++++++++++++++++++ + src/window.c | 5 ++++- + 2 files changed, 26 insertions(+), 1 deletion(-) + +diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim +index 440df96..ab3bfdf 100644 +--- a/src/testdir/test_cmdline.vim ++++ b/src/testdir/test_cmdline.vim +@@ -3457,4 +3457,26 @@ func Test_cmdwin_freed_buffer_ptr() + bwipe! + endfunc + ++" This was resulting in a window with negative width. ++" The test doesn't reproduce the illegal memory access though... ++func Test_cmdwin_split_often() ++ let lines = &lines ++ let columns = &columns ++ set t_WS= ++ ++ try ++ set encoding=iso8859 ++ set ruler ++ winsize 0 0 ++ noremap 0 H ++ sil norm 0000000q: ++ catch /E36:/ ++ endtry ++ ++ bwipe! ++ set encoding=utf8 ++ let &lines = lines ++ let &columns = columns ++endfunc ++ + " vim: shiftwidth=2 sts=2 expandtab +diff --git a/src/window.c b/src/window.c +index c91ebbc..73060db 100644 +--- a/src/window.c ++++ b/src/window.c +@@ -2087,6 +2087,8 @@ win_equal_rec( + if (hnc) // add next_curwin size + { + next_curwin_size -= p_wiw - (m - n); ++ if (next_curwin_size < 0) ++ next_curwin_size = 0; + new_size += next_curwin_size; + room -= new_size - next_curwin_size; + } +@@ -6495,7 +6497,8 @@ scroll_to_fraction(win_T *wp, int prev_height) + void + win_new_width(win_T *wp, int width) + { +- wp->w_width = width; ++ // Should we give an error if width < 0? ++ wp->w_width = width < 0 ? 0 : width; + wp->w_lines_valid = 0; + changed_line_abv_curs_win(wp); + invalidate_botline_win(wp); +-- +2.27.0 + diff --git a/vim.spec b/vim.spec index a242da8..d6f0c96 100644 --- a/vim.spec +++ b/vim.spec @@ -12,7 +12,7 @@ Name: vim Epoch: 2 Version: 9.0 -Release: 18 +Release: 19 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 @@ -69,6 +69,10 @@ Patch6038: backport-CVE-2022-3256.patch Patch6039: backport-CVE-2022-3296.patch Patch6040: backport-CVE-2022-3352.patch Patch6041: backport-spell-test-fails-because-error-message-changed.patch +Patch6042: backport-CVE-2022-3278.patch +Patch6043: backport-CVE-2022-3297.patch +Patch6044: backport-9.0.0581-adding-a-character-for-incsearch-fails-at-end-of-line.patch +Patch6045: backport-CVE-2022-3324.patch Patch9000: bugfix-rm-modify-info-version.patch @@ -468,6 +472,12 @@ LC_ALL=en_US.UTF-8 make -j1 test %{_mandir}/man1/evim.* %changelog +* Mon Oct 17 2022 dongyuzhen - 2:9.0-19 +- Type:CVE +- ID:CVE-2022-3278 CVE-2022-3297 CVE-2022-3324 +- SUG:NA +- DESC:fix CVE-2022-3278 CVE-2022-3297 CVE-2022-3324 + * Wed Oct 12 2022 dongyuzhen - 2:9.0-18 - Type:CVE - ID:CVE-2022-3352 -- Gitee