Fix CVE-2026-47162: netrw code injection via NetrwBookHistSave()

Backport upstream fix for CVE-2026-47162 which addresses a code
injection vulnerability in the netrw plugin's
NetrwBookHistSave() function. The fix uses string() to properly
quote directory names written to the netrw history file,
preventing malicious directory names from executing arbitrary
Vim commands when the history is sourced.

The patch was adapted from upstream commit f08ab2f4d7d2 for
vim 8.0: adjusted file path to runtime/autoload/netrw.vim,
adapted the setline() call to the downstream loop pattern,
and created a minimal test file for the injection scenario.

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

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

Assisted-by: Ymir
This commit is contained in:
RHEL Packaging Agent 2026-06-23 20:55:39 +00:00 committed by Zdenek Dohnal
parent 6a0060b814
commit 9aca0db7e7
2 changed files with 88 additions and 1 deletions

View File

@ -0,0 +1,77 @@
From 458f4aac609d31b2e6108c9883221168cf4d0b28 Mon Sep 17 00:00:00 2001
From: RHEL Packaging Agent <redhat-ymir-agent@redhat.com>
Date: Tue, 23 Jun 2026 20:47:37 +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)
Adapted for vim 8.0: netrw.vim is at runtime/autoload/netrw.vim,
setline uses (cnt+lastline) instead of lastline, loop uses while
instead of for. Stripped src/version.c and Last Change comment.
Created minimal test_plugin_netrw.vim with only the injection test.
---
runtime/autoload/netrw.vim | 2 +-
src/testdir/Make_all.mak | 1 +
src/testdir/test_plugin_netrw.vim | 21 +++++++++++++++++++++
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 89f749c..7534467 100644
--- a/runtime/autoload/netrw.vim
+++ b/runtime/autoload/netrw.vim
@@ -3558,7 +3558,7 @@ fun! s:NetrwBookHistSave()
let lastline = line("$")
let cnt = 1
while cnt <= g:netrw_dirhist_cnt
- call setline((cnt+lastline),'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'")
+ call setline((cnt+lastline),'let g:netrw_dirhist_'.cnt.'='.string(g:netrw_dirhist_{cnt}))
let cnt= cnt + 1
endwhile
exe "sil! w! ".savefile
diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak
index 5f1c38c..4b34928 100644
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -145,6 +145,7 @@ NEW_TESTS = test_arabic.res \
test_packadd.res \
test_paste.res \
test_perl.res \
+ test_plugin_netrw.res \
test_plus_arg_edit.res \
test_preview.res \
test_profile.res \
diff --git a/src/testdir/test_plugin_netrw.vim b/src/testdir/test_plugin_netrw.vim
new file mode 100644
index 0000000..737617f
--- /dev/null
+++ b/src/testdir/test_plugin_netrw.vim
@@ -0,0 +1,21 @@
+source shared.vim
+
+func Test_netrw_injection()
+ let g:netrw_home = getcwd()
+ let savefile = g:netrw_home . '/.netrwhist'
+ let g:netrw_dirhistmax = 10
+ let g:netrw_dirhist_cnt = 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_dirhist_cnt g:netrw_dirhist_1 g:injected
+ endtry
+endfunc
--
2.52.0

View File

@ -24,7 +24,7 @@ Summary: The VIM editor
URL: http://www.vim.org/
Name: vim
Version: %{baseversion}.%{patchlevel}
Release: 26%{?dist}
Release: 27%{?dist}
License: Vim and MIT
Source0: ftp://ftp.vim.org/pub/vim/unix/vim-%{baseversion}-%{patchlevel}.tar.bz2
Source1: vim.sh
@ -179,6 +179,12 @@ Patch3059: 0001-patch-9.2.0479-security-runtime-tar-command-injecti.patch
# - adapted test: replaced CheckFeature with has() guard, used mkdir 'p' flag
# with manual cleanup instead of 'pR' (not available in vim 8.0)
Patch3060: 0001-patch-9.2.0496-security-Code-Injection-in-cucumber-f.patch
# RHEL-186656 CVE-2026-47162 vim: netrw code injection via NetrwBookHistSave()
# https://redhat.atlassian.net/browse/RHEL-186656
# https://github.com/vim/vim/commit/f08ab2f4d7d2947c8dd6c179ae08ee6146a2694b
# Adapted for vim 8.0: netrw.vim path differs, setline uses (cnt+lastline),
# stripped src/version.c and Last Change comment, created minimal test file
Patch3061: 0001-patch-9.2.0495-security-runtime-netrw-code-injection.patch
# gcc is no longer in buildroot by default
@ -421,6 +427,7 @@ perl -pi -e "s,bin/nawk,bin/awk,g" runtime/tools/mve.awk
%patch -P 3058 -p1 -b .tag-backtick-inject
%patch -P 3059 -p1 -b .tar-shellescape-fix
%patch -P 3060 -p1 -b .cucumber-code-injection
%patch -P 3061 -p1 -b .netrw-injection
%build
@ -940,6 +947,9 @@ touch %{buildroot}/%{_datadir}/%{name}/vimfiles/doc/tags
%{_datadir}/icons/locolor/*/apps/*
%changelog
* 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
* Tue Jun 30 2026 RHEL Packaging Agent <redhat-ymir-agent@redhat.com> - 2:8.0.1763-26
- CVE-2026-47167 vim: Code Injection in cucumber filetype plugin