diff --git a/0001-patch-8.2.4253-using-freed-memory-when-substitute-wi.patch b/0001-patch-8.2.4253-using-freed-memory-when-substitute-wi.patch new file mode 100644 index 0000000..bb58404 --- /dev/null +++ b/0001-patch-8.2.4253-using-freed-memory-when-substitute-wi.patch @@ -0,0 +1,69 @@ +diff -up vim82/src/ex_cmds.c.cve0413 vim82/src/ex_cmds.c +--- vim82/src/ex_cmds.c.cve0413 2022-02-10 08:09:27.644493218 +0100 ++++ vim82/src/ex_cmds.c 2022-02-10 08:09:27.653493168 +0100 +@@ -3627,6 +3627,7 @@ ex_substitute(exarg_T *eap) + int save_do_all; // remember user specified 'g' flag + int save_do_ask; // remember user specified 'c' flag + char_u *pat = NULL, *sub = NULL; // init for GCC ++ char_u *sub_copy = NULL; + int delimiter; + int sublen; + int got_quit = FALSE; +@@ -3928,11 +3929,20 @@ ex_substitute(exarg_T *eap) + sub_firstline = NULL; + + /* +- * ~ in the substitute pattern is replaced with the old pattern. +- * We do it here once to avoid it to be replaced over and over again. +- * But don't do it when it starts with "\=", then it's an expression. ++ * If the substitute pattern starts with "\=" then it's an expression. ++ * Make a copy, a recursive function may free it. ++ * Otherwise, '~' in the substitute pattern is replaced with the old ++ * pattern. We do it here once to avoid it to be replaced over and over ++ * again. + */ +- if (!(sub[0] == '\\' && sub[1] == '=')) ++ if (sub[0] == '\\' && sub[1] == '=') ++ { ++ sub = vim_strsave(sub); ++ if (sub == NULL) ++ return; ++ sub_copy = sub; ++ } ++ else + sub = regtilde(sub, magic_isset()); + + /* +@@ -4737,6 +4747,7 @@ outofmem: + #endif + + vim_regfree(regmatch.regprog); ++ vim_free(sub_copy); + + // Restore the flag values, they can be used for ":&&". + subflags.do_all = save_do_all; +diff -up vim82/src/testdir/test_substitute.vim.cve0413 vim82/src/testdir/test_substitute.vim +--- vim82/src/testdir/test_substitute.vim.cve0413 2022-02-10 08:09:27.654493162 +0100 ++++ vim82/src/testdir/test_substitute.vim 2022-02-10 08:10:14.392230843 +0100 +@@ -926,4 +926,21 @@ func Test_substitute_multiline_submatch( + close! + endfunc + ++" This was using "old_sub" after it was freed. ++func Test_using_old_sub() ++ set compatible maxfuncdepth=10 ++ new ++ call setline(1, 'some text.') ++ func Repl() ++ ~ ++ s/ ++ endfunc ++ silent! s/\%')/\=Repl() ++ ++ delfunc Repl ++ bwipe! ++ set nocompatible ++endfunc ++ ++ + " vim: shiftwidth=2 sts=2 expandtab diff --git a/vim.spec b/vim.spec index 0b86ee4..b6a6dd3 100644 --- a/vim.spec +++ b/vim.spec @@ -104,6 +104,8 @@ Patch3035: 0001-patch-8.2.4217-illegal-memory-access-when-undo-makes.patch Patch3036: 0001-patch-8.2.4245-retab-0-may-cause-illegal-memory-acce.patch # CVE-2022-0408 vim: Stack-based Buffer Overflow in spellsuggest.c Patch3037: 0001-patch-8.2.4247-stack-corruption-when-looking-for-spe.patch +# CVE-2022-0413 vim: use after free in src/ex_cmds.c +Patch3038: 0001-patch-8.2.4253-using-freed-memory-when-substitute-wi.patch # gcc is no longer in buildroot by default BuildRequires: gcc @@ -328,6 +330,7 @@ perl -pi -e "s,bin/nawk,bin/awk,g" runtime/tools/mve.awk %patch3035 -p1 -b .cve0368 %patch3036 -p1 -b .cve0417 %patch3037 -p1 -b .cve0408 +%patch3038 -p1 -b .cve0413 %build cd src @@ -885,6 +888,9 @@ touch %{buildroot}/%{_datadir}/%{name}/vimfiles/doc/tags %endif %changelog +* Thu Feb 10 2022 Zdenek Dohnal - 2:8.2.2637-12 +- CVE-2022-0413 vim: use after free in src/ex_cmds.c + * Wed Feb 09 2022 Zdenek Dohnal - 2:8.2.2637-12 - CVE-2022-0368 vim: Out-of-bounds Read in vim - CVE-2022-0417 vim: heap-based-buffer-overflow in ex_retab() of src/indent.c