]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0435: [security]: backticks in 'path' may cause shell execution on completion v9.2.0435
authorChristian Brabandt <cb@256bit.org>
Sun, 3 May 2026 16:10:03 +0000 (16:10 +0000)
committerChristian Brabandt <cb@256bit.org>
Sun, 3 May 2026 18:17:02 +0000 (18:17 +0000)
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 <cb@256bit.org>
runtime/doc/options.txt
src/findfile.c
src/optiondefs.h
src/testdir/test_find_complete.vim
src/testdir/test_modeline.vim
src/version.c

index 7e1d4cb67ed9ad3db271312fd49d5015d56c394f..4628a1624c08108932ce79debbd5817db99f9b7a 100644 (file)
@@ -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
index ed0ee76c49a036c5bc36f999c3d06098b49f3712..af9523dcda9151525052015af56032d93bf2cd24 100644 (file)
@@ -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;
index 0a93b70f8ef82be9c4dccfbc1d0e5b59c665ca0f..f712ab7a14aec257e1b93667abb28b5f0db94f4d 100644 (file)
@@ -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)
index 079fb78043b461ea464d88e1e21cac24c46bf422..8b8b71c30301294379527d5c3d05278a7e512dd2 100644 (file)
@@ -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
index 6884ab473d7d2d5c5666905606c798ec080a41d8..6cbf87638a86173c3887e513c941a27d2e6bbae0 100644 (file)
@@ -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
index 6d8157e4aafd3ca56f6904fdfaabac8c8b9f4af4..2691f438b0bb0752b33ce8dbf3a2a24bfd3a487a 100644 (file)
@@ -729,6 +729,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    435,
 /**/
     434,
 /**/