vim-patch:8.1.0881: can execute shell commands in rvim through interfaces

Problem:    Can execute shell commands in rvim through interfaces.
Solution:   Disable using interfaces in restricted mode. Allow for writing
            file with writefile(), histadd() and a few others.
8c62a08faf
This commit is contained in:
Jan Edmund Lazo
2020-02-24 20:33:43 -05:00
parent 3618fe9e8c
commit d846f47cc8
5 changed files with 134 additions and 19 deletions

View File

@@ -4317,7 +4317,7 @@ static void f_histadd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
HistoryType histype;
rettv->vval.v_number = false;
if (check_restricted() || check_secure()) {
if (check_secure()) {
return;
}
const char *str = tv_get_string_chk(&argvars[0]); // NULL on type error
@@ -7779,8 +7779,7 @@ static void f_setbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_setbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (check_restricted()
|| check_secure()
if (check_secure()
|| !tv_check_str_or_nr(&argvars[0])) {
return;
}
@@ -8284,7 +8283,7 @@ static void f_settabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = 0;
if (check_restricted() || check_secure()) {
if (check_secure()) {
return;
}
@@ -11005,7 +11004,7 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = -1;
if (check_restricted() || check_secure()) {
if (check_secure()) {
return;
}

View File

@@ -3008,18 +3008,18 @@ void ex_z(exarg_T *eap)
ex_no_reprint = true;
}
/*
* Check if the restricted flag is set.
* If so, give an error message and return TRUE.
* Otherwise, return FALSE.
*/
int check_restricted(void)
// Check if the restricted flag is set.
// If so, give an error message and return true.
// Otherwise, return false.
bool check_restricted(void)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
if (restricted) {
EMSG(_("E145: Shell commands not allowed in restricted mode"));
return TRUE;
EMSG(_("E145: Shell commands and some functionality not allowed"
" in restricted mode"));
return true;
}
return FALSE;
return false;
}
/*

View File

@@ -1783,10 +1783,14 @@ static char_u * do_one_cmd(char_u **cmdlinep,
if (!ea.skip) {
if (sandbox != 0 && !(ea.argt & SBOXOK)) {
/* Command not allowed in sandbox. */
// Command not allowed in sandbox.
errormsg = (char_u *)_(e_sandbox);
goto doend;
}
if (restricted != 0 && (ea.argt & RESTRICT)) {
errormsg = (char_u *)_("E981: Command not allowed in restricted mode");
goto doend;
}
if (!MODIFIABLE(curbuf) && (ea.argt & MODIFY)
// allow :put in terminals
&& (!curbuf->terminal || ea.cmdidx != CMD_put)) {

View File

@@ -0,0 +1,107 @@
" Test for "rvim" or "vim -Z"
source shared.vim
func Test_restricted()
let cmd = GetVimCommand('Xrestricted')
if cmd == ''
return
endif
call writefile([
\ "silent !ls",
\ "call writefile([v:errmsg], 'Xrestrout')",
\ "qa!",
\ ], 'Xrestricted')
call system(cmd . ' -Z')
call assert_match('E145:', join(readfile('Xrestrout')))
call delete('Xrestricted')
call delete('Xrestrout')
endfunc
func Run_restricted_test(ex_cmd, error)
let cmd = GetVimCommand('Xrestricted')
if cmd == ''
return
endif
call writefile([
\ a:ex_cmd,
\ "call writefile([v:errmsg], 'Xrestrout')",
\ "qa!",
\ ], 'Xrestricted')
call system(cmd . ' -Z')
call assert_match(a:error, join(readfile('Xrestrout')))
call delete('Xrestricted')
call delete('Xrestrout')
endfunc
func Test_restricted_lua()
if !has('lua')
throw 'Skipped: Lua is not supported'
endif
call Run_restricted_test('lua print("Hello, Vim!")', 'E981:')
call Run_restricted_test('luado return "hello"', 'E981:')
call Run_restricted_test('luafile somefile', 'E981:')
call Run_restricted_test('call luaeval("expression")', 'E145:')
endfunc
func Test_restricted_mzscheme()
if !has('mzscheme')
throw 'Skipped: MzScheme is not supported'
endif
call Run_restricted_test('mzscheme statement', 'E981:')
call Run_restricted_test('mzfile somefile', 'E981:')
call Run_restricted_test('call mzeval("expression")', 'E145:')
endfunc
func Test_restricted_perl()
if !has('perl')
throw 'Skipped: Perl is not supported'
endif
" TODO: how to make Safe mode fail?
" call Run_restricted_test('perl system("ls")', 'E981:')
" call Run_restricted_test('perldo system("hello")', 'E981:')
" call Run_restricted_test('perlfile somefile', 'E981:')
" call Run_restricted_test('call perleval("system(\"ls\")")', 'E145:')
endfunc
func Test_restricted_python()
if !has('python')
throw 'Skipped: Python is not supported'
endif
call Run_restricted_test('python print "hello"', 'E981:')
call Run_restricted_test('pydo return "hello"', 'E981:')
call Run_restricted_test('pyfile somefile', 'E981:')
call Run_restricted_test('call pyeval("expression")', 'E145:')
endfunc
func Test_restricted_python3()
if !has('python3')
throw 'Skipped: Python3 is not supported'
endif
call Run_restricted_test('py3 print "hello"', 'E981:')
call Run_restricted_test('py3do return "hello"', 'E981:')
call Run_restricted_test('py3file somefile', 'E981:')
call Run_restricted_test('call py3eval("expression")', 'E145:')
endfunc
func Test_restricted_ruby()
if !has('ruby')
throw 'Skipped: Ruby is not supported'
endif
call Run_restricted_test('ruby print "Hello"', 'E981:')
call Run_restricted_test('rubydo print "Hello"', 'E981:')
call Run_restricted_test('rubyfile somefile', 'E981:')
endfunc
func Test_restricted_tcl()
if !has('tcl')
throw 'Skipped: Tcl is not supported'
endif
call Run_restricted_test('tcl puts "Hello"', 'E981:')
call Run_restricted_test('tcldo puts "Hello"', 'E981:')
call Run_restricted_test('tclfile somefile', 'E981:')
endfunc