diff --git a/0001-patch-9.2.0735-security-arbitrary-Ex-command-executi.patch b/0001-patch-9.2.0735-security-arbitrary-Ex-command-executi.patch new file mode 100644 index 00000000..2b188e47 --- /dev/null +++ b/0001-patch-9.2.0735-security-arbitrary-Ex-command-executi.patch @@ -0,0 +1,116 @@ +From 3670c2d9794931e2c3f01dcc2b26165f31306b90 Mon Sep 17 00:00:00 2001 +From: RHEL Packaging Agent +Date: Tue, 14 Jul 2026 08:48:36 +0000 +Subject: [PATCH] patch 9.2.0735: [security]: arbitrary Ex command execution + during C omni-completion + +Problem: [security]: With C omni-completion, a crafted tags file can execute + arbitrary Ex commands when completing a struct/union member + (cipher-creator) +Solution: Escape the type field before inserting it into the :vimgrep + pattern so it cannot close the pattern and start a new command + (Hirohito Higashi). + +Adapted for vim 8.0: the ccomplete.vim in 8.0 uses legacy Vim script syntax +(exe with dot concatenation) instead of vim9script (execute with .. operator). +The same escape() call is applied to the typename variable. +Stripped src/version.c hunk as per downstream policy. +--- + runtime/autoload/ccomplete.vim | 2 +- + src/testdir/Make_all.mak | 1 + + src/testdir/test_plugin_ccomplete.vim | 62 +++++++++++++++++++++++++++ + 3 files changed, 64 insertions(+), 1 deletion(-) + create mode 100644 src/testdir/test_plugin_ccomplete.vim + +diff --git a/runtime/autoload/ccomplete.vim b/runtime/autoload/ccomplete.vim +index d5bfa07..cdbb1ca 100644 +--- a/runtime/autoload/ccomplete.vim ++++ b/runtime/autoload/ccomplete.vim +@@ -500,7 +500,7 @@ function! s:StructMembers(typename, items, all) + endif + if !cached + while 1 +- exe 'silent! keepj noautocmd ' . n . 'vimgrep /\t' . typename . '\(\t\|$\)/j ' . fnames ++ exe 'silent! keepj noautocmd ' . n . 'vimgrep /\t' . escape(typename, '/\') . '\(\t\|$\)/j ' . fnames + + let qflist = getqflist() + if len(qflist) > 0 || match(typename, "::") < 0 +diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak +index ed348a4..xxxxxxx 100644 +--- a/src/testdir/Make_all.mak ++++ b/src/testdir/Make_all.mak +@@ -146,5 +146,6 @@ NEW_TESTS = test_arabic.res \ + test_paste.res \ + test_perl.res \ ++ test_plugin_ccomplete.res \ + test_plugin_netrw.res \ + test_plugin_python3complete.res \ + test_plus_arg_edit.res \ +diff --git a/src/testdir/test_plugin_ccomplete.vim b/src/testdir/test_plugin_ccomplete.vim +new file mode 100644 +index 0000000..a635bd5 +--- /dev/null ++++ b/src/testdir/test_plugin_ccomplete.vim +@@ -0,0 +1,62 @@ ++" Tests for the C omni-completion plugin (runtime/autoload/ccomplete.vim). ++ ++func s:WriteTags(lines) ++ " Mark unsorted so lookup is a linear scan regardless of entry order. ++ let tagsfile = tempname() ++ call writefile(["!_TAG_FILE_SORTED\t0\t/0/"] + a:lines, tagsfile) ++ return tagsfile ++endfunc ++ ++" A crafted typeref field is interpolated into the :vimgrep pattern in ++" StructMembers(). Without escaping, "/" closes the pattern and "|" starts a ++" new Ex command, so the field runs as an Ex command during completion. ++func Test_ccomplete_no_exec_via_typeref() ++ unlet! g:ccomplete_injected ++ let tagsfile = s:WriteTags([ ++ \ "myvar\tmain.c\t/^x$/;\"\tv\ttyperef:x/|let g:ccomplete_injected = 1|\"", ++ \ ]) ++ ++ let save_tags = &tags ++ let &tags = tagsfile ++ ++ new ++ call ccomplete#Complete(1, '') ++ call ccomplete#Complete(0, 'myvar.x') ++ ++ call assert_false(exists('g:ccomplete_injected'), ++ \ 'typeref field was executed as an Ex command during omni-completion') ++ ++ bwipe! ++ let &tags = save_tags ++ unlet! g:ccomplete_injected ++endfunc ++ ++" A legitimate typeref must still drive struct-member completion: escaping the ++" field value must not break the normal path. ++func Test_ccomplete_typeref_completion_still_works() ++ let tagsfile = s:WriteTags([ ++ \ "myvar\tmain.c\t/^x$/;\"\tv\ttyperef:struct:mystruct", ++ \ "alpha\tmain.c\t/^x$/;\"\tm\tstruct:mystruct", ++ \ "beta\tmain.c\t/^x$/;\"\tm\tstruct:mystruct", ++ \ ]) ++ ++ let save_tags = &tags ++ let &tags = tagsfile ++ ++ new ++ call ccomplete#Complete(1, '') ++ let items = ccomplete#Complete(0, 'myvar.') ++ ++ call assert_equal(type([]), type(items), ++ \ 'ccomplete#Complete did not return a list') ++ let names = map(copy(items), 'v:val.word') ++ call assert_true(index(names, 'alpha') >= 0, ++ \ 'struct member "alpha" missing from completion: ' . string(names)) ++ call assert_true(index(names, 'beta') >= 0, ++ \ 'struct member "beta" missing from completion: ' . string(names)) ++ ++ bwipe! ++ let &tags = save_tags ++endfunc ++ ++" vim: shiftwidth=2 sts=2 expandtab diff --git a/vim.spec b/vim.spec index 9e68b5f3..f3d1880f 100644 --- a/vim.spec +++ b/vim.spec @@ -24,7 +24,7 @@ Summary: The VIM editor URL: http://www.vim.org/ Name: vim Version: %{baseversion}.%{patchlevel} -Release: 30%{?dist} +Release: 31%{?dist} License: Vim and MIT Source0: ftp://ftp.vim.org/pub/vim/unix/vim-%{baseversion}-%{patchlevel}.tar.bz2 Source1: vim.sh @@ -210,6 +210,11 @@ Patch3065: 0001-patch-9.2.0698-security-Out-of-bounds-write-with-sou.patch # literals with system printf, used mkdir 'p' with manual cleanup instead # of 'pR', added test to Make_all.mak) Patch3066: 0001-patch-9.2.0653-security-out-of-bounds-write-in-tree_.patch +# RHEL-203873 CVE-2026-59858 arbitrary Ex command execution during C omni-completion +# https://redhat.atlassian.net/browse/RHEL-203873 +# https://github.com/vim/vim/commit/6b611b0d15603c52ebdad17172b0232b4f65704e +# stripped src/version.c hunk, adapted ccomplete.vim fix for vim 8.0 legacy script syntax +Patch3067: 0001-patch-9.2.0735-security-arbitrary-Ex-command-executi.patch # gcc is no longer in buildroot by default @@ -458,6 +463,7 @@ perl -pi -e "s,bin/nawk,bin/awk,g" runtime/tools/mve.awk %patch -P 3064 -p1 -b .CVE-2026-57456 %patch -P 3065 -p1 -b .CVE-2026-57455 %patch -P 3066 -p1 -b .CVE-2026-55693 +%patch -P 3067 -p1 -b .CVE-2026-59858 %build @@ -977,6 +983,10 @@ touch %{buildroot}/%{_datadir}/%{name}/vimfiles/doc/tags %{_datadir}/icons/locolor/*/apps/* %changelog +* Tue Jul 14 2026 RHEL Packaging Agent - 2:8.0.1763-31 +- RHEL-203873 CVE-2026-59858 vim: arbitrary Ex command execution in + C omni-completion + * Mon Jul 13 2026 RHEL Packaging Agent - 2:8.0.1763-30 - RHEL-194055 CVE-2026-55693 vim: out-of-bounds write in tree_count_words()