mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-06-11 15:37:29 +02:00
patch 9.2.0400: sandbox callbacks selected through 'complete'
Problem: Modeline-tainted 'complete' values can invoke completion
callbacks outside the sandbox.
Solution: Enter the sandbox for both 'complete' callback phases and add
a regression test (Barrett Ruth)
closes: #20078
Signed-off-by: Barrett Ruth <br.barrettruth@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
a622dda915
commit
dd9b31fb62
@@ -3631,6 +3631,9 @@ expand_by_function(int type, char_u *base, callback_T *cb)
|
||||
int save_State = State;
|
||||
int retval;
|
||||
int is_cpt_function = (cb != NULL);
|
||||
int use_sandbox = is_cpt_function
|
||||
&& was_set_insecurely(curwin,
|
||||
(char_u *)"complete", OPT_LOCAL);
|
||||
|
||||
if (!is_cpt_function)
|
||||
{
|
||||
@@ -3652,8 +3655,12 @@ expand_by_function(int type, char_u *base, callback_T *cb)
|
||||
// switching to another window, it should not be needed and may end up in
|
||||
// Insert mode in another buffer.
|
||||
++textlock;
|
||||
if (use_sandbox)
|
||||
++sandbox;
|
||||
|
||||
retval = call_callback(cb, 0, &rettv, 2, args);
|
||||
if (use_sandbox)
|
||||
--sandbox;
|
||||
|
||||
// Call a function, which returns a list or dict.
|
||||
if (retval == OK)
|
||||
@@ -6760,6 +6767,9 @@ get_userdefined_compl_info(
|
||||
pos_T pos;
|
||||
int save_State = State;
|
||||
int is_cpt_function = (cb != NULL);
|
||||
int use_sandbox = is_cpt_function
|
||||
&& was_set_insecurely(curwin,
|
||||
(char_u *)"complete", OPT_LOCAL);
|
||||
|
||||
if (!is_cpt_function)
|
||||
{
|
||||
@@ -6782,7 +6792,11 @@ get_userdefined_compl_info(
|
||||
args[2].v_type = VAR_UNKNOWN;
|
||||
pos = curwin->w_cursor;
|
||||
++textlock;
|
||||
if (use_sandbox)
|
||||
++sandbox;
|
||||
col = call_callback_retnr(cb, 2, args);
|
||||
if (use_sandbox)
|
||||
--sandbox;
|
||||
--textlock;
|
||||
|
||||
State = save_State;
|
||||
|
||||
@@ -283,6 +283,61 @@ func Test_modeline_fails_modelineexpr()
|
||||
call s:modeline_fails('titlestring', 'titlestring=Something()', 'E992:')
|
||||
endfunc
|
||||
|
||||
func Test_modeline_complete_uses_sandbox()
|
||||
let modeline = &modeline
|
||||
let modelineexpr = &modelineexpr
|
||||
let modelinestrict = &modelinestrict
|
||||
|
||||
func! ModelineCompletePwnFindstart(findstart, base)
|
||||
if a:findstart
|
||||
call writefile(['findstart'], 'Xmodeline_complete_proof')
|
||||
return 0
|
||||
endif
|
||||
return ['match']
|
||||
endfunc
|
||||
|
||||
func! ModelineCompletePwnMatches(findstart, base)
|
||||
if a:findstart
|
||||
return 0
|
||||
endif
|
||||
call writefile(['matches'], 'Xmodeline_complete_proof')
|
||||
return ['match']
|
||||
endfunc
|
||||
|
||||
try
|
||||
set modeline modelineexpr nomodelinestrict
|
||||
|
||||
call writefile([
|
||||
\ 'vim: set complete=FModelineCompletePwnFindstart :',
|
||||
\ 'body',
|
||||
\ ], 'Xmodeline_complete_attack', 'D')
|
||||
call delete('Xmodeline_complete_proof')
|
||||
edit Xmodeline_complete_attack
|
||||
call cursor(2, 1)
|
||||
call assert_fails('call feedkeys("i\<C-N>\<Esc>", "xt")', 'E48:')
|
||||
call assert_false(filereadable('Xmodeline_complete_proof'))
|
||||
bwipe!
|
||||
|
||||
call writefile([
|
||||
\ 'vim: set complete=FModelineCompletePwnMatches :',
|
||||
\ 'body',
|
||||
\ ], 'Xmodeline_complete_attack', 'D')
|
||||
call delete('Xmodeline_complete_proof')
|
||||
edit Xmodeline_complete_attack
|
||||
call cursor(2, 1)
|
||||
call assert_fails('call feedkeys("i\<C-N>\<Esc>", "xt")', 'E48:')
|
||||
call assert_false(filereadable('Xmodeline_complete_proof'))
|
||||
bwipe!
|
||||
finally
|
||||
let &modeline = modeline
|
||||
let &modelineexpr = modelineexpr
|
||||
let &modelinestrict = modelinestrict
|
||||
call delete('Xmodeline_complete_proof')
|
||||
delfunc ModelineCompletePwnFindstart
|
||||
delfunc ModelineCompletePwnMatches
|
||||
endtry
|
||||
endfunc
|
||||
|
||||
func Test_modeline_setoption_verbose()
|
||||
let modeline = &modeline
|
||||
set modeline
|
||||
|
||||
@@ -729,6 +729,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
400,
|
||||
/**/
|
||||
399,
|
||||
/**/
|
||||
|
||||
Reference in New Issue
Block a user