Bug 455023

Summary: vim: command execution due to insufficient input sanitation in netrw
Product: [Other] Security Response Reporter: Tomas Hoger <thoger>
Component: vulnerabilityAssignee: Red Hat Product Security <security-response-team>
Status: CLOSED DUPLICATE QA Contact:
Severity: low Docs Contact:
Priority: low    
Version: unspecifiedCC: jlieskov, karsten
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2008-10-27 12:37:05 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 453544, 453545    
Bug Blocks:    
Attachments:
Description Flags
Jan Minar's test suite none

Description Tomas Hoger 2008-07-11 14:46:45 UTC
Jan Minar published a follow-up to his previous advisory related to multiple
command execution flaws due to an insufficient file name sanitation in multiple
vim scripts.  His new advisory describes new issues affecting netrw.vim script.

  http://www.rdancer.org/vulnerablevim-netrw.html

Previous advisory is tracked via bug bug #451759 and is available at:

  http://www.rdancer.org/vulnerablevim.html

Additional references:
http://www.openwall.com/lists/oss-security/2008/07/07/1
http://www.openwall.com/lists/oss-security/2008/07/07/2

Comment 1 Tomas Hoger 2008-07-11 14:51:05 UTC
Created attachment 311589 [details]
Jan Minar's test suite

Downloaded from: http://www.rdancer.org/vulnerablevim-netrw.tar.bz2
At: Fri Jul 11 14:48:38 UTC 2008

Comment 2 Tomas Hoger 2008-07-11 15:00:16 UTC
Problems 1. and 2. as described in -netrw advisory (affecting mz and mc
commands) only affect netrw plugin as shipped with vim 7.1 alpha.

Problem 3. (affecting D command) affects vim 7.1 and possibly previous versions.

Furthermore, user needs to perform certain actions (running one of the affected
commands) for the malicious command to be executed.  Opening a file with
specially crafted name is not sufficient to exploit this flaw.

Comment 3 Tomas Hoger 2008-07-15 15:10:41 UTC
Correction to comment #2, first paragraph should be:

Problems 1. and 2. as described in -netrw advisory (affecting mz and mc
commands) only affect netrw plugin as shipped with vim 7.2 alpha.

(i.e. 7.2 alpha, not 7.1 alpha)

Comment 4 Jan Lieskovsky 2008-10-17 15:03:11 UTC
Problem #3 -- "Deleting Files (The ``D'' Command)" was moved to BZ#467439,
as it affects the same version of the Vim package (i.e. Vim 7.0 and Vim 7.1)
as the netrw.v5 issue. This bug is now only for tracking purposes.

The first two problems i.e "1. Compression and Decompression (The ``mz'' Command)" and "3.3. Copying Files (The ``mc'' Command)" affect the 7.2
version of the Vim package and versions of netrw.vim plugin before 132.
Current version of netrw.vim plugin in Fedora rawhide is 132, so this problem
fixed already.

Comment 5 Jan Lieskovsky 2008-10-27 11:39:50 UTC
Attaching netrw.vim plugin code differences between versions v.111 and v.132
for the 'mz' command issue (the relevant affected code function is NetrwMarkFileCompress()):

netrw.vim 111:

   2705     for sfx in sort(keys(g:netrw_decompress))
   2706      if fname =~ '\'.sfx.'$'
   2707       " fname has a suffix indicating that its compressed; apply associated decompression routine
   2708       let exe= g:netrw_decompress[sfx]
   2709 "      call Decho("fname<".fname."> is compressed so decompress with <".exe.">")
   2710       if executable(exe)
   2711        if a:islocal
   2712         call system(exe." ".fname)
   2713        else
   2714         call s:RemoteSystem(exe." ".fname)
   2715        endif
   2716       else
   2717        call netrw#ErrorMsg(s:WARNING,"unable to apply<".exe."> to file<".fname.">",50)
   2718       endif
   2719       break
   2720      endif
   2721     endfor
   2722     if exists("exe")
   2723      unlet exe
   2724     elseif a:islocal
   2725      " fname not a compressed file, so compress it
   2726      call system(g:netrw_compress." ".fname)
   2727     else
   2728      " fname not a compressed file, so compress it
   2729      call s:RemoteSystem(g:netrw_compress." ".fname)
   2730     endif
   2731    endfor

netrw.v132: 

   3858     for sfx in sort(keys(g:netrw_decompress))
   3859      if fname =~ '\'.sfx.'$'
   3860       " fname has a suffix indicating that its compressed; apply associated decompression routine
   3861       let exe= s:WinPath(g:netrw_decompress[sfx])
   3862 "      call Decho("fname<".fname."> is compressed so decompress with <".exe.">")
   3863       if a:islocal
   3864        if g:netrw_keepdir
   3865         let fname= shellescape(s:ComposePath(curdir,fname))
   3866        endif
   3867       else
   3868        let fname= shellescape(b:netrw_curdir.fname,1)
   3869       endif
   3870       if executable(exe)
   3871        if a:islocal
   3872         call system(exe." ".fname)
   3873        else
   3874         call s:RemoteSystem(exe." ".fname)
   3875        endif
   3876       else
   3877        call netrw#ErrorMsg(s:WARNING,"unable to apply<".exe."> to file<".fname.">",50)
   3878       endif
   3879       break
   3880      endif
   3881     endfor
   3882     if exists("exe")
   3883      unlet exe
   3884     elseif a:islocal
   3885      " fname not a compressed file, so compress it
   3886      call system(s:WinPath(g:netrw_compress)." ".shellescape(s:ComposePath(b:netrw_curdir,fname)))
   3887     else
   3888      " fname not a compressed file, so compress it
   3889      call s:RemoteSystem(s:WinPath(g:netrw_compress)." ".shellescape(fname))
   3890     endif
   3891    endfor


i.e. on Unix systems, the calls for "s:ComposePath(b:netrw_curdir,fname"
and "fname" were prefixed with "shellescape(s:ComposePath(b:netrw_curdir,fname)"
and "shellescape(fname)" respectively.

Comment 6 Jan Lieskovsky 2008-10-27 11:46:54 UTC
Attaching netrw.vim plugin code differences between versions v.122 and v.132
for the 'mc' command issue (the relevant affected function is called
NetrwMarkFileCopy):

netrw.v122:

3760      if  a:islocal &&  s:netrwmfloc
3761       " local to local copy
3762 "      call Decho("local to local copy: from b:netrw_curdir<".b:netrw_curdir."> fname<".fname."> to s:netrwmftgt<".s:netrwmftgt.">")
3763       if executable(g:netrw_localcopycmd)
3764 "       call Decho("let ret= system(".g:netrw_localcopycmd." ".s:ComposePath(b:netrw_curdir,fname)." ".s:netrwmftgt.")")
3765        let ret= system(g:netrw_localcopycmd." ".s:ComposePath(curdir,fname)." ".s:netrwmftgt)
3766        if v:shell_error < 0
3767         call netrw#ErrorMsg(s:ERROR,"command<".g:netrw_localcopycmd."> failed, aborting",54)
3768         break
3769        endif
3770       else
3771        call netrw#ErrorMsg(s:ERROR,"command<".g:netrw_localcopycmd."> is not executable!",57)
3772        break
3773       endif

netrw.v132:

   3925   if      a:islocal &&  s:netrwmftgt_islocal
   3926    " Copy marked files, local directory to local directory
   3927 "   call Decho("copy from local to local")
   3928    let args= join(map(deepcopy(s:netrwmarkfilelist_{bufnr('%')}),"shellescape(b:netrw_curdir.\"/\".v:val)"))
   3929 "   call Decho("system(".g:netrw_localcopycmd." ".args." ".shellescape(s:netrwmftgt).")")
   3930    call system(s:WinPath(g:netrw_localcopycmd)." ".args." ".shellescape(s:netrwmftgt))
   3931 

i.e. the relevant functions were replaced by their 'shellescape()-ed' 
alternatives.

Comment 7 Jan Lieskovsky 2008-10-27 11:53:45 UTC
Attaching netrw.vim code differences for the 'D' command issue between versions
netrw.vim v.122 and netrw.vim v.132 - the relevant affected code function
is called NetrwLocalRmFile:

netrw.v122:

6255    if all || ok =~ 'y\%[es]' || ok == ""
6256 "     call Decho("1st attempt: system(".g:netrw_local_rmdir.' "'.rmfile.'")')
6257     call s:System("system",g:netrw_local_rmdir.' "'.rmfile.'"')
6258 "     call Decho("v:shell_error=".v:shell_error)

netrw.v132: 

   6817    if all || ok =~ 'y\%[es]' || ok == ""
   6818 "    call Decho("1st attempt: system(s:WinPath(".g:netrw_local_rmdir.') '.shellescape(rmfile).')')
   6819     call system(s:WinPath(g:netrw_local_rmdir).' '.shellescape(rmfile))
   6820 "    call Decho("v:shell_error=".v:shell_error)

i.e. provided 'rmfile' argument was replaced with its shellescape()-ed alternative.

Comment 8 Jan Lieskovsky 2008-10-27 12:01:39 UTC
Attaching netrw.vim code differences for the 'arbitrary code execution
due insufficient directory name sanitization when opening directory'
(http://www.rdancer.org/vulnerablevim-netrw.v5.html) between versions
v.122 and v.132 -- the relevant affected code function is called BrowserMaps().

netrw.v122:

1709    if g:netrw_mousemaps == 1
1710     nnoremap <buffer> <silent> <leftmouse>   <leftmouse>:call <SID>NetrwLeftmouse(1)<cr>
1711     nnoremap <buffer> <silent> <middlemouse> <leftmouse>:call <SID>NetrwPrevWinOpen(1)<cr>
1712     nnoremap <buffer> <silent> <s-leftmouse> <leftmouse>:call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr>
1713     exe 'nnoremap <buffer> <silent> <rightmouse>  <leftmouse>:call <SID>NetrwLocalRm("'.b:netrw_curdir.'")<cr>'
1714     exe 'vnoremap <buffer> <silent> <rightmouse>  <leftmouse>:call <SID>NetrwLocalRm("'.b:netrw_curdir.'")<cr>'
1715    endif
1716    exe 'nnoremap <buffer> <silent> <del>        :call <SID>NetrwLocalRm("'.b:netrw_curdir.'")<cr>'
1717    exe 'vnoremap <buffer> <silent> <del>        :call <SID>NetrwLocalRm("'.b:netrw_curdir.'")<cr>'
1718    exe 'nnoremap <buffer> <silent> D            :call <SID>NetrwLocalRm("'.b:netrw_curdir.'")<cr>'
1719    exe 'vnoremap <buffer> <silent> D            :call <SID>NetrwLocalRm("'.b:netrw_curdir.'")<cr>'
1720    exe 'nnoremap <buffer> <silent> R            :call <SID>NetrwLocalRename("'.b:netrw_curdir.'")<cr>'
1721    exe 'vnoremap <buffer> <silent> R            :call <SID>NetrwLocalRename("'.b:netrw_curdir.'")<cr>'
1722    exe 'nnoremap <buffer> <silent> <Leader>m    :call <SID>NetrwMakeDir("")<cr>'
1723    nnoremap <buffer> <F1>               :he netrw-dir<cr>


netrv.v132: 

   1734    if g:netrw_mousemaps == 1
   1735     nnoremap <buffer> <silent> <leftmouse>   <leftmouse>:call <SID>NetrwLeftmouse(1)<cr>
   1736     nnoremap <buffer> <silent> <middlemouse> <leftmouse>:call <SID>NetrwPrevWinOpen(1)<cr>
   1737     nnoremap <buffer> <silent> <s-leftmouse> <leftmouse>:call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr>
   1738     exe 'nnoremap <buffer> <silent> <rightmouse>  <leftmouse>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
   1739     exe 'vnoremap <buffer> <silent> <rightmouse>  <leftmouse>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
   1740    endif
   1741    exe 'nnoremap <buffer> <silent> <del>        :call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
   1742    exe 'vnoremap <buffer> <silent> <del>        :call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
   1743    exe 'nnoremap <buffer> <silent> D            :call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
   1744    exe 'vnoremap <buffer> <silent> D            :call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
   1745    exe 'nnoremap <buffer> <silent> R            :call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
   1746    exe 'vnoremap <buffer> <silent> R            :call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
   1747    exe 'nnoremap <buffer> <silent> <Leader>m    :call <SID>NetrwMakeDir("")<cr>'
   1748    nnoremap <buffer> <F1>               :he netrw-quickhelp<cr>


i.e. instead of calling unsanitized NetrwLocalRm("'.b:netrw_curdir.'") we 
now call its more safe NetrwLocalRm("'.mapsafecurdir.'") alternative.

Comment 9 Jan Lieskovsky 2008-10-27 12:37:05 UTC

*** This bug has been marked as a duplicate of bug 467439 ***