fix CVE-2022-3016
(cherry picked from commit a44600c79d87d6cccaf9ff4d262f63960c57c764)
This commit is contained in:
parent
a4cd16d45b
commit
1fb6d9da0b
152
backport-CVE-2022-3016.patch
Normal file
152
backport-CVE-2022-3016.patch
Normal file
@ -0,0 +1,152 @@
|
||||
From 6d24a51b94beb1991cddce221f90b455e2d50db7 Mon Sep 17 00:00:00 2001
|
||||
From: Yegappan Lakshmanan <yegappan@yahoo.com>
|
||||
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\<CR>"
|
||||
+ catch
|
||||
+ endtry
|
||||
+ lnext
|
||||
+ %bw!
|
||||
+ call setloclist(0, [], 'f')
|
||||
+endfunc
|
||||
|
||||
" Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile
|
||||
" commands.
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,150 @@
|
||||
From 4d170af0a9379da64d67dc3fa7cc7297956c6f52 Mon Sep 17 00:00:00 2001
|
||||
From: Bram Moolenaar <Bram@vim.org>
|
||||
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\<CR>"', 'E926:')
|
||||
+
|
||||
+ augroup Test_LocList
|
||||
+ au!
|
||||
+ augroup END
|
||||
+ call delete('Xfile')
|
||||
+endfunc
|
||||
+
|
||||
func Test_caddbuffer_to_empty()
|
||||
helpgr quickfix
|
||||
call setqflist([], 'r')
|
||||
--
|
||||
2.27.0
|
||||
|
||||
10
vim.spec
10
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 <shixuantong@h-partners.com> - 2:8.2-62
|
||||
- Type:CVE
|
||||
- ID:CVE-2022-3016
|
||||
- SUG:NA
|
||||
- DESC:fix CVE-2022-3016
|
||||
|
||||
* Sat Aug 27 2022 licihua <licihua@huawei.com> - 2:8.2-61
|
||||
- Type:CVE
|
||||
- ID:CVE-2022-2980
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user