patch 9.2.0479: [security]: runtime(tar): command injection in tar plugin
Commit:
https://github.com/vim/vim/commit/3fb5e58fbc63d86a3e65f1a141b0d67af2aa38a1
Author: Christian Brabandt <
c...@256bit.org>
Date: Thu May 14 15:35:28 2026 +0000
patch 9.2.0479: [security]: runtime(tar): command injection in tar plugin
Problem: [security]: runtime(tar): command injection in tar plugin
(Christopher Lusk)
Solution: Use the correct shellescape(args, 1) form for a :! command
Github Advisory:
https://github.com/vim/vim/security/advisories/GHSA-2fpv-9ff7-xg5w
Signed-off-by: Christian Brabandt <
c...@256bit.org>
diff --git a/runtime/autoload/tar.vim b/runtime/autoload/tar.vim
index 1347371b5..3c899f85f 100644
--- a/runtime/autoload/tar.vim
+++ b/runtime/autoload/tar.vim
@@ -25,6 +25,7 @@
" 2026 Apr 09 by Vim Project: fix bug with dotted filename (#19930)
" 2026 Apr 15 by Vim Project: fix more path traversal issues (#19981)
" 2026 Apr 16 by Vim Project: use g:tar_secure in tar#Extract()
+" 2026 May 14 by Vim Project: use correct shellescape() call in Vimuntar()
"
" Contains many ideas from Michael Toren's <tar.vim>
"
@@ -832,9 +833,9 @@ fun! tar#Vimuntar(...)
" if necessary, decompress the tarball; then, extract it
if tartail =~ '\.tgz'
if executable("gunzip")
- silent exe "!gunzip ".shellescape(tartail)
+ silent exe "!gunzip ".shellescape(tartail, 1)
elseif executable("gzip")
- silent exe "!gzip -d ".shellescape(tartail)
+ silent exe "!gzip -d ".shellescape(tartail, 1)
else
echoerr "unable to decompress<".tartail."> on this system"
if simplify(curdir) != simplify(tarhome)
diff --git a/src/testdir/test_plugin_tar.vim b/src/testdir/test_plugin_tar.vim
index 56f25df2a..e19e5d809 100644
--- a/src/testdir/test_plugin_tar.vim
+++ b/src/testdir/test_plugin_tar.vim
@@ -318,3 +318,22 @@ def g:Test_extract_with_dotted_filename()
delete('X.txt')
bw!
enddef
+
+def g:Test_extract_command_injection()
+ CheckExecutable gunzip
+ CheckExecutable touch
+ var tgz = eval('0z1F8B08087795056A000364756D6D792E74617200EDCE2B12C2300004D01C254' ..
+ '7480269CE534080A8495BD1DBF3996106C3A08A7ACFACD8157B59A7690BFB4A0FC3707C666E357D' ..
+ 'E65BC8B5A47CC8A5D61A522EA5B510D3CEBF5ED679197B8CE17CEDB7F9D4C76FBB5F3D000000000' ..
+ '000000000FCD11D32415E2C00280000')
+ var dirname = tempname()
+
+ mkdir(dirname, 'R')
+ var tar = dirname .. "/';%$(touch pwned)'.tgz"
+ writefile(tgz, tar)
+ new
+ exe "e " .. fnameescape(tar)
+ exe ":Vimuntar " .. dirname
+ assert_false(filereadable(dirname .. "/pwned"))
+ bw!
+enddef
diff --git a/src/version.c b/src/version.c
index 8f46a438d..c98028a80 100644
--- a/src/version.c
+++ b/src/version.c
@@ -729,6 +729,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 479,
/**/
478,
/**/