vim/0001-patch-9.2.0495-security-runtime-netrw-code-injectio.patch
RHEL Packaging Agent e1c7040ec9 Fix CVE-2026-47162: netrw code injection via NetrwBookHistSave()
Backport upstream commit f08ab2f4d7d2 to fix CVE-2026-47162,
a code injection vulnerability in netrw's NetrwBookHistSave()
function. The fix replaces unsafe string concatenation with
the string() function for safe quoting of directory names
when saving bookmark history. A new test file
(test_plugin_netrw.vim) is included to verify the fix.

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

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

Assisted-by: Ymir
2026-08-05 18:06:22 +02:00

85 lines
3.1 KiB
Diff

From 191a038d82f12d4d55a42c505bf3faa10c22fbe4 Mon Sep 17 00:00:00 2001
From: Christian Brabandt <cb@256bit.org>
Date: Sun, 17 May 2026 18:53:48 +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
Signed-off-by: Christian Brabandt <cb@256bit.org>
---
runtime/autoload/netrw.vim | 2 +-
src/testdir/Make_all.mak | 2 ++
src/testdir/test_plugin_netrw.vim | 23 +++++++++++++++++++++++
3 files changed, 26 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 47575ef90..f7a44f35c 100644
--- a/runtime/autoload/netrw.vim
+++ b/runtime/autoload/netrw.vim
@@ -3803,7 +3803,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 2b3d16d78..2ed089f98 100644
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -229,6 +229,7 @@ NEW_TESTS = \
test_perl \
test_plugin_ccomplete \
+ test_plugin_netrw \
test_plugin_phpcomplete \
test_plugin_tar \
test_plus_arg_edit \
test_popup \
@@ -482,6 +483,7 @@ NEW_TESTS_RES = \
test_perl.res \
test_plugin_ccomplete.res \
+ test_plugin_netrw.res \
test_plugin_phpcomplete.res \
test_plugin_tar.res \
test_plus_arg_edit.res \
test_popup.res \
diff --git a/src/testdir/test_plugin_netrw.vim b/src/testdir/test_plugin_netrw.vim
new file mode 100644
index 000000000..e9d771078
--- /dev/null
+++ b/src/testdir/test_plugin_netrw.vim
@@ -0,0 +1,23 @@
+" Tests for the netrw plugin
+
+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