From: Christian Brabandt Date: Sun, 3 May 2026 16:10:03 +0000 (+0000) Subject: patch 9.2.0435: [security]: backticks in 'path' may cause shell execution on completion X-Git-Tag: v9.2.0435^0 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=190cb3c2b9c769a3972bcfd991a7b5b6cb771ef0;p=thirdparty%2Fvim.git 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. Signed-off-by: Christian Brabandt --- diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 7e1d4cb67e..4628a1624c 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -1,4 +1,4 @@ -*options.txt* For Vim version 9.2. Last change: 2026 May 01 +*options.txt* For Vim version 9.2. Last change: 2026 May 03 VIM REFERENCE MANUAL by Bram Moolenaar @@ -6799,6 +6799,9 @@ A jump table for the options with a short description can be found at |Q_op|. < Replace the ';' with a ':' or whatever separator is used. Note that this doesn't work when $INCL contains a comma or white space. + This option cannot be set from a |modeline| or in the |sandbox|, for + security reasons. + *'perldll'* 'perldll' string (default depends on the build) global diff --git a/src/findfile.c b/src/findfile.c index ed0ee76c49..af9523dcda 100644 --- a/src/findfile.c +++ b/src/findfile.c @@ -2412,6 +2412,10 @@ expand_path_option( { 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]))) { size_t plen; diff --git a/src/optiondefs.h b/src/optiondefs.h index 0a93b70f8e..f712ab7a14 100644 --- a/src/optiondefs.h +++ b/src/optiondefs.h @@ -1958,7 +1958,7 @@ static struct vimoption options[] = (char_u *)&p_pm, PV_NONE, did_set_backupext_or_patchmode, NULL, {(char_u *)"", (char_u *)0L} SCTX_INIT}, - {"path", "pa", P_STRING|P_EXPAND|P_VI_DEF|P_COMMA|P_NODUP, + {"path", "pa", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE|P_COMMA|P_NODUP, (char_u *)&p_path, PV_PATH, NULL, NULL, { #if defined(AMIGA) || defined(MSWIN) diff --git a/src/testdir/test_find_complete.vim b/src/testdir/test_find_complete.vim index 079fb78043..8b8b71c303 100644 --- a/src/testdir/test_find_complete.vim +++ b/src/testdir/test_find_complete.vim @@ -161,4 +161,21 @@ func Test_find_complete() 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 diff --git a/src/testdir/test_modeline.vim b/src/testdir/test_modeline.vim index 6884ab473d..6cbf87638a 100644 --- a/src/testdir/test_modeline.vim +++ b/src/testdir/test_modeline.vim @@ -665,4 +665,18 @@ func Test_modeline_strict_cannot_be_set_from_modeline() let &modeline = modeline 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 diff --git a/src/version.c b/src/version.c index 6d8157e4aa..2691f438b0 100644 --- a/src/version.c +++ b/src/version.c @@ -729,6 +729,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 435, /**/ 434, /**/