From a44600c79d87d6cccaf9ff4d262f63960c57c764 Mon Sep 17 00:00:00 2001 From: shixuantong Date: Mon, 29 Aug 2022 14:42:14 +0800 Subject: [PATCH] fix CVE-2022-3016 --- backport-CVE-2022-3016.patch | 152 ++++++++++++++++++ ...emory-access-errors-when-calling-set.patch | 150 +++++++++++++++++ vim.spec | 10 +- 3 files changed, 311 insertions(+), 1 deletion(-) create mode 100644 backport-CVE-2022-3016.patch create mode 100644 backport-patch-8.2.1677-memory-access-errors-when-calling-set.patch diff --git a/backport-CVE-2022-3016.patch b/backport-CVE-2022-3016.patch new file mode 100644 index 0000000..a2fcc3f --- /dev/null +++ b/backport-CVE-2022-3016.patch @@ -0,0 +1,152 @@ +From 6d24a51b94beb1991cddce221f90b455e2d50db7 Mon Sep 17 00:00:00 2001 +From: Yegappan Lakshmanan +Date: Sat, 27 Aug 2022 20:59:57 +0100 +Subject: [PATCH] patch 9.0.0286: using freed memory when location list changed + in autocmd + +Problem: Using freed memory when location list changed in autocmd. +Solution: Return QF_ABORT and handle it. (Yegappan Lakshmanan, +closes #10993) +--- + src/quickfix.c | 28 ++++++++++++++++++---------- + src/testdir/test_quickfix.vim | 17 +++++++++++++++++ + 2 files changed, 35 insertions(+), 10 deletions(-) + +diff --git a/src/quickfix.c b/src/quickfix.c +index a88475b..3ae5934 100644 +--- a/src/quickfix.c ++++ b/src/quickfix.c +@@ -584,6 +584,7 @@ enum { + QF_NOMEM = 3, + QF_IGNORE_LINE = 4, + QF_MULTISCAN = 5, ++ QF_ABORT = 6 + }; + + /* +@@ -3099,7 +3100,7 @@ qf_jump_to_usable_window(int qf_fnum, int newwin, int *opened_window) + /* + * Edit the selected file or help file. + * Returns OK if successfully edited the file, FAIL on failing to open the +- * buffer and NOTDONE if the quickfix/location list was freed by an autocmd ++ * buffer and QF_ABORT if the quickfix/location list was freed by an autocmd + * when opening the buffer. + */ + static int +@@ -3144,14 +3145,14 @@ qf_jump_edit_buffer( + { + emsg(_("E924: Current window was closed")); + *opened_window = FALSE; +- return NOTDONE; ++ return QF_ABORT; + } + } + + if (qfl_type == QFLT_QUICKFIX && !qflist_valid(NULL, save_qfid)) + { + emsg(_(e_current_quickfix_list_was_changed)); +- return NOTDONE; ++ return QF_ABORT; + } + + // Check if the list was changed. The pointers may happen to be identical, +@@ -3164,7 +3165,7 @@ qf_jump_edit_buffer( + emsg(_(e_current_quickfix_list_was_changed)); + else + emsg(_(e_current_location_list_was_changed)); +- return NOTDONE; ++ return QF_ABORT; + } + + return retval; +@@ -3262,7 +3263,8 @@ qf_jump_print_msg( + * a new window. + * Returns OK if successfully jumped or opened a window. Returns FAIL if not + * able to jump/open a window. Returns NOTDONE if a file is not associated +- * with the entry. ++ * with the entry. Returns QF_ABORT if the quickfix/location list was modified ++ * by an autocmd. + */ + static int + qf_jump_open_window( +@@ -3288,7 +3290,7 @@ qf_jump_open_window( + emsg(_(e_current_quickfix_list_was_changed)); + else + emsg(_(e_current_location_list_was_changed)); +- return FAIL; ++ return QF_ABORT; + } + + // If currently in the quickfix window, find another window to show the +@@ -3312,7 +3314,7 @@ qf_jump_open_window( + emsg(_(e_current_quickfix_list_was_changed)); + else + emsg(_(e_current_location_list_was_changed)); +- return FAIL; ++ return QF_ABORT; + } + + return OK; +@@ -3323,7 +3325,7 @@ qf_jump_open_window( + * particular line/column, adjust the folds and display a message about the + * jump. + * Returns OK on success and FAIL on failing to open the file/buffer. Returns +- * NOTDONE if the quickfix/location list is freed by an autocmd when opening ++ * QF_ABORT if the quickfix/location list is freed by an autocmd when opening + * the file. + */ + static int +@@ -3451,14 +3453,20 @@ qf_jump_newwin(qf_info_T *qi, + retval = qf_jump_open_window(qi, qf_ptr, newwin, &opened_window); + if (retval == FAIL) + goto failed; ++ if (retval == QF_ABORT) ++ { ++ qi = NULL; ++ qf_ptr = NULL; ++ goto theend; ++ } + if (retval == NOTDONE) + goto theend; + + retval = qf_jump_to_buffer(qi, qf_index, qf_ptr, forceit, prev_winid, + &opened_window, old_KeyTyped, print_message); +- if (retval == NOTDONE) ++ if (retval == QF_ABORT) + { +- // Quickfix/location list is freed by an autocmd ++ // Quickfix/location list was modified by an autocmd + qi = NULL; + qf_ptr = NULL; + } +diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim +index c6c0f28..cf0fdf9 100644 +--- a/src/testdir/test_quickfix.vim ++++ b/src/testdir/test_quickfix.vim +@@ -350,6 +350,23 @@ func Test_lopen_bwipe_all() + call delete('Xresult') + endfunc + ++" Test for replacing the location list from an autocmd. This used to cause a ++" read from freed memory. ++func Test_loclist_replace_autocmd() ++ %bw! ++ call setloclist(0, [], 'f') ++ let s:bufnr = bufnr() ++ cal setloclist(0, [{'0': 0, '': ''}]) ++ au BufEnter * cal setloclist(1, [{'t': ''}, {'bufnr': s:bufnr}], 'r') ++ lopen ++ try ++ exe "norm j\" ++ catch ++ endtry ++ lnext ++ %bw! ++ call setloclist(0, [], 'f') ++endfunc + + " Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile + " commands. +-- +2.27.0 + diff --git a/backport-patch-8.2.1677-memory-access-errors-when-calling-set.patch b/backport-patch-8.2.1677-memory-access-errors-when-calling-set.patch new file mode 100644 index 0000000..26098b5 --- /dev/null +++ b/backport-patch-8.2.1677-memory-access-errors-when-calling-set.patch @@ -0,0 +1,150 @@ +From 4d170af0a9379da64d67dc3fa7cc7297956c6f52 Mon Sep 17 00:00:00 2001 +From: Bram Moolenaar +Date: Sun, 13 Sep 2020 22:21:22 +0200 +Subject: [PATCH] patch 8.2.1677: memory access errors when calling + setloclist() in autocommand + +Problem: Memory access errors when calling setloclist() in an autocommand. +Solution: Give an error if the list was changed unexpectedly. (closes #6946) +--- + src/quickfix.c | 41 ++++++++++++++++++++++++++++++----- + src/testdir/test_quickfix.vim | 24 ++++++++++++++++++++ + 2 files changed, 60 insertions(+), 5 deletions(-) + +diff --git a/src/quickfix.c b/src/quickfix.c +index 206e901..a88475b 100644 +--- a/src/quickfix.c ++++ b/src/quickfix.c +@@ -211,7 +211,9 @@ static char_u *e_no_more_items = (char_u *)N_("E553: No more items"); + static char_u *qf_last_bufname = NULL; + static bufref_T qf_last_bufref = {NULL, 0, 0}; + +-static char *e_loc_list_changed = ++static char *e_current_quickfix_list_was_changed = ++ N_("E925: Current quickfix list was changed"); ++static char *e_current_location_list_was_changed = + N_("E926: Current location list was changed"); + + /* +@@ -3109,6 +3111,7 @@ qf_jump_edit_buffer( + int *opened_window) + { + qf_list_T *qfl = qf_get_curlist(qi); ++ int old_changedtick = qfl->qf_changedtick; + qfltype_T qfl_type = qfl->qfl_type; + int retval = OK; + int old_qf_curlist = qi->qf_curlist; +@@ -3147,17 +3150,20 @@ qf_jump_edit_buffer( + + if (qfl_type == QFLT_QUICKFIX && !qflist_valid(NULL, save_qfid)) + { +- emsg(_("E925: Current quickfix was changed")); ++ emsg(_(e_current_quickfix_list_was_changed)); + return NOTDONE; + } + ++ // Check if the list was changed. The pointers may happen to be identical, ++ // thus also check qf_changedtick. + if (old_qf_curlist != qi->qf_curlist ++ || old_changedtick != qfl->qf_changedtick + || !is_qf_entry_present(qfl, qf_ptr)) + { + if (qfl_type == QFLT_QUICKFIX) +- emsg(_("E925: Current quickfix was changed")); ++ emsg(_(e_current_quickfix_list_was_changed)); + else +- emsg(_(e_loc_list_changed)); ++ emsg(_(e_current_location_list_was_changed)); + return NOTDONE; + } + +@@ -3265,10 +3271,25 @@ qf_jump_open_window( + int newwin, + int *opened_window) + { ++ qf_list_T *qfl = qf_get_curlist(qi); ++ int old_changedtick = qfl->qf_changedtick; ++ int old_qf_curlist = qi->qf_curlist; ++ qfltype_T qfl_type = qfl->qfl_type; ++ + // For ":helpgrep" find a help window or open one. + if (qf_ptr->qf_type == 1 && (!bt_help(curwin->w_buffer) || cmdmod.tab != 0)) + if (jump_to_help_window(qi, newwin, opened_window) == FAIL) + return FAIL; ++ if (old_qf_curlist != qi->qf_curlist ++ || old_changedtick != qfl->qf_changedtick ++ || !is_qf_entry_present(qfl, qf_ptr)) ++ { ++ if (qfl_type == QFLT_QUICKFIX) ++ emsg(_(e_current_quickfix_list_was_changed)); ++ else ++ emsg(_(e_current_location_list_was_changed)); ++ return FAIL; ++ } + + // If currently in the quickfix window, find another window to show the + // file in. +@@ -3283,6 +3304,16 @@ qf_jump_open_window( + opened_window) == FAIL) + return FAIL; + } ++ if (old_qf_curlist != qi->qf_curlist ++ || old_changedtick != qfl->qf_changedtick ++ || !is_qf_entry_present(qfl, qf_ptr)) ++ { ++ if (qfl_type == QFLT_QUICKFIX) ++ emsg(_(e_current_quickfix_list_was_changed)); ++ else ++ emsg(_(e_current_location_list_was_changed)); ++ return FAIL; ++ } + + return OK; + } +@@ -5697,7 +5728,7 @@ vgr_qflist_valid( + if (wp != NULL) + { + // An autocmd has freed the location list. +- emsg(_(e_loc_list_changed)); ++ emsg(_(e_current_location_list_was_changed)); + return FALSE; + } + else +diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim +index 72f3172..c6c0f28 100644 +--- a/src/testdir/test_quickfix.vim ++++ b/src/testdir/test_quickfix.vim +@@ -1401,6 +1401,30 @@ func Test_quickfix_was_changed_by_autocmd() + call XquickfixChangedByAutocmd('l') + endfunc + ++func Test_setloclist_in_autocommand() ++ call writefile(['test1', 'test2'], 'Xfile') ++ edit Xfile ++ let s:bufnr = bufnr() ++ call setloclist(1, ++ \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'}, ++ \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}]) ++ ++ augroup Test_LocList ++ au! ++ autocmd BufEnter * call setloclist(1, ++ \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'}, ++ \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}], 'r') ++ augroup END ++ ++ lopen ++ call assert_fails('exe "normal j\"', 'E926:') ++ ++ augroup Test_LocList ++ au! ++ augroup END ++ call delete('Xfile') ++endfunc ++ + func Test_caddbuffer_to_empty() + helpgr quickfix + call setqflist([], 'r') +-- +2.27.0 + diff --git a/vim.spec b/vim.spec index 324869e..917b604 100644 --- a/vim.spec +++ b/vim.spec @@ -12,7 +12,7 @@ Name: vim Epoch: 2 Version: 8.2 -Release: 61 +Release: 62 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 @@ -167,6 +167,8 @@ Patch6130: backport-CVE-2022-2845.patch Patch6131: backport-CVE-2022-2923.patch Patch6132: backport-CVE-2022-2946.patch Patch6133: backport-CVE-2022-2980.patch +Patch6134: backport-patch-8.2.1677-memory-access-errors-when-calling-set.patch +Patch6135: backport-CVE-2022-3016.patch Patch9000: bugfix-rm-modify-info-version.patch @@ -555,6 +557,12 @@ popd %{_mandir}/man1/evim.* %changelog +* Mon Aug 29 2022 shixuantong - 2:8.2-62 +- Type:CVE +- ID:CVE-2022-3016 +- SUG:NA +- DESC:fix CVE-2022-3016 + * Sat Aug 27 2022 licihua - 2:8.2-61 - Type:CVE - ID:CVE-2022-2980 -- Gitee