diff options
Diffstat (limited to '')
-rw-r--r-- | debian/patches/upstream/patch-8.1.0881-can-execute-shell-commands-in-rvim-through.patch | 378 |
1 files changed, 378 insertions, 0 deletions
diff --git a/debian/patches/upstream/patch-8.1.0881-can-execute-shell-commands-in-rvim-through.patch b/debian/patches/upstream/patch-8.1.0881-can-execute-shell-commands-in-rvim-through.patch new file mode 100644 index 0000000..01e9ad7 --- /dev/null +++ b/debian/patches/upstream/patch-8.1.0881-can-execute-shell-commands-in-rvim-through.patch @@ -0,0 +1,378 @@ +From: Bram Moolenaar <Bram@vim.org> +Date: Fri, 8 Feb 2019 14:34:10 +0100 +Subject: 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. +(cherry picked from commit 8c62a08faf89663e5633dc5036cd8695c80f1075) +--- + runtime/doc/starting.txt | 14 ++++-- + src/evalfunc.c | 22 +++++++-- + src/ex_cmds.c | 2 +- + src/ex_docmd.c | 7 ++- + src/if_perl.xs | 13 ++--- + src/testdir/Make_all.mak | 2 + + src/testdir/test_restricted.vim | 107 ++++++++++++++++++++++++++++++++++++++++ + src/version.c | 2 + + 8 files changed, 151 insertions(+), 18 deletions(-) + create mode 100644 src/testdir/test_restricted.vim + +diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt +index 711a487..6289e9c 100644 +--- a/runtime/doc/starting.txt ++++ b/runtime/doc/starting.txt +@@ -248,12 +248,18 @@ a slash. Thus "-R" means recovery and "-/R" readonly. + changes and writing. + {not in Vi} + +- *-Z* *restricted-mode* *E145* ++ *-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, +- delete(), rename(), mkdir(), writefile(), libcall(), +- job_start(), etc. ++ ":sh", filtering, the system() function, backtick expansion ++ and libcall(). ++ Also disallowed are delete(), rename(), mkdir(), job_start(), ++ etc. ++ Interfaces, such as Python, Ruby and Lua, are also disabled, ++ since they could be used to execute shell commands. Perl uses ++ the Safe module. ++ Note that the user may still find a loophole to execute a ++ shell command, it has only been made difficult. + {not in Vi} + + *-g* +diff --git a/src/evalfunc.c b/src/evalfunc.c +index fa7ed9b..eb082b7 100644 +--- a/src/evalfunc.c ++++ b/src/evalfunc.c +@@ -6817,7 +6817,7 @@ f_histadd(typval_T *argvars UNUSED, typval_T *rettv) + #endif + + rettv->vval.v_number = FALSE; +- if (check_restricted() || check_secure()) ++ if (check_secure()) + return; + #ifdef FEAT_CMDHIST + str = tv_get_string_chk(&argvars[0]); /* NULL on type error */ +@@ -7898,6 +7898,9 @@ f_luaeval(typval_T *argvars, typval_T *rettv) + char_u *str; + char_u buf[NUMBUFLEN]; + ++ if (check_restricted() || check_secure()) ++ return; ++ + str = tv_get_string_buf(&argvars[0], buf); + do_luaeval(str, argvars + 1, rettv); + } +@@ -8644,6 +8647,8 @@ f_mzeval(typval_T *argvars, typval_T *rettv) + char_u *str; + char_u buf[NUMBUFLEN]; + ++ if (check_restricted() || check_secure()) ++ return; + str = tv_get_string_buf(&argvars[0], buf); + do_mzeval(str, rettv); + } +@@ -8932,6 +8937,9 @@ f_py3eval(typval_T *argvars, typval_T *rettv) + char_u *str; + char_u buf[NUMBUFLEN]; + ++ if (check_restricted() || check_secure()) ++ return; ++ + if (p_pyx == 0) + p_pyx = 3; + +@@ -8950,6 +8958,9 @@ f_pyeval(typval_T *argvars, typval_T *rettv) + char_u *str; + char_u buf[NUMBUFLEN]; + ++ if (check_restricted() || check_secure()) ++ return; ++ + if (p_pyx == 0) + p_pyx = 2; + +@@ -8965,6 +8976,9 @@ f_pyeval(typval_T *argvars, typval_T *rettv) + static void + f_pyxeval(typval_T *argvars, typval_T *rettv) + { ++ if (check_restricted() || check_secure()) ++ return; ++ + # if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3) + init_pyxversion(); + if (p_pyx == 2) +@@ -10819,7 +10833,7 @@ f_setbufvar(typval_T *argvars, typval_T *rettv UNUSED) + typval_T *varp; + char_u nbuf[NUMBUFLEN]; + +- if (check_restricted() || check_secure()) ++ if (check_secure()) + return; + (void)tv_get_number(&argvars[0]); /* issue errmsg if type error */ + varname = tv_get_string_chk(&argvars[1]); +@@ -11341,7 +11355,7 @@ f_settabvar(typval_T *argvars, typval_T *rettv) + + rettv->vval.v_number = 0; + +- if (check_restricted() || check_secure()) ++ if (check_secure()) + return; + + tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL)); +@@ -14714,7 +14728,7 @@ f_writefile(typval_T *argvars, typval_T *rettv) + blob_T *blob = NULL; + + rettv->vval.v_number = -1; +- if (check_restricted() || check_secure()) ++ if (check_secure()) + return; + + if (argvars[0].v_type == VAR_LIST) +diff --git a/src/ex_cmds.c b/src/ex_cmds.c +index a3974c1..681ef42 100644 +--- a/src/ex_cmds.c ++++ b/src/ex_cmds.c +@@ -4775,7 +4775,7 @@ check_restricted(void) + { + if (restricted) + { +- emsg(_("E145: Shell commands not allowed in rvim")); ++ emsg(_("E145: Shell commands and some functionality not allowed in rvim")); + return TRUE; + } + return FALSE; +diff --git a/src/ex_docmd.c b/src/ex_docmd.c +index b90ea7b..ccca2f9 100644 +--- a/src/ex_docmd.c ++++ b/src/ex_docmd.c +@@ -2007,11 +2007,16 @@ do_one_cmd( + #ifdef HAVE_SANDBOX + if (sandbox != 0 && !(ea.argt & SBOXOK)) + { +- /* Command not allowed in sandbox. */ ++ // Command not allowed in sandbox. + errormsg = _(e_sandbox); + goto doend; + } + #endif ++ if (restricted != 0 && (ea.argt & RESTRICT)) ++ { ++ errormsg = _("E981: Command not allowed in rvim"); ++ goto doend; ++ } + if (!curbuf->b_p_ma && (ea.argt & MODIFY)) + { + /* Command not allowed in non-'modifiable' buffer */ +diff --git a/src/if_perl.xs b/src/if_perl.xs +index 203bb6a..67d0b94 100644 +--- a/src/if_perl.xs ++++ b/src/if_perl.xs +@@ -971,6 +971,7 @@ VIM_init(void) + #ifdef DYNAMIC_PERL + static char *e_noperl = N_("Sorry, this command is disabled: the Perl library could not be loaded."); + #endif ++static char *e_perlsandbox = N_("E299: Perl evaluation forbidden in sandbox without the Safe module"); + + /* + * ":perl" +@@ -1019,13 +1020,12 @@ ex_perl(exarg_T *eap) + vim_free(script); + } + +-#ifdef HAVE_SANDBOX +- if (sandbox) ++ if (sandbox || secure) + { + safe = perl_get_sv("VIM::safe", FALSE); + # ifndef MAKE_TEST /* avoid a warning for unreachable code */ + if (safe == NULL || !SvTRUE(safe)) +- emsg(_("E299: Perl evaluation forbidden in sandbox without the Safe module")); ++ emsg(_(e_perlsandbox)); + else + # endif + { +@@ -1037,7 +1037,6 @@ ex_perl(exarg_T *eap) + } + } + else +-#endif + perl_eval_sv(sv, G_DISCARD | G_NOARGS); + + SvREFCNT_dec(sv); +@@ -1298,13 +1297,12 @@ do_perleval(char_u *str, typval_T *rettv) + ENTER; + SAVETMPS; + +-#ifdef HAVE_SANDBOX +- if (sandbox) ++ if (sandbox || secure) + { + safe = get_sv("VIM::safe", FALSE); + # ifndef MAKE_TEST /* avoid a warning for unreachable code */ + if (safe == NULL || !SvTRUE(safe)) +- emsg(_("E299: Perl evaluation forbidden in sandbox without the Safe module")); ++ emsg(_(e_perlsandbox)); + else + # endif + { +@@ -1320,7 +1318,6 @@ do_perleval(char_u *str, typval_T *rettv) + } + } + else +-#endif /* HAVE_SANDBOX */ + sv = eval_pv((char *)str, 0); + + if (sv) { +diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak +index 5857a22..2ca5f2b 100644 +--- a/src/testdir/Make_all.mak ++++ b/src/testdir/Make_all.mak +@@ -213,6 +213,7 @@ NEW_TESTS = \ + test_regexp_utf8 \ + test_registers \ + test_reltime \ ++ test_restricted \ + test_retab \ + test_ruby \ + test_scriptnames \ +@@ -375,6 +376,7 @@ NEW_TESTS_RES = \ + test_quotestar.res \ + test_regex_char_classes.res \ + test_registers.res \ ++ test_restricted.res \ + test_retab.res \ + test_ruby.res \ + test_scriptnames.res \ +diff --git a/src/testdir/test_restricted.vim b/src/testdir/test_restricted.vim +new file mode 100644 +index 0000000..9dd937c +--- /dev/null ++++ b/src/testdir/test_restricted.vim +@@ -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 +diff --git a/src/version.c b/src/version.c +index 1b5d863..adb3441 100644 +--- a/src/version.c ++++ b/src/version.c +@@ -809,6 +809,8 @@ static int included_patches[] = + 948, + /**/ + 884, ++/**/ ++ 881, + /**/ + 878, + /**/ |