From dea5065b7bb70e3bcaac6658c9336d58db800bb9 Mon Sep 17 00:00:00 2001 From: Funda Wang Date: Tue, 12 Aug 2025 08:43:41 +0800 Subject: [PATCH] 9.1.1623 --- backport-CVE-2025-53905.patch | 676 --------------------------- backport-CVE-2025-53906.patch | 236 ---------- v9.1.1546.tar.gz => v9.1.1623.tar.gz | 4 +- vim.spec | 9 +- 4 files changed, 7 insertions(+), 918 deletions(-) delete mode 100644 backport-CVE-2025-53905.patch delete mode 100644 backport-CVE-2025-53906.patch rename v9.1.1546.tar.gz => v9.1.1623.tar.gz (32%) diff --git a/backport-CVE-2025-53905.patch b/backport-CVE-2025-53905.patch deleted file mode 100644 index 2e46885..0000000 --- a/backport-CVE-2025-53905.patch +++ /dev/null @@ -1,676 +0,0 @@ -From 87757c6b0a4b2c1f71c72ea8e1438b8fb116b239 Mon Sep 17 00:00:00 2001 -From: Christian Brabandt -Date: Tue, 15 Jul 2025 21:54:00 +0200 -Subject: [PATCH] patch 9.1.1552: [security]: path traversal issue in tar.vim - -Problem: [security]: path traversal issue in tar.vim - (@ax) -Solution: warn the user for such things, drop leading /, don't - forcefully overwrite files when writing temporary files, - refactor autoload/tar.vim - -tar.vim: drop leading / in path names - -A tar archive containing files with leading `/` may cause confusions as -to where the content is extracted. Let's make sure we drop the leading -`/` and use a relative path instead. - -Also while at it, had to refactor it quite a bit and increase the -minimum supported Vim version to v9. Also add a test for some basic tar -functionality - -closes: #17733 ---- - runtime/autoload/tar.vim | 227 +++++++++++++++----------------- - runtime/doc/pi_tar.txt | 32 ++--- - runtime/doc/tags | 1 - - runtime/plugin/tarPlugin.vim | 8 +- - 4 files changed, 125 insertions(+), 143 deletions(-) - -diff --git a/runtime/autoload/tar.vim b/runtime/autoload/tar.vim -index 7c1cefa63eaad7..1a0d4f8a3d28e4 100644 ---- a/runtime/autoload/tar.vim -+++ b/runtime/autoload/tar.vim -@@ -16,6 +16,7 @@ - " instead of shelling out to file(1) - " 2025 Apr 16 by Vim Project: decouple from netrw by adding s:WinPath() - " 2025 May 19 by Vim Project: restore working directory after read/write -+" 2025 Jul 13 by Vim Project: warn with path traversal attacks - " - " Contains many ideas from Michael Toren's - " -@@ -34,9 +35,9 @@ if &cp || exists("g:loaded_tar") - finish - endif - let g:loaded_tar= "v32b" --if v:version < 702 -+if v:version < 900 - echohl WarningMsg -- echo "***warning*** this version of tar needs vim 7.2" -+ echo "***warning*** this version of tar needs vim 9.0" - echohl Normal - finish - endif -@@ -46,10 +47,10 @@ set cpo&vim - " --------------------------------------------------------------------- - " Default Settings: {{{1 - if !exists("g:tar_browseoptions") -- let g:tar_browseoptions= "Ptf" -+ let g:tar_browseoptions= "tf" - endif - if !exists("g:tar_readoptions") -- let g:tar_readoptions= "pPxf" -+ let g:tar_readoptions= "pxf" - endif - if !exists("g:tar_cmd") - let g:tar_cmd= "tar" -@@ -58,6 +59,7 @@ if !exists("g:tar_writeoptions") - let g:tar_writeoptions= "uf" - endif - if !exists("g:tar_delfile") -+ " Note: not supported on BSD - let g:tar_delfile="--delete -f" - endif - if !exists("g:netrw_cygwin") -@@ -106,10 +108,26 @@ if !exists("g:tar_shq") - endif - endif - -+let g:tar_secure=' -- ' -+let g:tar_leading_pat='^\%([.]\{,2\}/\)\+' -+ - " ---------------- - " Functions: {{{1 - " ---------------- - -+" --------------------------------------------------------------------- -+" s:Msg: {{{2 -+fun! s:Msg(func, severity, msg) -+ redraw! -+ if a:severity =~? 'error' -+ echohl Error -+ else -+ echohl WarningMsg -+ endif -+ echo $"***{a:severity}*** ({a:func}) {a:msg}" -+ echohl None -+endfunc -+ - " --------------------------------------------------------------------- - " tar#Browse: {{{2 - fun! tar#Browse(tarfile) -@@ -118,16 +136,14 @@ fun! tar#Browse(tarfile) - - " sanity checks - if !executable(g:tar_cmd) -- redraw! -- echohl Error | echo '***error*** (tar#Browse) "'.g:tar_cmd.'" not available on your system' -+ call s:Msg('tar#Browse', 'error', $"{g:tar_cmd} not available on your system") - let &report= repkeep - return - endif - if !filereadable(a:tarfile) - if a:tarfile !~# '^\a\+://' - " if it's an url, don't complain, let url-handlers such as vim do its thing -- redraw! -- echohl Error | echo "***error*** (tar#Browse) File not readable<".a:tarfile.">" | echohl None -+ call s:Msg('tar#Browse', 'error', $"File not readable<{a:tarfile}>") - endif - let &report= repkeep - return -@@ -203,28 +219,18 @@ fun! tar#Browse(tarfile) - exe "sil! r! ".g:tar_cmd." -".g:tar_browseoptions." ".shellescape(tarfile,1) - endif - if v:shell_error != 0 -- redraw! -- echohl WarningMsg | echo "***warning*** (tar#Browse) please check your g:tar_browseoptions<".g:tar_browseoptions.">" -+ call s:Msg('tar#Browse', 'warning', $"please check your g:tar_browseoptions '<{g:tar_browseoptions}>'") - return - endif -- " -- " The following should not be neccessary, since in case of errors the -- " previous if statement should have caught the problem (because tar exited -- " with a non-zero exit code). -- " if line("$") == curlast || ( line("$") == (curlast + 1) && -- " \ getline("$") =~# '\c\<\%(warning\|error\|inappropriate\|unrecognized\)\>' && -- " \ getline("$") =~ '\s' ) -- " redraw! -- " echohl WarningMsg | echo "***warning*** (tar#Browse) ".a:tarfile." doesn't appear to be a tar file" | echohl None -- " keepj sil! %d -- " let eikeep= &ei -- " set ei=BufReadCmd,FileReadCmd -- " exe "r ".fnameescape(a:tarfile) -- " let &ei= eikeep -- " keepj sil! 1d -- " call Dret("tar#Browse : a:tarfile<".a:tarfile.">") -- " return -- " endif -+ -+ " remove tar: Removing leading '/' from member names -+ " Note: the message could be localized -+ if search('^tar: ') > 0 || search(g:tar_leading_pat) > 0 -+ call append(3,'" Note: Path Traversal Attack detected!') -+ let b:leading_slash = 1 -+ " remove the message output -+ sil g/^tar: /d -+ endif - - " set up maps supported for tar - setlocal noma nomod ro -@@ -243,12 +249,7 @@ fun! s:TarBrowseSelect() - let repkeep= &report - set report=10 - let fname= getline(".") -- -- if !exists("g:tar_secure") && fname =~ '^\s*-\|\s\+-' -- redraw! -- echohl WarningMsg | echo '***warning*** (tar#BrowseSelect) rejecting tarfile member<'.fname.'> because of embedded "-"' -- return -- endif -+ let ls= get(b:, 'leading_slash', 0) - - " sanity check - if fname =~ '^"' -@@ -270,7 +271,8 @@ fun! s:TarBrowseSelect() - wincmd _ - endif - let s:tblfile_{winnr()}= curfile -- call tar#Read("tarfile:".tarfile.'::'.fname,1) -+ let b:leading_slash= ls -+ call tar#Read("tarfile:".tarfile.'::'.fname) - filetype detect - set nomod - exe 'com! -buffer -nargs=? -complete=file TarDiff :call tar#Diff(,"'.fnameescape(fname).'")' -@@ -280,26 +282,18 @@ endfun - - " --------------------------------------------------------------------- - " tar#Read: {{{2 --fun! tar#Read(fname,mode) -+fun! tar#Read(fname) - let repkeep= &report - set report=10 - let tarfile = substitute(a:fname,'tarfile:\(.\{-}\)::.*$','\1','') - let fname = substitute(a:fname,'tarfile:.\{-}::\(.*\)$','\1','') - " 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") -- redraw! -- echohl Error | echo "***error*** (tar#Write) sorry, mkdir() doesn't work on your system" | echohl None -- let &report= repkeep -- return -- endif -+ let escape_file = fname->substitute(g:tar_leading_pat, '', '')->fnameescape() - - let curdir= getcwd() -+ let b:curdir= curdir - let tmpdir= tempname() -- let b:curdir= tmpdir -- let b:tmpdir= curdir -+ let b:tmpdir= tmpdir - if tmpdir =~ '\.' - let tmpdir= substitute(tmpdir,'\.[^.]*$','','e') - endif -@@ -309,8 +303,7 @@ fun! tar#Read(fname,mode) - try - exe "lcd ".fnameescape(tmpdir) - catch /^Vim\%((\a\+)\)\=:E344/ -- redraw! -- echohl Error | echo "***error*** (tar#Write) cannot lcd to temporary directory" | Echohl None -+ call s:Msg('tar#Read', 'error', "cannot lcd to temporary directory") - let &report= repkeep - return - endtry -@@ -333,7 +326,7 @@ fun! tar#Read(fname,mode) - elseif fname =~ '\.bz3$' && executable("bz3cat") - let decmp= "|bz3cat" - let doro = 1 -- elseif fname =~ '\.t\=gz$' && executable("zcat") -+ elseif fname =~ '\.t\=gz$' && executable("zcat") - let decmp= "|zcat" - let doro = 1 - elseif fname =~ '\.lzma$' && executable("lzcat") -@@ -356,68 +349,66 @@ fun! tar#Read(fname,mode) - endif - endif - -- if exists("g:tar_secure") -- let tar_secure= " -- " -- else -- let tar_secure= " " -- endif - - 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 "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp - 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 "sil! r! bzip3 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp - 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 "sil! r! gzip -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp - exe "read ".escape_file - elseif tarfile =~# '\(\.tgz\|\.tbz\|\.txz\)' - let filekind= s:Header(tarfile) - 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 "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp - 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 "sil! r! bzip3 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp - 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 "sil! r! xz -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp - exe "read ".escape_file - elseif filekind =~? "zstd" -- exe "sil! r! zstd --decompress --stdout -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp -+ exe "sil! r! zstd --decompress --stdout -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp - exe "read ".escape_file - elseif filekind =~? "gzip" -- exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp -+ exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp - 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 "sil! r! cat -- ".shellescape(tarfile,1)." | gzip -d -c - | ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp - 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 "sil! r! lzma -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp - 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 "sil! r! xz --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp - 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 "sil! r! lz4 --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp - 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 "silent r! ".g:tar_cmd." -".g:tar_readoptions.shellescape(tarfile,1)." ".g:tar_secure.shellescape(fname,1).decmp - exe "read ".escape_file - endif -+ if get(b:, 'leading_slash', 0) -+ sil g/^tar: /d -+ endif - - redraw! - --if v:shell_error != 0 -+ if v:shell_error != 0 - lcd .. - call s:Rmdir("_ZIPVIM_") - exe "lcd ".fnameescape(curdir) -- echohl Error | echo "***error*** (tar#Read) sorry, unable to open or extract ".tarfile." with ".fname | echohl None -+ call s:Msg('tar#Read', 'error', $"sorry, unable to open or extract {tarfile} with {fname}") - endif - - if doro -@@ -426,7 +417,6 @@ if v:shell_error != 0 - endif - - let b:tarfile= a:fname -- exe "file tarfile::".fnameescape(fname) - - " cleanup - keepj sil! 0d -@@ -434,7 +424,7 @@ if v:shell_error != 0 - - let &report= repkeep - exe "lcd ".fnameescape(curdir) -- silent exe "file tarfile::".escape_file -+ silent exe "file tarfile::". fname->fnameescape() - endfun - - " --------------------------------------------------------------------- -@@ -446,22 +436,35 @@ fun! tar#Write(fname) - let curdir= b:curdir - let tmpdir= b:tmpdir - -- if !exists("g:tar_secure") && a:fname =~ '^\s*-\|\s\+-' -- redraw! -- echohl WarningMsg | echo '***warning*** (tar#Write) rejecting tarfile member<'.a:fname.'> because of embedded "-"' -- return -- endif -- - " sanity checks - if !executable(g:tar_cmd) - redraw! - let &report= repkeep - return - endif -- - let tarfile = substitute(b:tarfile,'tarfile:\(.\{-}\)::.*$','\1','') - let fname = substitute(b:tarfile,'tarfile:.\{-}::\(.*\)$','\1','') - -+ if get(b:, 'leading_slash', 0) -+ call s:Msg('tar#Write', 'error', $"sorry, not attempting to update {tarfile} with {fname}") -+ let &report= repkeep -+ return -+ endif -+ -+ if !isdirectory(fnameescape(tmpdir)) -+ call mkdir(fnameescape(tmpdir), 'p') -+ endif -+ exe $"lcd {fnameescape(tmpdir)}" -+ if isdirectory("_ZIPVIM_") -+ call s:Rmdir("_ZIPVIM_") -+ endif -+ call mkdir("_ZIPVIM_") -+ lcd _ZIPVIM_ -+ let dir = fnamemodify(fname, ':p:h') -+ if dir !~# '_ZIPVIM_$' -+ call mkdir(dir) -+ endif -+ - " handle compressed archives - if tarfile =~# '\.bz2' - call system("bzip2 -d -- ".shellescape(tarfile,0)) -@@ -500,8 +503,7 @@ fun! tar#Write(fname) - " Note: no support for name.tar.tbz/.txz/.tgz/.tlz4/.tzst - - if v:shell_error != 0 -- redraw! -- echohl Error | echo "***error*** (tar#Write) sorry, unable to update ".tarfile." with ".fname | echohl None -+ call s:Msg('tar#Write', 'error', $"sorry, unable to update {tarfile} with {fname}") - else - - if fname =~ '/' -@@ -519,28 +521,22 @@ fun! tar#Write(fname) - let tarfile = substitute(tarfile, '-', './-', '') - endif - -- if exists("g:tar_secure") -- let tar_secure= " -- " -- else -- let tar_secure= " " -- endif -- exe "w! ".fnameescape(fname) -+ " don't overwrite a file forcefully -+ exe "w ".fnameescape(fname) - if has("win32unix") && executable("cygpath") - let tarfile = substitute(system("cygpath ".shellescape(tarfile,0)),'\n','','e') - endif - - " delete old file from tarfile -- call system(g:tar_cmd." ".g:tar_delfile." ".shellescape(tarfile,0).tar_secure.shellescape(fname,0)) -+ " Note: BSD tar does not support --delete flag -+ call system(g:tar_cmd." ".g:tar_delfile." ".shellescape(tarfile,0).g:tar_secure.shellescape(fname,0)) - if v:shell_error != 0 -- redraw! -- echohl Error | echo "***error*** (tar#Write) sorry, unable to update ".fnameescape(tarfile)." with ".fnameescape(fname) | echohl None -+ call s:Msg('tar#Write', 'error', $"sorry, unable to update {fnameescape(tarfile)} with {fnameescape(fname)} --delete not supported?") - else -- - " update tarfile with new file -- call system(g:tar_cmd." -".g:tar_writeoptions." ".shellescape(tarfile,0).tar_secure.shellescape(fname,0)) -+ call system(g:tar_cmd." -".g:tar_writeoptions." ".shellescape(tarfile,0).g:tar_secure.shellescape(fname,0)) - if v:shell_error != 0 -- redraw! -- echohl Error | echo "***error*** (tar#Write) sorry, unable to update ".fnameescape(tarfile)." with ".fnameescape(fname) | echohl None -+ call s:Msg('tar#Write', 'error', $"sorry, unable to update {fnameescape(tarfile)} with {fnameescape(fname)}") - elseif exists("compress") - call system(compress) - if exists("tgz") -@@ -581,6 +577,7 @@ fun! tar#Diff(userfname,fname) - if a:userfname != "" - let fname= a:userfname - endif -+ exe "lcd ".fnameescape(b:tmpdir). '/_ZIPVIM_' - if filereadable(fname) - " sets current file (from tarball) for diff'ing - " splits window vertically -@@ -604,12 +601,6 @@ fun! tar#Extract() - set report=10 - let fname= getline(".") - -- if !exists("g:tar_secure") && fname =~ '^\s*-\|\s\+-' -- redraw! -- echohl WarningMsg | echo '***warning*** (tar#BrowseSelect) rejecting tarfile member<'.fname.'> because of embedded "-"' -- return -- endif -- - " sanity check - if fname =~ '^"' - let &report= repkeep -@@ -623,16 +614,16 @@ fun! tar#Extract() - if filereadable(tarbase.".tar") - call system(extractcmd." ".shellescape(tarbase).".tar ".shellescape(fname)) - if v:shell_error != 0 -- echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar ".fname.": failed!" | echohl NONE -+ call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar {fname}: failed!") - else -- echo "***note*** successfully extracted ".fname -+ echo "***note*** successfully extracted ". fname - endif - - elseif filereadable(tarbase.".tgz") - let extractcmd= substitute(extractcmd,"-","-z","") - call system(extractcmd." ".shellescape(tarbase).".tgz ".shellescape(fname)) - if v:shell_error != 0 -- echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tgz ".fname.": failed!" | echohl NONE -+ call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tgz {fname}: failed!") - else - echo "***note*** successfully extracted ".fname - endif -@@ -641,7 +632,7 @@ fun! tar#Extract() - let extractcmd= substitute(extractcmd,"-","-z","") - call system(extractcmd." ".shellescape(tarbase).".tar.gz ".shellescape(fname)) - if v:shell_error != 0 -- echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar.gz ".fname.": failed!" | echohl NONE -+ call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar.gz {fname}: failed!") - else - echo "***note*** successfully extracted ".fname - endif -@@ -650,7 +641,7 @@ fun! tar#Extract() - let extractcmd= substitute(extractcmd,"-","-j","") - call system(extractcmd." ".shellescape(tarbase).".tbz ".shellescape(fname)) - if v:shell_error != 0 -- echohl Error | echo "***error*** ".extractcmd."j ".tarbase.".tbz ".fname.": failed!" | echohl NONE -+ call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tbz {fname}: failed!") - else - echo "***note*** successfully extracted ".fname - endif -@@ -659,7 +650,7 @@ fun! tar#Extract() - let extractcmd= substitute(extractcmd,"-","-j","") - call system(extractcmd." ".shellescape(tarbase).".tar.bz2 ".shellescape(fname)) - if v:shell_error != 0 -- echohl Error | echo "***error*** ".extractcmd."j ".tarbase.".tar.bz2 ".fname.": failed!" | echohl NONE -+ call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar.bz2 {fname}: failed!") - else - echo "***note*** successfully extracted ".fname - endif -@@ -668,7 +659,7 @@ fun! tar#Extract() - let extractcmd= substitute(extractcmd,"-","-j","") - call system(extractcmd." ".shellescape(tarbase).".tar.bz3 ".shellescape(fname)) - if v:shell_error != 0 -- echohl Error | echo "***error*** ".extractcmd."j ".tarbase.".tar.bz3 ".fname.": failed!" | echohl NONE -+ call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar.bz3 {fname}: failed!") - else - echo "***note*** successfully extracted ".fname - endif -@@ -677,7 +668,7 @@ fun! tar#Extract() - let extractcmd= substitute(extractcmd,"-","-J","") - call system(extractcmd." ".shellescape(tarbase).".txz ".shellescape(fname)) - if v:shell_error != 0 -- echohl Error | echo "***error*** ".extractcmd." ".tarbase.".txz ".fname.": failed!" | echohl NONE -+ call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.txz {fname}: failed!") - else - echo "***note*** successfully extracted ".fname - endif -@@ -686,7 +677,7 @@ fun! tar#Extract() - let extractcmd= substitute(extractcmd,"-","-J","") - call system(extractcmd." ".shellescape(tarbase).".tar.xz ".shellescape(fname)) - if v:shell_error != 0 -- echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar.xz ".fname.": failed!" | echohl NONE -+ call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar.xz {fname}: failed!") - else - echo "***note*** successfully extracted ".fname - endif -@@ -695,7 +686,7 @@ fun! tar#Extract() - let extractcmd= substitute(extractcmd,"-","--zstd","") - call system(extractcmd." ".shellescape(tarbase).".tzst ".shellescape(fname)) - if v:shell_error != 0 -- echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tzst ".fname.": failed!" | echohl NONE -+ call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tzst {fname}: failed!") - else - echo "***note*** successfully extracted ".fname - endif -@@ -704,7 +695,7 @@ fun! tar#Extract() - let extractcmd= substitute(extractcmd,"-","--zstd","") - call system(extractcmd." ".shellescape(tarbase).".tar.zst ".shellescape(fname)) - if v:shell_error != 0 -- echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar.zst ".fname.": failed!" | echohl NONE -+ call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar.zst {fname}: failed!") - else - echo "***note*** successfully extracted ".fname - endif -@@ -713,7 +704,7 @@ fun! tar#Extract() - let extractcmd= substitute(extractcmd,"-","-I lz4","") - call system(extractcmd." ".shellescape(tarbase).".tlz4 ".shellescape(fname)) - if v:shell_error != 0 -- echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tlz4 ".fname.": failed!" | echohl NONE -+ call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tlz4 {fname}: failed!") - else - echo "***note*** successfully extracted ".fname - endif -@@ -722,7 +713,7 @@ fun! tar#Extract() - let extractcmd= substitute(extractcmd,"-","-I lz4","") - call system(extractcmd." ".shellescape(tarbase).".tar.lz4".shellescape(fname)) - if v:shell_error != 0 -- echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar.lz4 ".fname.": failed!" | echohl NONE -+ call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar.lz4 {fname}: failed!") - else - echo "***note*** successfully extracted ".fname - endif -@@ -735,15 +726,7 @@ endfun - " --------------------------------------------------------------------- - " s:Rmdir: {{{2 - fun! s:Rmdir(fname) -- if has("unix") -- call system("/bin/rm -rf -- ".shellescape(a:fname,0)) -- elseif has("win32") || has("win95") || has("win64") || has("win16") -- if &shell =~? "sh$" -- call system("/bin/rm -rf -- ".shellescape(a:fname,0)) -- else -- call system("del /S ".shellescape(a:fname,0)) -- endif -- endif -+ call delete(a:fname, 'rf') - endfun - - " s:FileHeader: {{{2 -diff --git a/runtime/doc/pi_tar.txt b/runtime/doc/pi_tar.txt -index 6d49928dcbc85f..52706e93efe1e6 100644 ---- a/runtime/doc/pi_tar.txt -+++ b/runtime/doc/pi_tar.txt -@@ -1,11 +1,10 @@ --*pi_tar.txt* For Vim version 9.1. Last change: 2025 Mar 16 -+*pi_tar.txt* For Vim version 9.1. Last change: 2025 Jul 15 - - +====================+ - | Tar File Interface | - +====================+ - --Author: Charles E. Campbell -- (remove NOSPAM from Campbell's email first) -+Original Author: Charles E. Campbell - Copyright 2005-2017: *tar-copyright* - The VIM LICENSE (see |copyright|) applies to the files in this - package, including tarPlugin.vim, tar.vim, and pi_tar.txt. Like -@@ -61,7 +60,7 @@ Copyright 2005-2017: *tar-copyright* - the file mentioned in the tarball. If the current directory is not - correct for that path, :TarDiff will fail to find the associated file. - -- If the [filename] is given, that that filename (and path) will be used -+ If the [filename] is given, that filename (and path) will be used - to specify the associated file. - - -@@ -95,24 +94,25 @@ Copyright 2005-2017: *tar-copyright* - *g:tar_readoptions* "OPxf" used to extract a file from a tarball - *g:tar_cmd* "tar" the name of the tar program - *g:tar_nomax* 0 if true, file window will not be maximized -- *g:tar_secure* undef if exists: -- "--"s will be used to prevent unwanted -- option expansion in tar commands. -- Please be sure that your tar command -- accepts "--"; Posix compliant tar -- utilities do accept them. -- if not exists: -- The tar plugin will reject any tar -- files or member files that begin with -- "-" -- Not all tar's support the "--" which is why -- it isn't default. - *g:tar_writeoptions* "uf" used to update/replace a file - - - ============================================================================== - 4. History *tar-history* - -+ unreleased: -+ Jul 13, 2025 * drop leading / -+ May 19, 2025 * restore working directory after read/write -+ Apr 16, 2025 * decouple from netrw by adding s:WinPath() -+ instead of shelling out to file(1) -+ Mar 02, 2025 * determine the compression using readblob() -+ Mar 02, 2025 * escape the filename before using :read -+ Mar 01, 2025 * fix syntax error in tar#Read() -+ Feb 28, 2025 * add support for bzip3 (#16755) -+ Feb 06, 2025 * add support for lz4 (#16591) -+ Nov 11, 2024 * support permissions (#7379) -+ Feb 19, 2024 * announce adoption -+ Jan 08, 2024 * fix a few problems (#138331, #12637, #8109) - v31 Apr 02, 2017 * (klartext) reported that browsing encrypted - files in a zip archive created unencrypted - swap files. I am applying a similar fix -diff --git a/runtime/doc/tags b/runtime/doc/tags -index 384b27aa6257a9..8251c73d412583 100644 ---- a/runtime/doc/tags -+++ b/runtime/doc/tags -@@ -7857,7 +7857,6 @@ g:tar_copycmd pi_tar.txt /*g:tar_copycmd* - g:tar_extractcmd pi_tar.txt /*g:tar_extractcmd* - g:tar_nomax pi_tar.txt /*g:tar_nomax* - g:tar_readoptions pi_tar.txt /*g:tar_readoptions* --g:tar_secure pi_tar.txt /*g:tar_secure* - g:tar_writeoptions pi_tar.txt /*g:tar_writeoptions* - g:termdebug_config terminal.txt /*g:termdebug_config* - g:termdebugger terminal.txt /*g:termdebugger* -diff --git a/runtime/plugin/tarPlugin.vim b/runtime/plugin/tarPlugin.vim -index 825b7ae17fb4f8..e55a367854857c 100644 ---- a/runtime/plugin/tarPlugin.vim -+++ b/runtime/plugin/tarPlugin.vim -@@ -23,14 +23,14 @@ set cpo&vim - " Public Interface: {{{1 - augroup tar - au! -- au BufReadCmd tarfile::* call tar#Read(expand(""), 1) -- au FileReadCmd tarfile::* call tar#Read(expand(""), 0) -+ au BufReadCmd tarfile::* call tar#Read(expand("")) -+ au FileReadCmd tarfile::* call tar#Read(expand("")) - au BufWriteCmd tarfile::* call tar#Write(expand("")) - au FileWriteCmd tarfile::* call tar#Write(expand("")) - - if has("unix") -- au BufReadCmd tarfile::*/* call tar#Read(expand(""), 1) -- au FileReadCmd tarfile::*/* call tar#Read(expand(""), 0) -+ au BufReadCmd tarfile::*/* call tar#Read(expand("")) -+ au FileReadCmd tarfile::*/* call tar#Read(expand("")) - au BufWriteCmd tarfile::*/* call tar#Write(expand("")) - au FileWriteCmd tarfile::*/* call tar#Write(expand("")) - endif - - diff --git a/backport-CVE-2025-53906.patch b/backport-CVE-2025-53906.patch deleted file mode 100644 index ab4243e..0000000 --- a/backport-CVE-2025-53906.patch +++ /dev/null @@ -1,236 +0,0 @@ -From 586294a04179d855c3d1d4ee5ea83931963680b8 Mon Sep 17 00:00:00 2001 -From: Christian Brabandt -Date: Tue, 15 Jul 2025 21:43:01 +0200 -Subject: [PATCH] patch 9.1.1551: [security]: path traversal issue in zip.vim - -Problem: [security]: path traversal issue in zip.vim (@ax) -Solution: drop leading ../ on write of zipfiles, don't forcefully - overwrite existing files - -A zip plugin which contains filenames with leading '../' may cause -confusion as to where the content will be extracted. Let's drop such -things and make sure we use a relative filename instead and don't -forcefully overwrite temporary files. Also, warn the user of such -things. - -related: #17733 - -Signed-off-by: Christian Brabandt ---- - runtime/autoload/zip.vim | 94 ++++++++++++++++++++++------------------ - runtime/doc/pi_zip.txt | 14 +++++- - 2 files changed, 64 insertions(+), 44 deletions(-) - -diff --git a/runtime/autoload/zip.vim b/runtime/autoload/zip.vim -index dae4ddeb9921ee..c46ec4470836ce 100644 ---- a/runtime/autoload/zip.vim -+++ b/runtime/autoload/zip.vim -@@ -15,6 +15,7 @@ - " 2024 Aug 18 by Vim Project: correctly handle special globbing chars - " 2024 Aug 21 by Vim Project: simplify condition to detect MS-Windows - " 2025 Mar 11 by Vim Project: handle filenames with leading '-' correctly -+" 2025 Jul 12 by Vim Project: drop ../ on write to prevent path traversal attacks - " License: Vim License (see vim's :help license) - " Copyright: Copyright (C) 2005-2019 Charles E. Campbell {{{1 - " Permission is hereby granted to use and distribute this code, -@@ -236,59 +237,62 @@ endfun - " zip#Write: {{{2 - fun! zip#Write(fname) - let dict = s:SetSaneOpts() -+ let need_rename = 0 - defer s:RestoreOpts(dict) - - " sanity checks - if !executable(substitute(g:zip_zipcmd,'\s\+.*$','','')) -- call s:Mess('Error', "***error*** (zip#Write) sorry, your system doesn't appear to have the ".g:zip_zipcmd." program") -- return -- endif -- if !exists("*mkdir") -- call s:Mess('Error', "***error*** (zip#Write) sorry, mkdir() doesn't work on your system") -- return -+ call s:Mess('Error', "***error*** (zip#Write) sorry, your system doesn't appear to have the ".g:zip_zipcmd." program") -+ return - endif - - let curdir= getcwd() - let tmpdir= tempname() - if tmpdir =~ '\.' -- let tmpdir= substitute(tmpdir,'\.[^.]*$','','e') -+ let tmpdir= substitute(tmpdir,'\.[^.]*$','','e') - endif - call mkdir(tmpdir,"p") - - " attempt to change to the indicated directory - if s:ChgDir(tmpdir,s:ERROR,"(zip#Write) cannot cd to temporary directory") -- return -+ return - endif - - " place temporary files under .../_ZIPVIM_/ - if isdirectory("_ZIPVIM_") -- call delete("_ZIPVIM_", "rf") -+ call delete("_ZIPVIM_", "rf") - endif - call mkdir("_ZIPVIM_") - cd _ZIPVIM_ - - if has("unix") -- let zipfile = substitute(a:fname,'zipfile://\(.\{-}\)::[^\\].*$','\1','') -- let fname = substitute(a:fname,'zipfile://.\{-}::\([^\\].*\)$','\1','') -+ let zipfile = substitute(a:fname,'zipfile://\(.\{-}\)::[^\\].*$','\1','') -+ let fname = substitute(a:fname,'zipfile://.\{-}::\([^\\].*\)$','\1','') - else -- let zipfile = substitute(a:fname,'^.\{-}zipfile://\(.\{-}\)::[^\\].*$','\1','') -- let fname = substitute(a:fname,'^.\{-}zipfile://.\{-}::\([^\\].*\)$','\1','') -+ let zipfile = substitute(a:fname,'^.\{-}zipfile://\(.\{-}\)::[^\\].*$','\1','') -+ let fname = substitute(a:fname,'^.\{-}zipfile://.\{-}::\([^\\].*\)$','\1','') -+ endif -+ if fname =~ '^[.]\{1,2}/' -+ call system(g:zip_zipcmd." -d ".s:Escape(fnamemodify(zipfile,":p"),0)." ".s:Escape(fname,0)) -+ let fname = fname->substitute('^\([.]\{1,2}/\)\+', '', 'g') -+ let need_rename = 1 - endif - - if fname =~ '/' -- let dirpath = substitute(fname,'/[^/]\+$','','e') -- if has("win32unix") && executable("cygpath") -+ let dirpath = substitute(fname,'/[^/]\+$','','e') -+ if has("win32unix") && executable("cygpath") - let dirpath = substitute(system("cygpath ".s:Escape(dirpath,0)),'\n','','e') -- endif -- call mkdir(dirpath,"p") -+ endif -+ call mkdir(dirpath,"p") - endif - if zipfile !~ '/' -- let zipfile= curdir.'/'.zipfile -+ let zipfile= curdir.'/'.zipfile - endif - -- exe "w! ".fnameescape(fname) -+ " don't overwrite files forcefully -+ exe "w ".fnameescape(fname) - if has("win32unix") && executable("cygpath") -- let zipfile = substitute(system("cygpath ".s:Escape(zipfile,0)),'\n','','e') -+ let zipfile = substitute(system("cygpath ".s:Escape(zipfile,0)),'\n','','e') - endif - - if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$' -@@ -297,21 +301,24 @@ fun! zip#Write(fname) - - call system(g:zip_zipcmd." -u ".s:Escape(fnamemodify(zipfile,":p"),0)." ".s:Escape(fname,0)) - if v:shell_error != 0 -- call s:Mess('Error', "***error*** (zip#Write) sorry, unable to update ".zipfile." with ".fname) -+ call s:Mess('Error', "***error*** (zip#Write) sorry, unable to update ".zipfile." with ".fname) - - elseif s:zipfile_{winnr()} =~ '^\a\+://' -- " support writing zipfiles across a network -- let netzipfile= s:zipfile_{winnr()} -- 1split|enew -- let binkeep= &binary -- let eikeep = &ei -- set binary ei=all -- exe "noswapfile e! ".fnameescape(zipfile) -- call netrw#NetWrite(netzipfile) -- let &ei = eikeep -- let &binary = binkeep -- q! -- unlet s:zipfile_{winnr()} -+ " support writing zipfiles across a network -+ let netzipfile= s:zipfile_{winnr()} -+ 1split|enew -+ let binkeep= &binary -+ let eikeep = &ei -+ set binary ei=all -+ exe "noswapfile e! ".fnameescape(zipfile) -+ call netrw#NetWrite(netzipfile) -+ let &ei = eikeep -+ let &binary = binkeep -+ q! -+ unlet s:zipfile_{winnr()} -+ elseif need_rename -+ exe $"sil keepalt file {fnameescape($"zipfile://{zipfile}::{fname}")}" -+ call s:Mess('Warning', "***error*** (zip#Browse) Path Traversal Attack detected, dropping relative path") - endif - - " cleanup and restore current directory -@@ -320,7 +327,6 @@ fun! zip#Write(fname) - call s:ChgDir(curdir,s:WARNING,"(zip#Write) unable to return to ".curdir."!") - call delete(tmpdir, "rf") - setlocal nomod -- - endfun - - " --------------------------------------------------------------------- -@@ -333,15 +339,18 @@ fun! zip#Extract() - - " sanity check - if fname =~ '^"' -- return -+ return - endif - if fname =~ '/$' -- call s:Mess('Error', "***error*** (zip#Extract) Please specify a file, not a directory") -- return -+ call s:Mess('Error', "***error*** (zip#Extract) Please specify a file, not a directory") -+ return -+ elseif fname =~ '^[.]\?[.]/' -+ call s:Mess('Error', "***error*** (zip#Browse) Path Traversal Attack detected, not extracting!") -+ return - endif - if filereadable(fname) -- call s:Mess('Error', "***error*** (zip#Extract) <" .. fname .."> already exists in directory, not overwriting!") -- return -+ call s:Mess('Error', "***error*** (zip#Extract) <" .. fname .."> already exists in directory, not overwriting!") -+ return - endif - let target = fname->substitute('\[', '[[]', 'g') - " unzip 6.0 does not support -- to denote end-of-arguments -@@ -363,13 +372,12 @@ fun! zip#Extract() - " extract the file mentioned under the cursor - call system($"{g:zip_extractcmd} -o {shellescape(b:zipfile)} {target}") - if v:shell_error != 0 -- call s:Mess('Error', "***error*** ".g:zip_extractcmd." ".b:zipfile." ".fname.": failed!") -+ call s:Mess('Error', "***error*** ".g:zip_extractcmd." ".b:zipfile." ".fname.": failed!") - elseif !filereadable(fname) -- call s:Mess('Error', "***error*** attempted to extract ".fname." but it doesn't appear to be present!") -+ call s:Mess('Error', "***error*** attempted to extract ".fname." but it doesn't appear to be present!") - else -- echomsg "***note*** successfully extracted ".fname -+ echomsg "***note*** successfully extracted ".fname - endif -- - endfun - - " --------------------------------------------------------------------- -diff --git a/runtime/doc/pi_zip.txt b/runtime/doc/pi_zip.txt -index afc2d0e..0f7ef4e 100644 ---- a/runtime/doc/pi_zip.txt -+++ b/runtime/doc/pi_zip.txt -@@ -1,4 +1,4 @@ --*pi_zip.txt* For Vim version 9.1. Last change: 2025 Apr 02 -+*pi_zip.txt* For Vim version 9.1. Last change: 2025 Jul 15 - - +====================+ - | Zip File Interface | -@@ -111,6 +111,18 @@ Copyright: Copyright (C) 2005-2015 Charles E Campbell *zip-copyright* - - ============================================================================== - 4. History *zip-history* {{{1 -+ unreleased: -+ Jul 12, 2025 * drop ../ on write to prevent path traversal attacks -+ Mar 11, 2025 * handle filenames with leading '-' correctly -+ Aug 21, 2024 * simplify condition to detect MS-Windows -+ Aug 18, 2024 * correctly handle special globbing chars -+ Aug 05, 2024 * clean-up and make it work with shellslash on Windows -+ Aug 05, 2024 * workaround for the FreeBSD's unzip -+ Aug 04, 2024 * escape '[' in name of file to be extracted -+ Jul 30, 2024 * fix opening remote zipfile -+ Jul 24, 2024 * use delete() function -+ Jul 23, 2024 * fix 'x' command -+ Jun 16, 2024 * handle whitespace on Windows properly (#14998) - v33 Dec 07, 2021 * *.xlam mentioned twice in zipPlugin - v32 Oct 22, 2021 * to avoid an issue with a vim 8.2 patch, zipfile: has - been changed to zipfile:// . This often shows up - - diff --git a/v9.1.1546.tar.gz b/v9.1.1623.tar.gz similarity index 32% rename from v9.1.1546.tar.gz rename to v9.1.1623.tar.gz index 2a3c282..dee2727 100644 --- a/v9.1.1546.tar.gz +++ b/v9.1.1623.tar.gz @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a7e088b7d4cbbf2850d852883e971b51de1c6b790ff118f8bd417c4ea3009a48 -size 18677802 +oid sha256:315721807e467726cf1d6848f09c9b37216d33b7b37ec2b70b8a00fa080948be +size 18748047 diff --git a/vim.spec b/vim.spec index 59c00e3..62acbbd 100644 --- a/vim.spec +++ b/vim.spec @@ -4,13 +4,13 @@ %{!?_with_netbeans__:%define _with_netbeans__ 1} %define baseversion 9.1 -%define patchlevel 1546 +%define patchlevel 1623 %define vimdir vim91 Name: vim Epoch: 2 Version: %{baseversion}.%{patchlevel} -Release: 2 +Release: 1 Summary: Vim is a highly configurable text editor for efficiently creating and changing any kind of text. License: Vim AND LGPL-2.1-or-later AND MIT AND GPL-1.0-only AND (GPL-2.0-only OR Vim) AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND GPL-2.0-or-later AND GPL-3.0-or-later AND OPUBL-1.0 AND Apache-2.0 WITH Swift-exception URL: https://www.vim.org @@ -24,8 +24,6 @@ Patch0002: vim-8.0-copy-paste.patch Patch0003: vim-python3-tests.patch Patch0005: bugfix-rm-modify-info-version.patch Patch0006: vim-Add-sw64-architecture-debcontrol.patch -Patch0007: backport-CVE-2025-53906.patch -Patch0008: backport-CVE-2025-53905.patch BuildRequires: autoconf python3-devel ncurses-devel gettext perl-devel perl-generators gcc BuildRequires: perl(ExtUtils::Embed) perl(ExtUtils::ParseXS) libacl-devel gpm-devel file @@ -428,6 +426,9 @@ LC_ALL=en_US.UTF-8 make -j1 test || echo "Warning: Please check tests." %{_mandir}/man1/evim.* %changelog +* Tue Aug 12 2025 Funda Wang - 2:9.1.1623-1 +- update to 9.1 patchlevel 1623 + * Wed Jul 23 2025 wangjiang - 2:9.1.1546-2 - fix CVE-2025-53905 CVE-2025-53906 -- Gitee