vim-patch:9.2.0435: [security]: backticks in 'path' may cause shell execution on completion

Problem:  [security]: Backticks enclosed shell commands in the 'path'
          option value are executed during completion (q1uf3ng).
Solution: Skip path entries containing backticks, add P_SECURE to 'path'
          option, so that it cannot be set from a modeline (for symmetry with
          the 'cdpath' option)

Github Advisory:
https://github.com/vim/vim/security/advisories/GHSA-hwg5-3cxw-wvvg

Supported by AI.

https://github.com/vim/vim/commit/190cb3c2b9c769a3972bcfd991a7b5b6cb771ef0

Co-authored-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
zeertzjq
2026-05-06 07:18:45 +08:00
parent d0582fcc74
commit b06f8b174f
5 changed files with 41 additions and 2 deletions
+1
View File
@@ -4806,6 +4806,7 @@ A jump table for the options with a short description can be found at |Q_op|.
*'path'* *'pa'* *E343* *E345* *E347* *E854*
'path' 'pa' string (default ".,,")
global or local to buffer |global-local|
Disallowed in |modeline|. |no-modeline-option|
This is a list of directories which will be searched when using the
|gf|, [f, ]f, ^Wf, |:find|, |:sfind|, |:tabfind| and other commands,
provided that the file being searched for has a relative path (not
+1
View File
@@ -6556,6 +6556,7 @@ local options = {
full_name = 'path',
list = 'comma',
scope = { 'global', 'buf' },
secure = true,
short_desc = N_('list of directories searched with "gf" et.al.'),
tags = { 'E343', 'E345', 'E347', 'E854' },
type = 'string',
+5
View File
@@ -898,6 +898,11 @@ static void expand_path_option(char *curdir, char *path_option, garray_T *gap)
while (*path_option != NUL) {
size_t buflen = copy_option_part(&path_option, buf, MAXPATHL, " ,");
// do not expand backticks, could have been set via a modeline
if (vim_strchr(buf, '`') != NULL) {
continue;
}
if (buf[0] == '.' && (buf[1] == NUL || vim_ispathsep(buf[1]))) {
// Relative to current buffer:
// "/path/file" + "." -> "/path/"
+20 -2
View File
@@ -10,7 +10,7 @@ func Test_find_complete()
call delete("Xfind", "rf")
let cwd = getcwd()
let test_out = cwd . '/test.out'
call mkdir('Xfind')
call mkdir('Xfind', 'R')
cd Xfind
new
@@ -158,6 +158,24 @@ func Test_find_complete()
enew | only
call chdir(cwd)
call delete('Xfind', 'rf')
set path&
endfunc
" Verify that backticks in 'path' are not executed
func Test_find_completion_backtick_in_path()
CheckUnix
CheckExecutable id
new Xpoc.c
setl path+=`id>Xrce_marker`
" Triggering completion must not execute the backtick command.
call getcompletion('', 'file_in_path')
call assert_false(filereadable('Xrce_marker'))
call feedkeys(":find \t\n", "xt")
call assert_false(filereadable('Xrce_marker'))
bwipe!
call delete('Xrce_marker')
endfunc
" vim: shiftwidth=2 sts=2 expandtab
+14
View File
@@ -559,4 +559,18 @@ func Test_modeline_nowrap_lcs_extends()
set equalalways&
endfunc
" Verify that backticks in 'path' set from a modeline are not executed
func Test_path_modeline()
let lines =<< trim END
// vim: set path+=foobar :
END
call writefile(lines, 'Xpoc.c', 'D')
set nomodelinestrict modeline
call assert_fails('split Xpoc.c', 'E520:')
bwipe!
set modelinestrict& modeline&
endfunc
" vim: shiftwidth=2 sts=2 expandtab