vim/0001-patch-9.2.0495-security-runtime-netrw-code-injectio.patch
RHEL Packaging Agent 12deb611d3 Fix CVE-2026-47162: netrw code injection via NetrwBookHistSave()
Backport upstream patch 9.2.0495 (commit f08ab2f4d7d2) to fix
CVE-2026-47162 — code injection via NetrwBookHistSave() in the
netrw plugin.

The vulnerable setline() call in s:NetrwBookHistSave() used naive
string concatenation to build Vimscript let statements, allowing
code injection through crafted directory names. The fix replaces
this with string() for proper quoting.

The patch was adjusted for the RHEL 9 Vim 8.2 codebase: netrw
path changed from runtime/pack/dist/opt/netrw/autoload/ to
runtime/autoload/, and a new test file was added.

CVE: CVE-2026-47162
Upstream patches:
 - f08ab2f4d7.patch
Resolves: RHEL-186655

This commit was backported by Ymir, a Red Hat Enterprise Linux software maintenance AI agent.

Assisted-by: Ymir
2026-07-31 16:22:25 +02:00

80 lines
3.0 KiB
Diff

From 952ef64dbdc6939d8beb59ce1304f231debc52e2 Mon Sep 17 00:00:00 2001
From: RHEL Packaging Agent <redhat-ymir-agent@redhat.com>
Date: Thu, 30 Jul 2026 12:30:41 +0000
Subject: [PATCH] patch 9.2.0495: [security]: runtime(netrw): code injection
via NetrwBookHistSave()
Problem: [security]: runtime(netrw): code injection via
NetrwBookHistSave()
Solution: Properly quote the directory name using string() function
(Srinivas Piskala Ganesh Babu)
Github Security Advisory:
https://github.com/vim/vim/security/advisories/GHSA-crm5-rh6j-2c7c
---
runtime/autoload/netrw.vim | 2 +-
src/testdir/Make_all.mak | 2 ++
src/testdir/test_plugin_netrw.vim | 20 ++++++++++++++++++++
3 files changed, 23 insertions(+), 1 deletion(-)
create mode 100644 src/testdir/test_plugin_netrw.vim
diff --git a/runtime/autoload/netrw.vim b/runtime/autoload/netrw.vim
index 5fd08ac..41893e2 100644
--- a/runtime/autoload/netrw.vim
+++ b/runtime/autoload/netrw.vim
@@ -3736,7 +3736,7 @@ fun! s:NetrwBookHistSave()
while ( first || cnt != g:netrw_dirhistcnt )
let lastline= lastline + 1
if exists("g:netrw_dirhist_{cnt}")
- call setline(lastline,'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'")
+ call setline(lastline,'let g:netrw_dirhist_'.cnt.'='.string(g:netrw_dirhist_{cnt}))
" call Decho("..".lastline.'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'",'~'.expand("<slnum>"))
endif
let first = 0
diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak
index 7fd4e89..1709886 100644
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -209,6 +209,7 @@ NEW_TESTS = \
test_perl \
test_plugin_ccomplete \
+ test_plugin_netrw \
test_plugin_tar \
test_plugin_phpcomplete \
test_plugin_python3complete \
test_plus_arg_edit \
@@ -448,6 +449,7 @@ NEW_TESTS_RES = \
test_perl.res \
test_plugin_ccomplete.res \
+ test_plugin_netrw.res \
test_plugin_tar.res \
test_plugin_phpcomplete.res \
test_plugin_python3complete.res \
test_plus_arg_edit.res \
diff --git a/src/testdir/test_plugin_netrw.vim b/src/testdir/test_plugin_netrw.vim
new file mode 100644
index 0000000..d840905
--- /dev/null
+++ b/src/testdir/test_plugin_netrw.vim
@@ -0,0 +1,20 @@
+func Test_netrw_injection()
+ let g:netrw_home = getcwd()
+ let savefile = g:netrw_home . '/.netrwhist'
+ let g:netrw_dirhistmax = 10
+ let g:netrw_dirhistcnt = 1
+ let g:netrw_dirhist_1 = "x'|let g:injected = 1|let y='z"
+ call delete(savefile)
+ try
+ call netrw#Call('NetrwBookHistSave')
+ call assert_true(filereadable(savefile), savefile . ' must be written')
+ unlet g:netrw_dirhist_1
+ execute 'source ' . fnameescape(savefile)
+ call assert_false(exists("g:injected"), 'injected statement must not execute')
+ call assert_equal("x'|let g:injected = 1|let y='z", g:netrw_dirhist_1, 'dirname must round-trip')
+ finally
+ call delete(savefile)
+ unlet! g:netrw_home g:netrw_dirhistmax g:netrw_dirhistcnt g:netrw_dirhist_1 g:injected
+ endtry
+endfunc
+" vim:ts=8 sts=2 sw=2 et