import CS git vim-8.0.1763-31.el8_10

This commit is contained in:
AlmaLinux RelEng Bot 2026-07-30 08:08:52 -04:00
parent 01a7da4d65
commit c145c452cb
5 changed files with 460 additions and 1 deletions

View File

@ -0,0 +1,77 @@
From 8afb664612a7bd2fc7203cb87658bbbcc3ce29b1 Mon Sep 17 00:00:00 2001
From: RHEL Packaging Agent <redhat-ymir-agent@redhat.com>
Date: Mon, 13 Jul 2026 08:37:21 +0000
Subject: [PATCH] patch 9.2.0653: [security]: out-of-bounds write in
tree_count_words()
Problem: [security]: a crafted spell file can drive tree_count_words()
past the end of its MAXWLEN-sized depth arrays; the descent
loop has no depth bound.
Solution: only descend while depth < MAXWLEN - 1, as the sibling trie
walkers already do; apply the same guard to sug_filltree().
Github Security Advisory:
https://github.com/vim/vim/security/advisories/GHSA-wgh4-64f7-q3jq
Signed-off-by: Christian Brabandt <cb@256bit.org>
---
src/spellfile.c | 4 ++--
src/testdir/test_spellfile.vim | 28 ++++++++++++++++++++++++++++
2 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/src/spellfile.c b/src/spellfile.c
index 92997ef..50a9c6a 100644
--- a/src/spellfile.c
+++ b/src/spellfile.c
@@ -639,7 +639,7 @@ tree_count_words(char_u *byts, idx_T *idxs)
++curi[depth];
}
}
- else
+ else if (depth < MAXWLEN - 1)
{
/* Normal char, go one level deeper to count the words. */
++depth;
@@ -5687,7 +5687,7 @@ sug_filltree(spellinfo_T *spin, slang_T *slang)
++curi[depth];
}
}
- else
+ else if (depth < MAXWLEN - 1)
{
/* Normal char, go one level deeper. */
tword[depth++] = c;
diff --git a/src/testdir/test_spellfile.vim b/src/testdir/test_spellfile.vim
index 26235fe..d9f77d9 100644
--- a/src/testdir/test_spellfile.vim
+++ b/src/testdir/test_spellfile.vim
@@ -23,4 +23,29 @@ func Test_soundfold_overflow()
call delete('Xtest.latin1.sug')
endfunc
+func Test_spell_sug_tree_count_words_overflow()
+ " A crafted .spl/.sug pair with a BY_INDEX self-cycle in the fold word tree
+ " parses cleanly (shared refs aren't recursed, so read_tree_node()'s depth
+ " cap never trips), but drove tree_count_words() past its MAXWLEN-sized depth
+ " arrays -> stack out-of-bounds write. The walk only happens when
+ " spellsuggest() loads the matching .sug. Reaching the assert == no OOB.
+ call mkdir('Xrtp/spell', 'p')
+ " VIMspell + v50, SN_SUGFILE(ts), SN_END, LWORDTREE{node:1,BY_INDEX->0,'A'},
+ " empty KWORDTREE/PREFIXTREE
+ call system('printf ''\x56\x49\x4D\x73\x70\x65\x6C\x6C\x32\x0B\x00\x00\x00\x00\x08\x00\x00\x00\x00\x12\x34\x56\x78\xFF\x00\x00\x00\x02\x01\x01\x00\x00\x00\x41\x00\x00\x00\x00\x00\x00\x00\x00'' > Xrtp/spell/xx.utf-8.spl')
+ " VIMsug + v1, matching ts, SUGWORDTREE word "a", empty SUGTABLE
+ call system('printf ''\x56\x49\x4D\x73\x75\x67\x01\x00\x00\x00\x00\x12\x34\x56\x78\x00\x00\x00\x04\x01\x61\x01\x00\x00\x00\x00\x00'' > Xrtp/spell/xx.utf-8.sug')
+
+ new
+ set runtimepath+=./Xrtp
+ set spelllang=xx
+ set spell
+ " Unpatched: OOB write here (ASan abort, or crash). Patched: returns a list.
+ call assert_equal(v:t_list, type(spellsuggest('helloo')))
+
+ set spell& spelllang& runtimepath&
+ bwipe!
+ call delete('Xrtp', 'rf')
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab

View File

@ -0,0 +1,81 @@
From 11c60c9ae5466580e93defdff683bcd4b93c5283 Mon Sep 17 00:00:00 2001
From: RHEL Packaging Agent <redhat-ymir-agent@redhat.com>
Date: Thu, 2 Jul 2026 11:09:19 +0000
Subject: [PATCH] patch 9.2.0698: [security]: Out-of-bounds write with
soundfold()
Problem: [security]: Out-of-bounds write with soundfold()
(cipher-creator)
Solution: Add an abort condition to the for loop to validate the buffer
size.
Github Security Advisory:
https://github.com/vim/vim/security/advisories/GHSA-q8mh-6qm3-25g4
Supported by AI
Signed-off-by: Christian Brabandt <cb@256bit.org>
---
src/spell.c | 2 +-
src/testdir/Make_all.mak | 1 +
src/testdir/test_spellfile.vim | 26 ++++++++++++++++++++++++++
3 files changed, 28 insertions(+), 1 deletion(-)
create mode 100644 src/testdir/test_spellfile.vim
diff --git a/src/spell.c b/src/spell.c
index 05a9d2c..54f935b 100644
--- a/src/spell.c
+++ b/src/spell.c
@@ -7107,7 +7107,7 @@ spell_soundfold_sofo(slang_T *slang, char_u *inword, char_u *res)
#endif
{
/* The sl_sal_first[] table contains the translation. */
- for (s = inword; (c = *s) != NUL; ++s)
+ for (s = inword; (c = *s) != NUL && ri < MAXWLEN - 1; ++s)
{
if (VIM_ISWHITE(c))
c = ' ';
diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak
index 4b34928..c7b5893 100644
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -166,6 +166,7 @@ NEW_TESTS = test_arabic.res \
test_signs.res \
test_smartindent.res \
test_spell.res \
+ test_spellfile.res \
test_startup.res \
test_stat.res \
test_substitute.res \
diff --git a/src/testdir/test_spellfile.vim b/src/testdir/test_spellfile.vim
new file mode 100644
index 0000000..26235fe
--- /dev/null
+++ b/src/testdir/test_spellfile.vim
@@ -0,0 +1,26 @@
+" Tests for spellfile langauage generation and stripping
+
+" A word longer than MAXWLEN must not overflow the soundfold result buffer in
+" the single-byte SOFO branch of spell_soundfold_sofo().
+func Test_soundfold_overflow()
+ let _enc=&enc
+ set enc=latin1
+ call writefile(['SOFOFROM ab', 'SOFOTO xy'], 'Xtest.aff')
+ call writefile(['1', 'foo'], 'Xtest.dic')
+ mkspell! Xtest Xtest
+ setl spelllang=Xtest.latin1.spl spell
+
+ " Before the fix the copy loop wrote one byte per input byte into a
+ " MAXWLEN (254) stack buffer with no upper bound, smashing the stack.
+ let sound = soundfold(repeat('ab', 300))
+ call assert_true(strlen(sound) < 254, 'soundfold result exceeds MAXWLEN')
+
+ set spell& spelllang&
+ let &enc = _enc
+ call delete('Xtest.aff')
+ call delete('Xtest.dic')
+ call delete('Xtest.latin1.spl')
+ call delete('Xtest.latin1.sug')
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab

View File

@ -0,0 +1,144 @@
From 578cdd1cd87dcf24959b2031f046932fdfcbe8ab Mon Sep 17 00:00:00 2001
From: Christian Brabandt <cb@256bit.org>
Date: Sun, 21 Jun 2026 19:50:56 +0000
Subject: [PATCH] patch 9.2.0699: [security]: possible code execution with
python complete
Problem: [security]: possible code execution with python complete
(morningbread)
Solution: Use repr() to quote the doc strings correctly
Github Security Advisory:
https://github.com/vim/vim/security/advisories/GHSA-ppj8-wqjf-6fp3
Supported by AI
Signed-off-by: Christian Brabandt <cb@256bit.org>
---
runtime/autoload/python3complete.vim | 6 ++--
runtime/autoload/pythoncomplete.vim | 6 ++--
src/testdir/Make_all.mak | 1 +
src/testdir/test_plugin_python3complete.vim | 40 +++++++++++++++++++++
4 files changed, 47 insertions(+), 6 deletions(-)
create mode 100644 src/testdir/test_plugin_python3complete.vim
diff --git a/runtime/autoload/python3complete.vim b/runtime/autoload/python3complete.vim
index cd8786d..86fd678 100644
--- a/runtime/autoload/python3complete.vim
+++ b/runtime/autoload/python3complete.vim
@@ -307,7 +307,7 @@ class Scope(object):
def get_code(self):
str = ""
- if len(self.docstr) > 0: str += '"""'+self.docstr+'"""\n'
+ if len(self.docstr) > 0: str += repr(self.docstr)+'\n'
str += 'class _PyCmplNoType:\n def __getattr__(self,name):\n return None\n'
for sub in self.subscopes:
str += sub.get_code()
@@ -344,7 +344,7 @@ class Class(Scope):
str = '%sclass %s' % (self.currentindent(),self.name)
if len(self.supers) > 0: str += '(%s)' % ','.join(self.supers)
str += ':\n'
- if len(self.docstr) > 0: str += self.childindent()+'"""'+self.docstr+'"""\n'
+ if len(self.docstr) > 0: str += self.childindent()+repr(self.docstr)+'\n'
if len(self.subscopes) > 0:
for s in self.subscopes: str += s.get_code()
else:
@@ -361,7 +361,7 @@ class Function(Scope):
def get_code(self):
str = "%sdef %s(%s):\n" % \
(self.currentindent(),self.name,','.join(self.params))
- if len(self.docstr) > 0: str += self.childindent()+'"""'+self.docstr+'"""\n'
+ if len(self.docstr) > 0: str += self.childindent()+repr(self.docstr)+'\n'
str += "%spass\n" % self.childindent()
return str
diff --git a/runtime/autoload/pythoncomplete.vim b/runtime/autoload/pythoncomplete.vim
index a4dc18c..ea0499b 100644
--- a/runtime/autoload/pythoncomplete.vim
+++ b/runtime/autoload/pythoncomplete.vim
@@ -325,7 +325,7 @@ class Scope(object):
def get_code(self):
str = ""
- if len(self.docstr) > 0: str += '"""'+self.docstr+'"""\n'
+ if len(self.docstr) > 0: str += repr(self.docstr)+'\n'
str += 'class _PyCmplNoType:\n def __getattr__(self,name):\n return None\n'
for sub in self.subscopes:
str += sub.get_code()
@@ -362,7 +362,7 @@ class Class(Scope):
str = '%sclass %s' % (self.currentindent(),self.name)
if len(self.supers) > 0: str += '(%s)' % ','.join(self.supers)
str += ':\n'
- if len(self.docstr) > 0: str += self.childindent()+'"""'+self.docstr+'"""\n'
+ if len(self.docstr) > 0: str += self.childindent()+repr(self.docstr)+'\n'
if len(self.subscopes) > 0:
for s in self.subscopes: str += s.get_code()
else:
@@ -379,7 +379,7 @@ class Function(Scope):
def get_code(self):
str = "%sdef %s(%s):\n" % \
(self.currentindent(),self.name,','.join(self.params))
- if len(self.docstr) > 0: str += self.childindent()+'"""'+self.docstr+'"""\n'
+ if len(self.docstr) > 0: str += self.childindent()+repr(self.docstr)+'\n'
str += "%spass\n" % self.childindent()
return str
diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak
index 4b34928..ed348a4 100644
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -146,6 +146,7 @@ NEW_TESTS = test_arabic.res \
test_paste.res \
test_perl.res \
test_plugin_netrw.res \
+ test_plugin_python3complete.res \
test_plus_arg_edit.res \
test_preview.res \
test_profile.res \
diff --git a/src/testdir/test_plugin_python3complete.vim b/src/testdir/test_plugin_python3complete.vim
new file mode 100644
index 0000000..639d9ce
--- /dev/null
+++ b/src/testdir/test_plugin_python3complete.vim
@@ -0,0 +1,40 @@
+" Tests for the Python omni-completion plugin (runtime/autoload/python3complete.vim).
+
+if !has('python3')
+ finish
+endif
+
+func s:CompleteAndExpectNoMarker(buffer_lines, marker_path, msg)
+ call delete(a:marker_path)
+ let g:pythoncomplete_allow_import = 0
+ new
+ setfiletype python
+ call setline(1, a:buffer_lines)
+ call cursor(line('$'), col([line('$'), '$']))
+
+ silent! call python3complete#Complete(0, '')
+
+ call assert_false(filereadable(a:marker_path),
+ \ a:msg . ' (marker ' . a:marker_path . ' was created)')
+
+ bwipe!
+ call delete(a:marker_path)
+ unlet! g:pythoncomplete_allow_import
+endfunc
+
+func Test_python3complete_no_exec_via_class_docstring()
+ " A class-body docstring is emitted verbatim between triple quotes by
+ " get_code() and runs at class-definition time during exec(). A single-
+ " quoted source docstring lets an embedded """ survive doc()'s leading/
+ " trailing quote strip and break out of the generated literal.
+ let marker = tempname()
+ call s:CompleteAndExpectNoMarker([
+ \ 'class Foo:',
+ \ ' ''x"""+open("' . marker . '", "w").close()+"""y''',
+ \ ' pass',
+ \ 'Foo.',
+ \ ], marker,
+ \ 'class docstring expression was evaluated during omni-completion')
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab

View File

@ -0,0 +1,116 @@
From 3670c2d9794931e2c3f01dcc2b26165f31306b90 Mon Sep 17 00:00:00 2001
From: RHEL Packaging Agent <redhat-ymir-agent@redhat.com>
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

View File

@ -24,7 +24,7 @@ Summary: The VIM editor
URL: http://www.vim.org/
Name: vim
Version: %{baseversion}.%{patchlevel}
Release: 27%{?dist}
Release: 31%{?dist}
License: Vim and MIT
Source0: ftp://ftp.vim.org/pub/vim/unix/vim-%{baseversion}-%{patchlevel}.tar.bz2
Source1: vim.sh
@ -193,6 +193,28 @@ Patch3062: 0001-patch-9.2.0561-security-possible-code-execution-with.patch
# https://github.com/vim/vim/commit/868ad62cb8bf8038322eab2badd31bd98b02b9df
# stripped src/version.c hunk
Patch3063: 0001-patch-9.2.0568-pythoncomplete-g-pythoncomplete_allow.patch
# RHEL-192102 CVE-2026-57456 possible code execution with python complete
# https://redhat.atlassian.net/browse/RHEL-192102
# https://github.com/vim/vim/commit/cce141c42740f122dd8486ae04e21c2a81016ba8
# stripped src/version.c hunk, omitted Last Updated comment changes, created minimal test file, adapted for vim 8.0
Patch3064: 0001-patch-9.2.0699-security-possible-code-execution-with.patch
# RHEL-191365 CVE-2026-57455 Out-of-bounds write with soundfold()
# https://redhat.atlassian.net/browse/RHEL-191365
# https://github.com/vim/vim/commit/497f931f85339d175d7f69588dd249e8ccfed41b
# stripped src/version.c hunk, adapted test to vim 8.0 (no defer/D flag), added test to Make_all.mak
Patch3065: 0001-patch-9.2.0698-security-Out-of-bounds-write-with-sou.patch
# RHEL-194055 CVE-2026-55693 out-of-bounds write in tree_count_words()
# https://redhat.atlassian.net/browse/RHEL-194055
# https://github.com/vim/vim/commit/a80874d9b84a01040e3d1aef2d4a59e1934dafb7
# stripped src/version.c hunk, adapted test for vim 8.0 (replaced blob
# 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
@ -438,6 +460,10 @@ perl -pi -e "s,bin/nawk,bin/awk,g" runtime/tools/mve.awk
%patch -P 3061 -p1 -b .netrw-injection
%patch -P 3062 -p1 -b .CVE-2026-52858
%patch -P 3063 -p1 -b .CVE-2026-52858-fix
%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
@ -957,6 +983,21 @@ touch %{buildroot}/%{_datadir}/%{name}/vimfiles/doc/tags
%{_datadir}/icons/locolor/*/apps/*
%changelog
* Tue Jul 14 2026 RHEL Packaging Agent <redhat-ymir-agent@redhat.com> - 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 <redhat-ymir-agent@redhat.com> - 2:8.0.1763-30
- RHEL-194055 CVE-2026-55693 vim: out-of-bounds write in
tree_count_words()
* Mon Jul 13 2026 RHEL Packaging Agent <redhat-ymir-agent@redhat.com> - 2:8.0.1763-29
- RHEL-191365 CVE-2026-57455 vim: Out-of-bounds write with soundfold()
* Sat Jul 04 2026 RHEL Packaging Agent <redhat-ymir-agent@redhat.com> - 2:8.0.1763-28
- RHEL-192102 CVE-2026-57456 vim: possible code execution with python
complete via crafted docstrings
* Wed Jul 01 2026 RHEL Packaging Agent <redhat-ymir-agent@redhat.com> - 2:8.0.1763-27
- RHEL-186656 CVE-2026-47162 vim: netrw code injection via NetrwBookHistSave
- RHEL-186648 CVE-2026-52858 vim: possible code execution with python3complete