patch 9.1.1164: [security]: code execution with tar.vim and special crafted tar 
files

Commit: 
https://github.com/vim/vim/commit/334a13bff78aa0ad206bc436885f63e3a0bab399
Author: Christian Brabandt <[email protected]>
Date:   Sun Mar 2 19:33:51 2025 +0100

    patch 9.1.1164: [security]: code execution with tar.vim and special crafted 
tar files
    
    Problem:  editing a special crafted tar file allows code execution
              (RyotaK, after 129a8446d23cd9cb4445fcfea259cba5e0487d29)
    Solution: escape the filename before feeding it to the `:read` command
    
    Github Advisory:
    https://github.com/vim/vim/security/advisories/GHSA-wfmf-8626-q3r3
    
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/runtime/autoload/tar.vim b/runtime/autoload/tar.vim
index 1c2ed78c1..14e68b789 100644
--- a/runtime/autoload/tar.vim
+++ b/runtime/autoload/tar.vim
@@ -11,6 +11,7 @@
 "   2025 Feb 06 by Vim Project: add support for lz4 (#16591)
 "   2025 Feb 28 by Vim Project: add support for bzip3 (#16755)
 "   2025 Mar 01 by Vim Project: fix syntax error in tar#Read()
+"   2025 Mar 02 by Vim Project: escape the filename before using :read
 "
 "      Contains many ideas from Michael Toren's <tar.vim>
 "
@@ -284,6 +285,8 @@ fun! tar#Read(fname,mode)
   set report=10
   let tarfile = substitute(a:fname,'tarfile:\(.\{-}\)::.*$',' ','')
   let fname   = substitute(a:fname,'tarfile:.\{-}::\(.*\)$',' ','')
+  " be careful not to execute special crafted files
+  let escape_file = fname->fnameescape()
 
   " changing the directory to the temporary earlier to allow tar to extract 
the file with permissions intact
   if !exists("*mkdir")
@@ -361,13 +364,13 @@ fun! tar#Read(fname,mode)
 
   if tarfile =~# '\.bz2$'
    exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." 
-".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
-   exe "read ".fname
+   exe "read ".escape_file
   elseif tarfile =~# '\.bz3$'
    exe "sil! r! bzip3 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." 
-".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
-   exe "read ".fname
+   exe "read ".escape_file
   elseif tarfile =~# '\.\(gz\)$'
    exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." 
-".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
-   exe "read ".fname
+   exe "read ".escape_file
   elseif tarfile =~# '\(\.tgz\|\.tbz\|\.txz\)'
    if has("unix") && executable("file")
     let filekind= system("file ".shellescape(tarfile,1))
@@ -376,40 +379,40 @@ fun! tar#Read(fname,mode)
    endif
    if filekind =~ "bzip2"
     exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." 
-".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
-    exe "read ".fname
+    exe "read ".escape_file
    elseif filekind =~ "bzip3"
     exe "sil! r! bzip3 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." 
-".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
-    exe "read ".fname
+    exe "read ".escape_file
    elseif filekind =~ "XZ"
     exe "sil! r! xz -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." 
-".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
-    exe "read ".fname
+    exe "read ".escape_file
    elseif filekind =~ "Zstandard"
     exe "sil! r! zstd --decompress --stdout -- ".shellescape(tarfile,1)."| 
".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
-    exe "read ".fname
+    exe "read ".escape_file
    else
     exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." 
-".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
-    exe "read ".fname
+    exe "read ".escape_file
    endif
 
   elseif tarfile =~# '\.lrp$'
    exe "sil! r! cat -- ".shellescape(tarfile,1)." | gzip -d -c - | 
".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
-   exe "read ".fname
+   exe "read ".escape_file
   elseif tarfile =~# '\.lzma$'
    exe "sil! r! lzma -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." 
-".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
-   exe "read ".fname
+   exe "read ".escape_file
   elseif tarfile =~# '\.\(xz\|txz\)$'
    exe "sil! r! xz --decompress --stdout -- ".shellescape(tarfile,1)." | 
".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
-   exe "read ".fname
+   exe "read ".escape_file
   elseif tarfile =~# '\.\(lz4\|tlz4\)$'
    exe "sil! r! lz4 --decompress --stdout -- ".shellescape(tarfile,1)." | 
".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
-   exe "read ".fname
+   exe "read ".escape_file
   else
    if tarfile =~ '^\s*-'
     " A file name starting with a dash is taken as an option.  Prepend ./ to 
avoid that.
     let tarfile = substitute(tarfile, '-', './-', '')
    endif
    exe "silent r! ".g:tar_cmd." -".g:tar_readoptions.shellescape(tarfile,1)." 
".tar_secure.shellescape(fname,1).decmp
-   exe "read ".fname
+   exe "read ".escape_file
   endif
 
    redraw!
diff --git a/src/version.c b/src/version.c
index 25c29256c..6fd80d6b1 100644
--- a/src/version.c
+++ b/src/version.c
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1164,
 /**/
     1163,
 /**/

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/vim_dev/E1tooJI-004lCc-M3%40256bit.org.

Raspunde prin e-mail lui