From c084ab9f579115a53a4bc115a7f682e3a84c6d7e Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 1 Apr 2026 08:00:33 +0800 Subject: [PATCH] vim-patch:9.2.0276: [security]: modeline security bypass (#38657) Problem: [security]: modeline security bypass Solution: disallow mapset() from secure mode, set the P_MLE flag for the 'complete', 'guitabtooltip' and 'printheader' options. Github Advisory: https://github.com/vim/vim/security/advisories/GHSA-8h6p-m6gr-mpw9 https://github.com/vim/vim/commit/75661a66a1db1e1f3f1245c615f13a7de44c0587 Co-authored-by: Christian Brabandt (cherry picked from commit c7604323e30a235961c4a976e1c9cee20d4cfa52) --- src/nvim/mapping.c | 5 +++++ src/nvim/options.lua | 2 ++ test/old/testdir/test_modeline.vim | 25 +++++++++++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/src/nvim/mapping.c b/src/nvim/mapping.c index de48a27461..02a300f665 100644 --- a/src/nvim/mapping.c +++ b/src/nvim/mapping.c @@ -26,6 +26,7 @@ #include "nvim/eval/typval_defs.h" #include "nvim/eval/userfunc.h" #include "nvim/eval/vars.h" +#include "nvim/ex_cmds.h" #include "nvim/ex_cmds_defs.h" #include "nvim/ex_session.h" #include "nvim/fuzzy.h" @@ -2277,6 +2278,10 @@ static int get_map_mode_string(const char *const mode_string, const bool abbr) /// "mapset()" function void f_mapset(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { + if (check_secure()) { + return; + } + const char *which; char buf[NUMBUFLEN]; int is_abbr; diff --git a/src/nvim/options.lua b/src/nvim/options.lua index f7ded5639b..4f8e9d2599 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -1545,6 +1545,7 @@ local options = { (CTRL-N) and is ignored during backward completion (CTRL-P). ]=], full_name = 'complete', + modelineexpr = true, list = 'onecomma', scope = { 'buf' }, short_desc = N_('specify how Insert mode completion works'), @@ -4256,6 +4257,7 @@ local options = { < ]=], full_name = 'guitabtooltip', + modelineexpr = true, redraw = { 'current_window' }, scope = { 'global' }, short_desc = N_('GUI: custom tooltip for a tab page'), diff --git a/test/old/testdir/test_modeline.vim b/test/old/testdir/test_modeline.vim index 628c4770db..e1c3d362ee 100644 --- a/test/old/testdir/test_modeline.vim +++ b/test/old/testdir/test_modeline.vim @@ -503,4 +503,29 @@ func Test_modeline_nowrap_lcs_extends() set equalalways& endfunc +func Test_modeline_forbidden() + let tempfile = tempname() + let lines =<< trim END + some test text for completion + vim: set complete=F{->system('touch_should_not_run')} : + END + call writefile(lines, tempfile, 'D') + call assert_fails($'new {tempfile}', 'E992:') + bw! + let lines =<< trim END + some text + vim: set guitabtooltip=%{%mapset()%}: + END + call writefile(lines, tempfile) + call assert_fails($'new {tempfile}', 'E992:') + bw! + let lines =<< trim END + some text + vim: set printheader=%{mapset('n',0,{})%)%}: + END + call writefile(lines, tempfile, 'D') + "call assert_fails($'new {tempfile}', 'E992:') + bw! +endfunc + " vim: shiftwidth=2 sts=2 expandtab