Merge pull request #11996 from georg3tom/remove_restricted

Removed restricted mode - Fix #11972
This commit is contained in:
Björn Linse 2020-11-11 19:39:08 +01:00 committed by GitHub
commit 4875db2e56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 55 additions and 200 deletions

View File

@ -973,7 +973,7 @@ name). This is included for backwards compatibility with version 3.0, the
Note: Where a file name is expected wildcards expansion is done. On Unix the
shell is used for this, unless it can be done internally (for speed).
Unless in |restricted-mode|, backticks work also, like in >
Backticks work also, like in >
:n `echo *.c`
But expansion is only done if there are any wildcards before expanding the
'%', '#', etc.. This avoids expanding wildcards inside a file name. If you

View File

@ -20,8 +20,8 @@ additionally sets up for viewing the differences between the arguments. >
nvim -d file1 file2 [file3 [file4]]
In addition to the |-d| argument, |-Z| and |-R| may be used for restricted
mode and readonly mode respectively.
In addition to the |-d| argument, |-R| may be used for readonly mode
respectively.
The second and following arguments may also be a directory name. Vim will
then append the file name of the first argument to the directory name to find

View File

@ -5698,7 +5698,6 @@ libcall({libname}, {funcname}, {argument})
If {argument} is a number, it is passed to the function as an
int; if {argument} is a string, it is passed as a
null-terminated string.
This function will fail in |restricted-mode|.
libcall() allows you to write your own 'plug-in' extensions to
Vim without having to recompile the program. It is NOT a
@ -8804,7 +8803,6 @@ system({cmd} [, {input}]) *system()* *E677*
{cmd} is a string: 'shell' 'shellcmdflag' {cmd}
The resulting error code can be found in |v:shell_error|.
This function will fail in |restricted-mode|.
Note that any wrong value in the options mentioned above may
make the function fail. It has also been reported to fail

View File

@ -185,18 +185,6 @@ argument.
the 'modifiable' and 'write' options can be set to enable
changes and writing.
*-Z* *restricted-mode* *E145* *E981*
-Z Restricted mode. All commands that make use of an external
shell are disabled. This includes suspending with CTRL-Z,
":sh", filtering, the system() function, backtick expansion
and libcall().
Also disallowed are delete(), rename(), mkdir(), jobstart(),
etc.
Interfaces, such as Python, Ruby and Lua, are also disabled,
since they could be used to execute shell commands.
Note that the user may still find a loophole to execute a
shell command, it has only been made difficult.
-e *-e* *-E*
-E Start Nvim in Ex mode |gQ|.

View File

@ -7152,7 +7152,7 @@ void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv,
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
if (check_restricted() || check_secure()) {
if (check_secure()) {
return;
}
@ -10418,7 +10418,7 @@ Channel *find_job(uint64_t id, bool show_error)
void script_host_eval(char *name, typval_T *argvars, typval_T *rettv)
{
if (check_restricted() || check_secure()) {
if (check_secure()) {
return;
}

View File

@ -205,7 +205,7 @@ static void float_op_wrapper(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void api_wrapper(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (check_restricted() || check_secure()) {
if (check_secure()) {
return;
}
@ -862,7 +862,7 @@ static void f_chanclose(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
if (check_restricted() || check_secure()) {
if (check_secure()) {
return;
}
@ -901,7 +901,7 @@ static void f_chansend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
if (check_restricted() || check_secure()) {
if (check_secure()) {
return;
}
@ -1480,7 +1480,7 @@ static void f_deepcopy(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_delete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = -1;
if (check_restricted() || check_secure()) {
if (check_secure()) {
return;
}
@ -1515,7 +1515,7 @@ static void f_delete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// dictwatcheradd(dict, key, funcref) function
static void f_dictwatcheradd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (check_restricted() || check_secure()) {
if (check_secure()) {
return;
}
@ -1553,7 +1553,7 @@ static void f_dictwatcheradd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// dictwatcherdel(dict, key, funcref) function
static void f_dictwatcherdel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (check_restricted() || check_secure()) {
if (check_secure()) {
return;
}
@ -4798,7 +4798,7 @@ static void f_jobpid(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
if (check_restricted() || check_secure()) {
if (check_secure()) {
return;
}
@ -4822,7 +4822,7 @@ static void f_jobresize(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
if (check_restricted() || check_secure()) {
if (check_secure()) {
return;
}
@ -4855,7 +4855,7 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
if (check_restricted() || check_secure()) {
if (check_secure()) {
return;
}
@ -4988,7 +4988,7 @@ static void f_jobstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
if (check_restricted() || check_secure()) {
if (check_secure()) {
return;
}
@ -5021,7 +5021,7 @@ static void f_jobwait(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
if (check_restricted() || check_secure()) {
if (check_secure()) {
return;
}
if (argvars[0].v_type != VAR_LIST || (argvars[1].v_type != VAR_NUMBER
@ -5239,7 +5239,7 @@ static void libcall_common(typval_T *argvars, typval_T *rettv, int out_type)
rettv->vval.v_string = NULL;
}
if (check_restricted() || check_secure()) {
if (check_secure()) {
return;
}
@ -5942,8 +5942,9 @@ static void f_mkdir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
int prot = 0755; // -V536
rettv->vval.v_number = FAIL;
if (check_restricted() || check_secure())
if (check_secure()) {
return;
}
char buf[NUMBUFLEN];
const char *const dir = tv_get_string_buf(&argvars[0], buf);
@ -6832,7 +6833,7 @@ static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_rename(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (check_restricted() || check_secure()) {
if (check_secure()) {
rettv->vval.v_number = -1;
} else {
char buf[NUMBUFLEN];
@ -7230,7 +7231,7 @@ static void f_rpcnotify(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
if (check_restricted() || check_secure()) {
if (check_secure()) {
return;
}
@ -7266,7 +7267,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = 0;
const int l_provider_call_nesting = provider_call_nesting;
if (check_restricted() || check_secure()) {
if (check_secure()) {
return;
}
@ -7363,7 +7364,7 @@ static void f_rpcstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
if (check_restricted() || check_secure()) {
if (check_secure()) {
return;
}
@ -7429,7 +7430,7 @@ static void f_rpcstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
if (check_restricted() || check_secure()) {
if (check_secure()) {
return;
}
@ -7891,7 +7892,7 @@ static void f_serverstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL; // Address of the new server
if (check_restricted() || check_secure()) {
if (check_secure()) {
return;
}
@ -7933,7 +7934,7 @@ static void f_serverstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
/// "serverstop()" function
static void f_serverstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (check_restricted() || check_secure()) {
if (check_secure()) {
return;
}
@ -10466,7 +10467,7 @@ static void f_tempname(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// "termopen(cmd[, cwd])" function
static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (check_restricted() || check_secure()) {
if (check_secure()) {
return;
}

View File

@ -1049,13 +1049,13 @@ void do_bang(int addr_count, exarg_T *eap, int forceit, int do_in, int do_out)
int len;
int scroll_save = msg_scroll;
/*
* Disallow shell commands in restricted mode (-Z)
* Disallow shell commands from .exrc and .vimrc in current directory for
* security reasons.
*/
if (check_restricted() || check_secure())
//
// Disallow shell commands from .exrc and .vimrc in current directory for
// security reasons.
//
if (check_secure()) {
return;
}
if (addr_count == 0) { /* :! */
msg_scroll = FALSE; /* don't scroll here */
@ -1383,10 +1383,9 @@ do_shell(
int flags // may be SHELL_DOOUT when output is redirected
)
{
// Disallow shell commands in restricted mode (-Z)
// Disallow shell commands from .exrc and .vimrc in current directory for
// security reasons.
if (check_restricted() || check_secure()) {
if (check_secure()) {
msg_end();
return;
}
@ -3030,20 +3029,6 @@ 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.
bool check_restricted(void)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
if (restricted) {
EMSG(_("E145: Shell commands and some functionality not allowed"
" in restricted mode"));
return true;
}
return false;
}
/*
* Check if the secure flag is set (.exrc or .vimrc in current directory).
* If so, give an error message and return TRUE.

View File

@ -62,7 +62,6 @@
// curbuf_lock is set
#define MODIFY 0x200000 // forbidden in non-'modifiable' buffer
#define EXFLAGS 0x400000 // allow flags after count in argument
#define RESTRICT 0x800000L // forbidden in restricted mode
#define FILES (XFILE | EXTRA) // multiple extra files allowed
#define WORD1 (EXTRA | NOSPC) // one extra word allowed
#define FILE1 (FILES | NOSPC) // 1 file allowed, defaults to current file

View File

@ -1503,10 +1503,6 @@ static char_u * do_one_cmd(char_u **cmdlinep,
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)) {
@ -6624,25 +6620,22 @@ static void ex_hide(exarg_T *eap)
/// ":stop" and ":suspend": Suspend Vim.
static void ex_stop(exarg_T *eap)
{
// Disallow suspending in restricted mode (-Z)
if (!check_restricted()) {
if (!eap->forceit) {
autowrite_all();
}
apply_autocmds(EVENT_VIMSUSPEND, NULL, NULL, false, NULL);
// TODO(bfredl): the TUI should do this on suspend
ui_cursor_goto(Rows - 1, 0);
ui_call_grid_scroll(1, 0, Rows, 0, Columns, 1, 0);
ui_flush();
ui_call_suspend(); // call machine specific function
ui_flush();
maketitle();
resettitle(); // force updating the title
ui_refresh(); // may have resized window
apply_autocmds(EVENT_VIMRESUME, NULL, NULL, false, NULL);
if (!eap->forceit) {
autowrite_all();
}
apply_autocmds(EVENT_VIMSUSPEND, NULL, NULL, false, NULL);
// TODO(bfredl): the TUI should do this on suspend
ui_cursor_goto(Rows - 1, 0);
ui_call_grid_scroll(1, 0, Rows, 0, Columns, 1, 0);
ui_flush();
ui_call_suspend(); // call machine specific function
ui_flush();
maketitle();
resettitle(); // force updating the title
ui_refresh(); // may have resized window
apply_autocmds(EVENT_VIMRESUME, NULL, NULL, false, NULL);
}
// ":exit", ":xit" and ":wq": Write file and quite the current window.

View File

@ -492,9 +492,6 @@ EXTERN int stdout_isatty INIT(= true);
// volatile because it is used in a signal handler.
EXTERN volatile int full_screen INIT(= false);
// When started in restricted mode (-Z).
EXTERN int restricted INIT(= false);
/// Non-zero when only "safe" commands are allowed, e.g. when sourcing .exrc or
/// .vimrc in current directory.
EXTERN int secure INIT(= false);

View File

@ -965,7 +965,7 @@ static void typval_exec_lua(const char *lcmd, size_t lcmd_len, const char *name,
typval_T *const args, int argcount, bool special,
typval_T *ret_tv)
{
if (check_restricted() || check_secure()) {
if (check_secure()) {
if (ret_tv) {
ret_tv->v_type = VAR_NUMBER;
ret_tv->vval.v_number = 0;

View File

@ -1012,10 +1012,6 @@ static void command_line_scan(mparm_T *parmp)
want_argument = true;
break;
}
case 'Z': { // "-Z" restricted mode
restricted = true;
break;
}
case 'c': { // "-c{command}" or "-c {command}" exec command
if (argv[0][argv_idx] != NUL) {

View File

@ -1091,8 +1091,9 @@ char_u *get_cmd_output(char_u *cmd, char_u *infile, ShellOpts flags,
{
char_u *buffer = NULL;
if (check_restricted() || check_secure())
if (check_secure()) {
return NULL;
}
// get a name for the temp file
char_u *tempname = vim_tempname();

View File

@ -150,11 +150,11 @@ int os_expand_wildcards(int num_pat, char_u **pat, int *num_file,
return FAIL;
}
// Don't allow the use of backticks in secure and restricted mode.
if (secure || restricted) {
// Don't allow the use of backticks in secure.
if (secure) {
for (i = 0; i < num_pat; i++) {
if (vim_strchr(pat[i], '`') != NULL
&& (check_restricted() || check_secure())) {
&& (check_secure())) {
return FAIL;
}
}

View File

@ -1,103 +0,0 @@
" Test for "rvim" or "vim -Z"
source shared.vim
"if has('win32') && has('gui')
" " Win32 GUI shows a dialog instead of displaying the error in the last line.
" finish
"endif
func Test_restricted()
call Run_restricted_test('!ls', 'E145:')
endfunc
func Run_restricted_test(ex_cmd, error)
let cmd = GetVimCommand('Xrestricted')
if cmd == ''
return
endif
" Use a VimEnter autocommand to avoid that the error message is displayed in
" a dialog with an OK button.
call writefile([
\ "func Init()",
\ " silent! " . a:ex_cmd,
\ " call writefile([v:errmsg], 'Xrestrout')",
\ " qa!",
\ "endfunc",
\ "au VimEnter * call Init()",
\ ], '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