fix CVE-2022-2889 CVE-2022-2923 CVE-2022-2946
This commit is contained in:
parent
0d51181826
commit
db1190641a
245
backport-CVE-2022-2889.patch
Normal file
245
backport-CVE-2022-2889.patch
Normal file
@ -0,0 +1,245 @@
|
||||
From 91c7cbfe31bbef57d5fcf7d76989fc159f73ef15 Mon Sep 17 00:00:00 2001
|
||||
From: Bram Moolenaar <Bram@vim.org>
|
||||
Date: Thu, 18 Aug 2022 13:28:31 +0100
|
||||
Subject: [PATCH] patch 9.0.0225: using freed memory with multiple line breaks
|
||||
in expression
|
||||
|
||||
Problem: Using freed memory with multiple line breaks in expression.
|
||||
Solution: Free eval_tofree later.
|
||||
---
|
||||
src/eval.c | 102 ++++++++++++++++++-------------
|
||||
src/proto/eval.pro | 4 +-
|
||||
src/testdir/test_vim9_script.vim | 13 ++++
|
||||
src/userfunc.c | 15 -----
|
||||
4 files changed, 75 insertions(+), 59 deletions(-)
|
||||
|
||||
diff --git a/src/eval.c b/src/eval.c
|
||||
index 42b883e..60daca5 100644
|
||||
--- a/src/eval.c
|
||||
+++ b/src/eval.c
|
||||
@@ -353,6 +353,63 @@ eval_to_string_skip(
|
||||
return retval;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Initialize "evalarg" for use.
|
||||
+ */
|
||||
+ void
|
||||
+init_evalarg(evalarg_T *evalarg)
|
||||
+{
|
||||
+ CLEAR_POINTER(evalarg);
|
||||
+ ga_init2(&evalarg->eval_tofree_ga, sizeof(char_u *), 20);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * If "evalarg->eval_tofree" is not NULL free it later.
|
||||
+ * Caller is expected to overwrite "evalarg->eval_tofree" next.
|
||||
+ */
|
||||
+ static void
|
||||
+free_eval_tofree_later(evalarg_T *evalarg)
|
||||
+{
|
||||
+ if (evalarg->eval_tofree != NULL)
|
||||
+ {
|
||||
+ if (ga_grow(&evalarg->eval_tofree_ga, 1) == OK)
|
||||
+ ((char_u **)evalarg->eval_tofree_ga.ga_data)
|
||||
+ [evalarg->eval_tofree_ga.ga_len++]
|
||||
+ = evalarg->eval_tofree;
|
||||
+ else
|
||||
+ vim_free(evalarg->eval_tofree);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * After using "evalarg" filled from "eap": free the memory.
|
||||
+ */
|
||||
+ void
|
||||
+clear_evalarg(evalarg_T *evalarg, exarg_T *eap)
|
||||
+{
|
||||
+ if (evalarg != NULL)
|
||||
+ {
|
||||
+ if (evalarg->eval_tofree != NULL)
|
||||
+ {
|
||||
+ if (eap != NULL)
|
||||
+ {
|
||||
+ // We may need to keep the original command line, e.g. for
|
||||
+ // ":let" it has the variable names. But we may also need the
|
||||
+ // new one, "nextcmd" points into it. Keep both.
|
||||
+ vim_free(eap->cmdline_tofree);
|
||||
+ eap->cmdline_tofree = *eap->cmdlinep;
|
||||
+ *eap->cmdlinep = evalarg->eval_tofree;
|
||||
+ }
|
||||
+ else
|
||||
+ vim_free(evalarg->eval_tofree);
|
||||
+ evalarg->eval_tofree = NULL;
|
||||
+ }
|
||||
+
|
||||
+ ga_clear_strings(&evalarg->eval_tofree_ga);
|
||||
+ VIM_CLEAR(evalarg->eval_tofree_lambda);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Skip over an expression at "*pp".
|
||||
* Return FAIL for an error, OK otherwise.
|
||||
@@ -435,8 +492,8 @@ skip_expr_concatenate(
|
||||
// Do not free the first line, the caller can still use it.
|
||||
*((char_u **)gap->ga_data) = NULL;
|
||||
// Do not free the last line, "arg" points into it, free it
|
||||
- // later.
|
||||
- vim_free(evalarg->eval_tofree);
|
||||
+ // later. Also free "eval_tofree" later if needed.
|
||||
+ free_eval_tofree_later(evalarg);
|
||||
evalarg->eval_tofree =
|
||||
((char_u **)gap->ga_data)[gap->ga_len - 1];
|
||||
((char_u **)gap->ga_data)[gap->ga_len - 1] = NULL;
|
||||
@@ -2274,7 +2331,7 @@ eval_next_line(char_u *arg, evalarg_T *evalarg)
|
||||
}
|
||||
else if (evalarg->eval_cookie != NULL)
|
||||
{
|
||||
- vim_free(evalarg->eval_tofree);
|
||||
+ free_eval_tofree_later(evalarg);
|
||||
evalarg->eval_tofree = line;
|
||||
}
|
||||
|
||||
@@ -2301,45 +2358,6 @@ skipwhite_and_linebreak(char_u *arg, evalarg_T *evalarg)
|
||||
return p;
|
||||
}
|
||||
|
||||
-/*
|
||||
- * Initialize "evalarg" for use.
|
||||
- */
|
||||
- void
|
||||
-init_evalarg(evalarg_T *evalarg)
|
||||
-{
|
||||
- CLEAR_POINTER(evalarg);
|
||||
- ga_init2(&evalarg->eval_tofree_ga, sizeof(char_u *), 20);
|
||||
-}
|
||||
-
|
||||
-/*
|
||||
- * After using "evalarg" filled from "eap": free the memory.
|
||||
- */
|
||||
- void
|
||||
-clear_evalarg(evalarg_T *evalarg, exarg_T *eap)
|
||||
-{
|
||||
- if (evalarg != NULL)
|
||||
- {
|
||||
- if (evalarg->eval_tofree != NULL)
|
||||
- {
|
||||
- if (eap != NULL)
|
||||
- {
|
||||
- // We may need to keep the original command line, e.g. for
|
||||
- // ":let" it has the variable names. But we may also need the
|
||||
- // new one, "nextcmd" points into it. Keep both.
|
||||
- vim_free(eap->cmdline_tofree);
|
||||
- eap->cmdline_tofree = *eap->cmdlinep;
|
||||
- *eap->cmdlinep = evalarg->eval_tofree;
|
||||
- }
|
||||
- else
|
||||
- vim_free(evalarg->eval_tofree);
|
||||
- evalarg->eval_tofree = NULL;
|
||||
- }
|
||||
-
|
||||
- ga_clear_strings(&evalarg->eval_tofree_ga);
|
||||
- VIM_CLEAR(evalarg->eval_tofree_lambda);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* The "evaluate" argument: When FALSE, the argument is only parsed but not
|
||||
* executed. The function may return OK, but the rettv will be of type
|
||||
diff --git a/src/proto/eval.pro b/src/proto/eval.pro
|
||||
index e6cd892..27a13c9 100644
|
||||
--- a/src/proto/eval.pro
|
||||
+++ b/src/proto/eval.pro
|
||||
@@ -9,6 +9,8 @@ int eval_expr_valid_arg(typval_T *tv);
|
||||
int eval_expr_typval(typval_T *expr, typval_T *argv, int argc, typval_T *rettv);
|
||||
int eval_expr_to_bool(typval_T *expr, int *error);
|
||||
char_u *eval_to_string_skip(char_u *arg, exarg_T *eap, int skip);
|
||||
+void init_evalarg(evalarg_T *evalarg);
|
||||
+void clear_evalarg(evalarg_T *evalarg, exarg_T *eap);
|
||||
int skip_expr(char_u **pp, evalarg_T *evalarg);
|
||||
int skip_expr_concatenate(char_u **arg, char_u **start, char_u **end, evalarg_T *evalarg);
|
||||
char_u *typval2string(typval_T *tv, int convert);
|
||||
@@ -34,8 +36,6 @@ int pattern_match(char_u *pat, char_u *text, int ic);
|
||||
char_u *eval_next_non_blank(char_u *arg, evalarg_T *evalarg, int *getnext);
|
||||
char_u *eval_next_line(char_u *arg, evalarg_T *evalarg);
|
||||
char_u *skipwhite_and_linebreak(char_u *arg, evalarg_T *evalarg);
|
||||
-void init_evalarg(evalarg_T *evalarg);
|
||||
-void clear_evalarg(evalarg_T *evalarg, exarg_T *eap);
|
||||
int eval0(char_u *arg, typval_T *rettv, exarg_T *eap, evalarg_T *evalarg);
|
||||
int eval0_retarg(char_u *arg, typval_T *rettv, exarg_T *eap, evalarg_T *evalarg, char_u **retarg);
|
||||
int eval1(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
|
||||
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
|
||||
index 75b3e9c..c09c0d2 100644
|
||||
--- a/src/testdir/test_vim9_script.vim
|
||||
+++ b/src/testdir/test_vim9_script.vim
|
||||
@@ -1560,6 +1560,19 @@ def Test_func_redefine_fails()
|
||||
v9.CheckScriptFailure(lines, 'E1073:')
|
||||
enddef
|
||||
|
||||
+def Test_lambda_split()
|
||||
+ # this was using freed memory, because of the split expression
|
||||
+ var lines =<< trim END
|
||||
+ vim9script
|
||||
+ try
|
||||
+ 0
|
||||
+ 0->(0
|
||||
+ ->a.0(
|
||||
+ ->u
|
||||
+ END
|
||||
+ v9.CheckScriptFailure(lines, 'E1050:')
|
||||
+enddef
|
||||
+
|
||||
def Test_fixed_size_list()
|
||||
# will be allocated as one piece of memory, check that changes work
|
||||
var l = [1, 2, 3, 4]
|
||||
diff --git a/src/userfunc.c b/src/userfunc.c
|
||||
index 9b960b7..3777e03 100644
|
||||
--- a/src/userfunc.c
|
||||
+++ b/src/userfunc.c
|
||||
@@ -1371,7 +1371,6 @@ get_lambda_tv(
|
||||
char_u *start, *end;
|
||||
int *old_eval_lavars = eval_lavars_used;
|
||||
int eval_lavars = FALSE;
|
||||
- char_u *tofree1 = NULL;
|
||||
char_u *tofree2 = NULL;
|
||||
int equal_arrow = **arg == '(';
|
||||
int white_error = FALSE;
|
||||
@@ -1456,12 +1455,6 @@ get_lambda_tv(
|
||||
ret = skip_expr_concatenate(arg, &start, &end, evalarg);
|
||||
if (ret == FAIL)
|
||||
goto errret;
|
||||
- if (evalarg != NULL)
|
||||
- {
|
||||
- // avoid that the expression gets freed when another line break follows
|
||||
- tofree1 = evalarg->eval_tofree;
|
||||
- evalarg->eval_tofree = NULL;
|
||||
- }
|
||||
|
||||
if (!equal_arrow)
|
||||
{
|
||||
@@ -1584,10 +1577,6 @@ get_lambda_tv(
|
||||
|
||||
theend:
|
||||
eval_lavars_used = old_eval_lavars;
|
||||
- if (evalarg != NULL && evalarg->eval_tofree == NULL)
|
||||
- evalarg->eval_tofree = tofree1;
|
||||
- else
|
||||
- vim_free(tofree1);
|
||||
vim_free(tofree2);
|
||||
if (types_optional)
|
||||
ga_clear_strings(&argtypes);
|
||||
@@ -1606,10 +1595,6 @@ errret:
|
||||
}
|
||||
vim_free(fp);
|
||||
vim_free(pt);
|
||||
- if (evalarg != NULL && evalarg->eval_tofree == NULL)
|
||||
- evalarg->eval_tofree = tofree1;
|
||||
- else
|
||||
- vim_free(tofree1);
|
||||
vim_free(tofree2);
|
||||
eval_lavars_used = old_eval_lavars;
|
||||
return FAIL;
|
||||
--
|
||||
2.36.1
|
||||
|
||||
56
backport-CVE-2022-2923.patch
Normal file
56
backport-CVE-2022-2923.patch
Normal file
@ -0,0 +1,56 @@
|
||||
From 6669de1b235843968e88844ca6d3c8dec4b01a9e Mon Sep 17 00:00:00 2001
|
||||
From: Bram Moolenaar <Bram@vim.org>
|
||||
Date: Sun, 21 Aug 2022 20:33:47 +0100
|
||||
Subject: [PATCH] patch 9.0.0240: crash when using ":mkspell" with an
|
||||
empty
|
||||
.dic file
|
||||
|
||||
Problem: Crash when using ":mkspell" with an empty .dic file.
|
||||
Solution: Check for an empty word tree.
|
||||
---
|
||||
src/spellfile.c | 4 +++-
|
||||
src/testdir/test_spellfile.vim | 12 ++++++++++++
|
||||
2 files changed, 15 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/spellfile.c b/src/spellfile.c
|
||||
index 4a0de52..a4407fa 100644
|
||||
--- a/src/spellfile.c
|
||||
+++ b/src/spellfile.c
|
||||
@@ -5585,10 +5585,12 @@ sug_filltree(spellinfo_T *spin, slang_T *slang)
|
||||
|
||||
/*
|
||||
* Go through the whole case-folded tree, soundfold each word and put it
|
||||
- * in the trie.
|
||||
+ * in the trie. Bail out if the tree is empty.
|
||||
*/
|
||||
byts = slang->sl_fbyts;
|
||||
idxs = slang->sl_fidxs;
|
||||
+ if (byts == NULL || idxs == NULL)
|
||||
+ return FAIL;
|
||||
|
||||
arridx[0] = 0;
|
||||
curi[0] = 1;
|
||||
diff --git a/src/testdir/test_spellfile.vim b/src/testdir/test_spellfile.vim
|
||||
index 38d1ec0..e81aa65 100644
|
||||
--- a/src/testdir/test_spellfile.vim
|
||||
+++ b/src/testdir/test_spellfile.vim
|
||||
@@ -1160,4 +1160,16 @@ func Test_mkspellmem_opt()
|
||||
call assert_fails('set mkspellmem=1000,50,0', 'E474:')
|
||||
endfunc
|
||||
|
||||
+" this was using a NULL pointer
|
||||
+func Test_mkspell_empty_dic()
|
||||
+ call writefile(['1'], 'XtestEmpty.dic')
|
||||
+ call writefile(['SOFOFROM abcd', 'SOFOTO ABCD', 'SAL CIA X'], 'XtestEmpty.aff')
|
||||
+ mkspell! XtestEmpty.spl XtestEmpty
|
||||
+
|
||||
+ call delete('XtestEmpty.dic')
|
||||
+ call delete('XtestEmpty.aff')
|
||||
+ call delete('XtestEmpty.spl')
|
||||
+endfunc
|
||||
+
|
||||
+
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
--
|
||||
2.36.1
|
||||
|
||||
71
backport-CVE-2022-2946.patch
Normal file
71
backport-CVE-2022-2946.patch
Normal file
@ -0,0 +1,71 @@
|
||||
From adce965162dd89bf29ee0e5baf53652e7515762c Mon Sep 17 00:00:00 2001
|
||||
From: Bram Moolenaar <Bram@vim.org>
|
||||
Date: Mon, 22 Aug 2022 16:35:45 +0100
|
||||
Subject: [PATCH] patch 9.0.0246: using freed memory when 'tagfunc' deletes the
|
||||
buffer
|
||||
|
||||
Problem: Using freed memory when 'tagfunc' deletes the buffer.
|
||||
Solution: Make a copy of the tag name.
|
||||
---
|
||||
src/tag.c | 9 ++++++++-
|
||||
src/testdir/test_tagfunc.vim | 12 ++++++++++++
|
||||
2 files changed, 20 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/tag.c b/src/tag.c
|
||||
index 8a351cc..02f0818 100644
|
||||
--- a/src/tag.c
|
||||
+++ b/src/tag.c
|
||||
@@ -281,6 +281,7 @@ do_tag(
|
||||
char_u *buf_ffname = curbuf->b_ffname; // name to use for
|
||||
// priority computation
|
||||
int use_tfu = 1;
|
||||
+ char_u *tofree = NULL;
|
||||
|
||||
// remember the matches for the last used tag
|
||||
static int num_matches = 0;
|
||||
@@ -630,7 +631,12 @@ do_tag(
|
||||
* When desired match not found yet, try to find it (and others).
|
||||
*/
|
||||
if (use_tagstack)
|
||||
- name = tagstack[tagstackidx].tagname;
|
||||
+ {
|
||||
+ // make a copy, the tagstack may change in 'tagfunc'
|
||||
+ name = vim_strsave(tagstack[tagstackidx].tagname);
|
||||
+ vim_free(tofree);
|
||||
+ tofree = name;
|
||||
+ }
|
||||
#if defined(FEAT_QUICKFIX)
|
||||
else if (g_do_tagpreview != 0)
|
||||
name = ptag_entry.tagname;
|
||||
@@ -922,6 +928,7 @@ end_do_tag:
|
||||
g_do_tagpreview = 0; // don't do tag preview next time
|
||||
# endif
|
||||
|
||||
+ vim_free(tofree);
|
||||
#ifdef FEAT_CSCOPE
|
||||
return jumped_to_tag;
|
||||
#else
|
||||
diff --git a/src/testdir/test_tagfunc.vim b/src/testdir/test_tagfunc.vim
|
||||
index 05d8473..9582612 100644
|
||||
--- a/src/testdir/test_tagfunc.vim
|
||||
+++ b/src/testdir/test_tagfunc.vim
|
||||
@@ -389,4 +389,16 @@ func Test_tagfunc_callback()
|
||||
%bw!
|
||||
endfunc
|
||||
|
||||
+func Test_tagfunc_wipes_buffer()
|
||||
+ func g:Tag0unc0(t,f,o)
|
||||
+ bwipe
|
||||
+ endfunc
|
||||
+ set tagfunc=g:Tag0unc0
|
||||
+ new
|
||||
+ cal assert_fails('tag 0', 'E987:')
|
||||
+
|
||||
+ delfunc g:Tag0unc0
|
||||
+ set tagfunc=
|
||||
+endfunc
|
||||
+
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
11
vim.spec
11
vim.spec
@ -12,7 +12,7 @@
|
||||
Name: vim
|
||||
Epoch: 2
|
||||
Version: 9.0
|
||||
Release: 6
|
||||
Release: 7
|
||||
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
|
||||
@ -53,6 +53,9 @@ Patch6022: backport-CVE-2022-2845.patch
|
||||
Patch6023: backport-CVE-2022-2849.patch
|
||||
Patch6024: backport-CVE-2022-2862.patch
|
||||
Patch6025: backport-CVE-2022-2874.patch
|
||||
Patch6026: backport-CVE-2022-2889.patch
|
||||
Patch6027: backport-CVE-2022-2923.patch
|
||||
Patch6028: backport-CVE-2022-2946.patch
|
||||
|
||||
Patch9000: bugfix-rm-modify-info-version.patch
|
||||
|
||||
@ -446,6 +449,12 @@ popd
|
||||
%{_mandir}/man1/evim.*
|
||||
|
||||
%changelog
|
||||
* Sat Aug 20 2022 shixuantong <shixuantong@h-partners.com> - 2:9.0-7
|
||||
- Type:CVE
|
||||
- ID:CVE-2022-2889 CVE-2022-2923 CVE-2022-2946
|
||||
- SUG:NA
|
||||
- DESC:fix CVE-2022-2889 CVE-2022-2923 CVE-2022-2946
|
||||
|
||||
* Thu Aug 18 2022 shixuantong <shixuantong@h-partners.com> - 2:9.0-6
|
||||
- Type:CVE
|
||||
- ID:CVE-2022-2816 CVE-2022-2817 CVE-2022-2819 CVE-2022-2845 CVE-2022-2849 CVE-2022-2862 CVE-2022-2874
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user