Skip to content

Commit

Permalink
vim-patch:8.1.1366: using expressions in a modeline is unsafe
Browse files Browse the repository at this point in the history
Problem:    Using expressions in a modeline is unsafe.
Solution:   Disallow using expressions in a modeline, unless the
            'modelineexpr' option is set.  Update help, add more tests.
vim/vim@110289e
  • Loading branch information
jamessan committed Jun 24, 2019
1 parent 45bb175 commit 1e4673d
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 27 deletions.
79 changes: 61 additions & 18 deletions runtime/doc/options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -478,14 +478,17 @@ backslash in front of the ':' will be removed. Example:
/* vi:set dir=c\:\tmp: */ ~
This sets the 'dir' option to "c:\tmp". Only a single backslash before the
':' is removed. Thus to include "\:" you have to specify "\\:".

*E992*
No other commands than "set" are supported, for security reasons (somebody
might create a Trojan horse text file with modelines). And not all options
can be set. For some options a flag is set, so that when it's used the
|sandbox| is effective. Still, there is always a small risk that a modeline
causes trouble. E.g., when some joker sets 'textwidth' to 5 all your lines
are wrapped unexpectedly. So disable modelines before editing untrusted text.
The mail ftplugin does this, for example.
can be set. For some options a flag is set, so that when the value is used
the |sandbox| is effective. Some options can only be set from the modeline
when 'modelineexpr' is set (the default is off).

Still, there is always a small risk that a modeline causes trouble. E.g.,
when some joker sets 'textwidth' to 5 all your lines are wrapped unexpectedly.
So disable modelines before editing untrusted text. The mail ftplugin does
this, for example.

Hint: If you would like to do something else than setting an option, you could
define an autocommand that checks the file for a specific string. For
Expand Down Expand Up @@ -2427,7 +2430,7 @@ A jump table for the options with a short description can be found at |Q_op|.
The expression will be evaluated in the |sandbox| if set from a
modeline, see |sandbox-option|.
This option can't be set from a |modeline| when the 'diff' option is
on.
on or the 'modelineexpr' option is off.

It is not allowed to change text or jump to another window while
evaluating 'foldexpr' |textlock|.
Expand Down Expand Up @@ -2542,6 +2545,7 @@ A jump table for the options with a short description can be found at |Q_op|.

The expression will be evaluated in the |sandbox| if set from a
modeline, see |sandbox-option|.
This option cannot be set in a modeline when 'modelineexpr' is off.

It is not allowed to change text or jump to another window while
evaluating 'foldtext' |textlock|.
Expand Down Expand Up @@ -2577,16 +2581,8 @@ A jump table for the options with a short description can be found at |Q_op|.
The expression will be evaluated in the |sandbox| when set from a
modeline, see |sandbox-option|. That stops the option from working,
since changing the buffer text is not allowed.

*'formatoptions'* *'fo'*
'formatoptions' 'fo' string (default: "tcqj", Vi default: "vt")
local to buffer
This is a sequence of letters which describes how automatic
formatting is to be done. See |fo-table|. When the 'paste' option is
on, no formatting is done (like 'formatoptions' is empty). Commas can
be inserted for readability.
To avoid problems with flags that are added in the future, use the
"+=" and "-=" feature of ":set" |add-option-flags|.
This option cannot be set in a modeline when 'modelineexpr' is off.
NOTE: This option is set to "" when 'compatible' is set.

*'formatlistpat'* *'flp'*
'formatlistpat' 'flp' string (default: "^\s*\d\+[\]:.)}\t ]\s*")
Expand All @@ -2601,6 +2597,16 @@ A jump table for the options with a short description can be found at |Q_op|.
The default recognizes a number, followed by an optional punctuation
character and white space.

*'formatoptions'* *'fo'*
'formatoptions' 'fo' string (default: "tcqj", Vi default: "vt")
local to buffer
This is a sequence of letters which describes how automatic
formatting is to be done. See |fo-table|. When the 'paste' option is
on, no formatting is done (like 'formatoptions' is empty). Commas can
be inserted for readability.
To avoid problems with flags that are added in the future, use the
"+=" and "-=" feature of ":set" |add-option-flags|.

*'formatprg'* *'fp'*
'formatprg' 'fp' string (default "")
global or local to buffer |global-local|
Expand Down Expand Up @@ -2631,6 +2637,9 @@ A jump table for the options with a short description can be found at |Q_op|.
- system signals low battery life
- Nvim exits abnormally

This option cannot be set from a |modeline| or in the |sandbox|, for
security reasons.

*'gdefault'* *'gd'* *'nogdefault'* *'nogd'*
'gdefault' 'gd' boolean (default off)
global
Expand Down Expand Up @@ -2972,6 +2981,7 @@ A jump table for the options with a short description can be found at |Q_op|.
'guitabtooltip' is used for the tooltip, see below.
The expression will be evaluated in the |sandbox| when set from a
modeline, see |sandbox-option|.
This option cannot be set in a modeline when 'modelineexpr' is off.

Only used when the GUI tab pages line is displayed. 'e' must be
present in 'guioptions'. For the non-GUI tab pages line 'tabline' is
Expand Down Expand Up @@ -3100,6 +3110,7 @@ A jump table for the options with a short description can be found at |Q_op|.
When this option contains printf-style '%' items, they will be
expanded according to the rules used for 'statusline'. See
'titlestring' for example settings.
This option cannot be set in a modeline when 'modelineexpr' is off.

*'ignorecase'* *'ic'* *'noignorecase'* *'noic'*
'ignorecase' 'ic' boolean (default off)
Expand Down Expand Up @@ -3203,6 +3214,7 @@ A jump table for the options with a short description can be found at |Q_op|.

The expression will be evaluated in the |sandbox| when set from a
modeline, see |sandbox-option|.
This option cannot be set in a modeline when 'modelineexpr' is off.

It is not allowed to change text or jump to another window while
evaluating 'includeexpr' |textlock|.
Expand Down Expand Up @@ -3271,6 +3283,7 @@ A jump table for the options with a short description can be found at |Q_op|.

The expression will be evaluated in the |sandbox| when set from a
modeline, see |sandbox-option|.
This option cannot be set in a modeline when 'modelineexpr' is off.

It is not allowed to change text or jump to another window while
evaluating 'indentexpr' |textlock|.
Expand Down Expand Up @@ -3777,6 +3790,12 @@ A jump table for the options with a short description can be found at |Q_op|.
< This option cannot be set from a |modeline| or in the |sandbox|, for
security reasons.

*'makespellmem'* *'msm'*
'makespellmem' 'msm' string (default "460000,2000,500")
global
Values relevant only when compressing a spell file, see |spell|.
This option cannot be set from a |modeline| or in the |sandbox|.

*'matchpairs'* *'mps'*
'matchpairs' 'mps' string (default "(:),{:},[:]")
local to buffer
Expand Down Expand Up @@ -3892,6 +3911,17 @@ A jump table for the options with a short description can be found at |Q_op|.
'modeline' 'ml' boolean (Vim default: on (off for root),
Vi default: off)
local to buffer
If 'modeline' is on 'modelines' gives the number of lines that is
checked for set commands. If 'modeline' is off or 'modelines' is zero
no lines are checked. See |modeline|.

*'modelineexpr'* *'mle'* *'nomodelineexpr'* *'nomle'*
'modelineexpr' 'mle' boolean (default: off)
global
When on allow some options that are an expression to be set in the
modeline. Check the option for whether it is affected by
'modelineexpr'. Also see |modeline|.

*'modelines'* *'mls'*
'modelines' 'mls' number (default 5)
global
Expand Down Expand Up @@ -4668,6 +4698,8 @@ A jump table for the options with a short description can be found at |Q_op|.
When this option is not empty, it determines the content of the ruler
string, as displayed for the 'ruler' option.
The format of this option is like that of 'statusline'.
This option cannot be set in a modeline when 'modelineexpr' is off.

The default ruler width is 17 characters. To make the ruler 15
characters wide, put "%15(" at the start and "%)" at the end.
Example: >
Expand Down Expand Up @@ -5065,6 +5097,8 @@ A jump table for the options with a short description can be found at |Q_op|.
When equal to "NONE" no shada file will be read or written.
This option can be set with the |-i| command line flag. The |--clean|
command line flag sets it to "NONE".
This option cannot be set from a |modeline| or in the |sandbox|, for
security reasons.

*'shell'* *'sh'* *E91*
'shell' 'sh' string (default $SHELL or "sh",
Expand Down Expand Up @@ -5304,7 +5338,8 @@ A jump table for the options with a short description can be found at |Q_op|.
"Pattern not found", "Back at original", etc.
q use "recording" instead of "recording @a"
F don't give the file info when editing a file, like `:silent`
was used for the command
was used for the command; note that this also affects messages
from autocommands
S do not show search count message when searching, e.g.
"[1/5]"

Expand Down Expand Up @@ -5831,6 +5866,7 @@ A jump table for the options with a short description can be found at |Q_op|.

The 'statusline' option will be evaluated in the |sandbox| if set from
a modeline, see |sandbox-option|.
This option cannot be set in a modeline when 'modelineexpr' is off.

It is not allowed to change text or jump to another window while
evaluating 'statusline' |textlock|.
Expand Down Expand Up @@ -5985,6 +6021,8 @@ A jump table for the options with a short description can be found at |Q_op|.
the text to be displayed. Use "%1T" for the first label, "%2T" for
the second one, etc. Use "%X" items for closing labels.

This option cannot be set in a modeline when 'modelineexpr' is off.

Keep in mind that only one of the tab pages is the current one, others
are invisible and you can't jump to their windows.

Expand Down Expand Up @@ -6264,8 +6302,11 @@ A jump table for the options with a short description can be found at |Q_op|.
global
When this option is not empty, it will be used for the title of the
window. This happens only when the 'title' option is on.

When this option contains printf-style '%' items, they will be
expanded according to the rules used for 'statusline'.
This option cannot be set in a modeline when 'modelineexpr' is off.

Example: >
:auto BufEnter * let &titlestring = hostname() . "/" . expand("%:p")
:set title titlestring=%<%F%=%l/%L-%P titlelen=70
Expand Down Expand Up @@ -6299,6 +6340,8 @@ A jump table for the options with a short description can be found at |Q_op|.
undo file that exists is used. When it cannot be read an error is
given, no further entry is used.
See |undo-persistence|.
This option cannot be set from a |modeline| or in the |sandbox|, for
security reasons.

*'undofile'* *'noundofile'* *'udf'* *'noudf'*
'undofile' 'udf' boolean (default off)
Expand Down
1 change: 1 addition & 0 deletions src/nvim/generators/gen_options.lua
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ local get_flags = function(o)
{'pri_mkrc'},
{'deny_in_modelines', 'P_NO_ML'},
{'deny_duplicates', 'P_NODUP'},
{'modelineexpr', 'P_MLE'},
}) do
local key_name = flag_desc[1]
local def_name = flag_desc[2] or ('P_' .. key_name:upper())
Expand Down
6 changes: 6 additions & 0 deletions src/nvim/option.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ typedef struct vimoption {
#define P_RWINONLY 0x10000000U ///< only redraw current window
#define P_NDNAME 0x20000000U ///< only normal dir name chars allowed
#define P_UI_OPTION 0x40000000U ///< send option to remote ui
#define P_MLE 0x80000000U ///< under control of 'modelineexpr'

#define HIGHLIGHT_INIT \
"8:SpecialKey,~:EndOfBuffer,z:TermCursor,Z:TermCursorNC,@:NonText," \
Expand Down Expand Up @@ -1327,6 +1328,11 @@ int do_set(
errmsg = (char_u *)_("E520: Not allowed in a modeline");
goto skip;
}
if ((flags & P_MLE) && !p_mle) {
errmsg = (char_u *)_(
"E992: Not allowed in a modeline when 'modelineexpr' is off");
goto skip;
}
// In diff mode some options are overruled. This avoids that
// 'foldmethod' becomes "marker" instead of "diff" and that
// "wrap" gets set.
Expand Down
1 change: 1 addition & 0 deletions src/nvim/option_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,7 @@ EXTERN long p_mmd; // 'maxmapdepth'
EXTERN long p_mmp; // 'maxmempattern'
EXTERN long p_mis; // 'menuitems'
EXTERN char_u *p_msm; // 'mkspellmem'
EXTERN long p_mle; // 'modelineexpr'
EXTERN long p_mls; // 'modelines'
EXTERN char_u *p_mouse; // 'mouse'
EXTERN char_u *p_mousem; // 'mousemodel'
Expand Down
20 changes: 20 additions & 0 deletions src/nvim/options.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
-- defaults={condition=nil, if_true={vi=224, vim=0}, if_false=nil},
-- secure=nil, gettext=nil, noglob=nil, normal_fname_chars=nil,
-- pri_mkrc=nil, deny_in_modelines=nil, normal_dname_chars=nil,
-- modelineexpr=nil,
-- expand=nil, nodefault=nil, no_mkrc=nil, vi_def=true, vim=true,
-- alloced=nil,
-- save_pv_indir=nil,
Expand Down Expand Up @@ -283,6 +284,7 @@ return {
deny_duplicates=true,
vi_def=true,
expand=true,
secure=true,
varname='p_cdpath',
defaults={if_true={vi=",,"}}
},
Expand Down Expand Up @@ -847,6 +849,7 @@ return {
type='string', scope={'window'},
vi_def=true,
vim=true,
modelineexpr=true,
alloced=true,
redraw={'current_window'},
defaults={if_true={vi="0"}}
Expand Down Expand Up @@ -922,6 +925,7 @@ return {
type='string', scope={'window'},
vi_def=true,
vim=true,
modelineexpr=true,
alloced=true,
redraw={'current_window'},
defaults={if_true={vi="foldtext()"}}
Expand All @@ -931,6 +935,7 @@ return {
type='string', scope={'buffer'},
vi_def=true,
vim=true,
modelineexpr=true,
alloced=true,
varname='p_fex',
defaults={if_true={vi=""}}
Expand Down Expand Up @@ -1045,6 +1050,7 @@ return {
full_name='guitablabel', abbreviation='gtl',
type='string', scope={'global'},
vi_def=true,
modelineexpr=true,
redraw={'current_window'},
enable_if=false,
},
Expand Down Expand Up @@ -1136,6 +1142,7 @@ return {
full_name='iconstring',
type='string', scope={'global'},
vi_def=true,
modelineexpr=true,
varname='p_iconstring',
defaults={if_true={vi=""}}
},
Expand Down Expand Up @@ -1198,6 +1205,7 @@ return {
full_name='includeexpr', abbreviation='inex',
type='string', scope={'buffer'},
vi_def=true,
modelineexpr=true,
alloced=true,
varname='p_inex',
defaults={if_true={vi=""}}
Expand All @@ -1214,6 +1222,7 @@ return {
type='string', scope={'buffer'},
vi_def=true,
vim=true,
modelineexpr=true,
alloced=true,
varname='p_inde',
defaults={if_true={vi=""}}
Expand Down Expand Up @@ -1527,6 +1536,13 @@ return {
varname='p_ml',
defaults={if_true={vi=false, vim=true}}
},
{
full_name='modelineexpr', abbreviation='mle',
type='bool', scope={'global'},
vi_def=true,
varname='p_mle',
defaults={if_true={vi=false}}
},
{
full_name='modelines', abbreviation='mls',
type='number', scope={'global'},
Expand Down Expand Up @@ -1903,6 +1919,7 @@ return {
type='string', scope={'global'},
vi_def=true,
alloced=true,
modelineexpr=true,
redraw={'statuslines'},
varname='p_ruf',
defaults={if_true={vi=""}}
Expand Down Expand Up @@ -2310,6 +2327,7 @@ return {
type='string', scope={'global', 'window'},
vi_def=true,
alloced=true,
modelineexpr=true,
redraw={'statuslines'},
varname='p_stl',
defaults={if_true={vi=""}}
Expand Down Expand Up @@ -2369,6 +2387,7 @@ return {
full_name='tabline', abbreviation='tal',
type='string', scope={'global'},
vi_def=true,
modelineexpr=true,
redraw={'all_windows'},
varname='p_tal',
defaults={if_true={vi=""}}
Expand Down Expand Up @@ -2528,6 +2547,7 @@ return {
full_name='titlestring',
type='string', scope={'global'},
vi_def=true,
modelineexpr=true,
varname='p_titlestring',
defaults={if_true={vi=""}}
},
Expand Down
2 changes: 1 addition & 1 deletion src/nvim/testdir/test49.in
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ If after adding a new test, the test output doesn't appear properly in
test49.failed, try to add one or more "G"s at the line ending in "test.out"

STARTTEST
:se nomore
:se nomore modelineexpr
:lang mess C
:so test49.vim
:" Go back to this file and append the results from register r.
Expand Down
Loading

0 comments on commit 1e4673d

Please sign in to comment.