From f7219fd7ccc27c5d1161b6e509ee88aa8613dcf8 Mon Sep 17 00:00:00 2001 From: qz_cx Date: Mon, 5 Dec 2022 15:18:10 +0800 Subject: [PATCH] fix:CVE-2022-3491 --- backport-CVE-2022-3491.patch | 284 +++++++++++++++++++++++++++++++++++ vim.spec | 9 +- 2 files changed, 292 insertions(+), 1 deletion(-) create mode 100644 backport-CVE-2022-3491.patch diff --git a/backport-CVE-2022-3491.patch b/backport-CVE-2022-3491.patch new file mode 100644 index 0000000..bc4eb76 --- /dev/null +++ b/backport-CVE-2022-3491.patch @@ -0,0 +1,284 @@ +From 730b78b09f3f39320d18ce105e1e82cd1f045b53 Mon Sep 17 00:00:00 2001 +From: qz_cx +Date: Mon, 5 Dec 2022 15:06:32 +0800 +Subject: [PATCH] patch 9.0.0742: reading past end of the line when compiling a + function + +Problem: Reading past end of the line when compiling a function with + errors. +Solution: Do not return an invalid pointer. Fix skipping redirection. +brammool committed on Oct 13 +--- + src/testdir/test_vim9_func.vim | 27 ++++++++++++++ + src/testdir/test_vim9_script.vim | 53 ++++++++++++++++++++++++++- + src/version.c | 2 ++ + src/vim9cmds.c | 62 ++++++++++++++++++-------------- + src/vim9compile.c | 25 ++++++++++--- + 5 files changed, 137 insertions(+), 32 deletions(-) + +diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim +index 426fde4..6300f3f 100644 +--- a/src/testdir/test_vim9_func.vim ++++ b/src/testdir/test_vim9_func.vim +@@ -4217,6 +4217,33 @@ def Test_multiple_funcref() + v9.CheckScriptSuccess(lines) + enddef + ++def Test_invalid_redir() ++ var lines =<< trim END ++ def Tone() ++ if 1 ++ redi =>@0 ++ redi END ++ endif ++ enddef ++ defcompile ++ END ++ v9.CheckScriptFailure(lines, 'E354:') ++ delfunc g:Tone ++ ++ # this was reading past the end of the line ++ lines =<< trim END ++ def Ttwo() ++ if 0 ++ redi =>@0 ++ redi END ++ endif ++ enddef ++ defcompile ++ END ++ v9.CheckScriptFailure(lines, 'E354:') ++ delfunc g:Ttwo ++enddef ++ + " The following messes up syntax highlight, keep near the end. + if has('python3') + def Test_python3_command() +diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim +index c09c0d2..f2c9842 100644 +--- a/src/testdir/test_vim9_script.vim ++++ b/src/testdir/test_vim9_script.vim +@@ -2112,7 +2112,7 @@ enddef + + def Test_skipped_redir() + var lines =<< trim END +- def T() ++ def Tredir() + if 0 + redir =>l[0] + redir END +@@ -2121,6 +2121,57 @@ def Test_skipped_redir() + defcompile + END + v9.CheckScriptSuccess(lines) ++ delfunc g:Tredir ++ ++ lines =<< trim END ++ def Tredir() ++ if 0 ++ redir => l[0] ++ endif ++ echo 'executed' ++ if 0 ++ redir END ++ endif ++ enddef ++ defcompile ++ END ++ v9.CheckScriptSuccess(lines) ++ delfunc g:Tredir ++ ++ lines =<< trim END ++ def Tredir() ++ var l = [''] ++ if 1 ++ redir => l[0] ++ endif ++ echo 'executed' ++ if 0 ++ redir END ++ else ++ redir END ++ endif ++ enddef ++ defcompile ++ END ++ v9.CheckScriptSuccess(lines) ++ delfunc g:Tredir ++ ++ lines =<< trim END ++ let doit = 1 ++ def Tredir() ++ var l = [''] ++ if g:doit ++ redir => l[0] ++ endif ++ echo 'executed' ++ if g:doit ++ redir END ++ endif ++ enddef ++ defcompile ++ END ++ v9.CheckScriptSuccess(lines) ++ delfunc g:Tredir + enddef + + def Test_for_loop() +diff --git a/src/version.c b/src/version.c +index 5e21279..bd4ac87 100644 +--- a/src/version.c ++++ b/src/version.c +@@ -735,6 +735,8 @@ static char *(features[]) = + + static int included_patches[] = + { /* Add new patch number below this line */ ++/**/ ++ 742, + /**/ + 0 + }; +diff --git a/src/vim9cmds.c b/src/vim9cmds.c +index 93032d6..4329ed1 100644 +--- a/src/vim9cmds.c ++++ b/src/vim9cmds.c +@@ -2123,34 +2123,37 @@ compile_redir(char_u *line, exarg_T *eap, cctx_T *cctx) + { + if (STRNCMP(arg, "END", 3) == 0) + { +- if (lhs->lhs_append) ++ if (cctx->ctx_skip != SKIP_YES) + { +- // First load the current variable value. +- if (compile_load_lhs_with_index(lhs, lhs->lhs_whole, ++ if (lhs->lhs_append) ++ { ++ // First load the current variable value. ++ if (compile_load_lhs_with_index(lhs, lhs->lhs_whole, + cctx) == FAIL) +- return NULL; +- } ++ return NULL; ++ } + +- // Gets the redirected text and put it on the stack, then store it +- // in the variable. +- generate_instr_type(cctx, ISN_REDIREND, &t_string); ++ // Gets the redirected text and put it on the stack, then store ++ // it in the variable. ++ generate_instr_type(cctx, ISN_REDIREND, &t_string); + +- if (lhs->lhs_append) +- generate_CONCAT(cctx, 2); ++ if (lhs->lhs_append) ++ generate_CONCAT(cctx, 2); + +- if (lhs->lhs_has_index) +- { +- // Use the info in "lhs" to store the value at the index in the +- // list or dict. +- if (compile_assign_unlet(lhs->lhs_whole, lhs, TRUE, ++ if (lhs->lhs_has_index) ++ { ++ // Use the info in "lhs" to store the value at the index in ++ // the list or dict. ++ if (compile_assign_unlet(lhs->lhs_whole, lhs, TRUE, + &t_string, cctx) == FAIL) ++ return NULL; ++ } ++ else if (generate_store_lhs(cctx, lhs, -1, FALSE) == FAIL) + return NULL; +- } +- else if (generate_store_lhs(cctx, lhs, -1, FALSE) == FAIL) +- return NULL; + +- VIM_CLEAR(lhs->lhs_name); +- VIM_CLEAR(lhs->lhs_whole); ++ VIM_CLEAR(lhs->lhs_name); ++ VIM_CLEAR(lhs->lhs_whole); ++ } + return arg + 3; + } + emsg(_(e_cannot_nest_redir)); +@@ -2176,13 +2179,20 @@ compile_redir(char_u *line, exarg_T *eap, cctx_T *cctx) + if (need_type(&t_string, lhs->lhs_member_type, + -1, 0, cctx, FALSE, FALSE) == FAIL) + return NULL; +- generate_instr(cctx, ISN_REDIRSTART); +- lhs->lhs_append = append; +- if (lhs->lhs_has_index) ++ if (cctx->ctx_skip == SKIP_YES) + { +- lhs->lhs_whole = vim_strnsave(arg, lhs->lhs_varlen_total); +- if (lhs->lhs_whole == NULL) +- return NULL; ++ VIM_CLEAR(lhs->lhs_name); ++ } ++ else ++ { ++ generate_instr(cctx, ISN_REDIRSTART); ++ lhs->lhs_append = append; ++ if (lhs->lhs_has_index) ++ { ++ lhs->lhs_whole = vim_strnsave(arg, lhs->lhs_varlen_total); ++ if (lhs->lhs_whole == NULL) ++ return NULL; ++ } + } + + return arg + lhs->lhs_varlen_total; +diff --git a/src/vim9compile.c b/src/vim9compile.c +index a8fa5dc..ab043d7 100644 +--- a/src/vim9compile.c ++++ b/src/vim9compile.c +@@ -1217,6 +1217,21 @@ vim9_declare_error(char_u *name) + semsg(_(e_cannot_declare_a_scope_variable), scope, name); + } + ++ ++/* ++ * Return TRUE if "name" is a valid register to use. ++ * Return FALSE and give an error message if not. ++ */ ++ static int ++valid_dest_reg(int name) ++{ ++ if ((name == '@' || valid_yank_reg(name, FALSE)) && name != '.') ++ return TRUE; ++ emsg_invreg(name); ++ return FAIL; ++} ++ ++ + /* + * For one assignment figure out the type of destination. Return it in "dest". + * When not recognized "dest" is not set. +@@ -1298,12 +1313,8 @@ get_var_dest( + } + else if (*name == '@') + { +- if (name[1] != '@' +- && (!valid_yank_reg(name[1], FALSE) || name[1] == '.')) +- { +- emsg_invreg(name[1]); ++ if (!valid_dest_reg(name[1])) + return FAIL; +- } + *dest = dest_reg; + *type = name[1] == '#' ? &t_number_or_string : &t_string; + } +@@ -1379,7 +1390,11 @@ compile_lhs( + // "var_end" is the end of the variable/option/etc. name. + lhs->lhs_dest_end = skip_var_one(var_start, FALSE); + if (*var_start == '@') ++ { ++ if (!valid_dest_reg(var_start[1])) ++ return FAIL; + var_end = var_start + 2; ++ } + else + { + // skip over the leading "&", "&l:", "&g:" and "$" +-- +2.33.0 + diff --git a/vim.spec b/vim.spec index f5abbfb..de23141 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 @@ -75,6 +75,7 @@ Patch6044: backport-9.0.0581-adding-a-character-for-incsearch-fails-at-end- Patch6045: backport-CVE-2022-3324.patch Patch6046: backport-CVE-2022-3705.patch Patch6047: backport-CVE-2022-4141.patch +Patch6048: backport-CVE-2022-3491.patch Patch9000: bugfix-rm-modify-info-version.patch @@ -474,6 +475,12 @@ LC_ALL=en_US.UTF-8 make -j1 test %{_mandir}/man1/evim.* %changelog +* Mon Dec 05 2022 qz_cx - 2:9.0-22 +- Type:CVE +- ID:NA +- SUG:NA +- DESC: fix CVE-2022-3491 + * Tue Nov 29 2022 wangjiang - 2:9.0-21 - Type:CVE - ID:CVE-2022-4141 -- Gitee