Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Security issue in Zsh restricted mode (zsh -r) – escape via history built‑ins



On 1 Feb, I wrote:
> On further deliberation, I think we should just drop the whole
> restricted mode feature. The documentation has carried a warning that
> "the feature may be removed in future" for the past six years.

Nobody argued for a reprieve so a patch to get rid of it follows.

This does leave the option in existence but it does nothing. That's
just for backwards compatibility with old set -o or setopt commands.

PM_RESTRICTED is overloaded in the zsh/param/private module so needs to
stay. It doesn't appear that the module was relying on protections that
option gave to variables with the flag set but I could be wrong.

For what it's worth, compiling zsh statically does not help with the
LD_ variables used by the loader. The problem is anytime the loader
is used when invoking a command from the restricted shell. Actually,
a couple of LD_ variables are treated as protected but not all that
matter. And as I mentioned these vary between operating systems.

Oliver

diff --git a/Doc/Makefile.in b/Doc/Makefile.in
index f68f40a9e..083e019d5 100644
--- a/Doc/Makefile.in
+++ b/Doc/Makefile.in
@@ -84,7 +84,7 @@ Zsh/filelist.yo Zsh/files.yo \
 Zsh/func.yo Zsh/grammar.yo Zsh/manual.yo \
 Zsh/index.yo Zsh/intro.yo Zsh/invoke.yo Zsh/jobs.yo Zsh/metafaq.yo \
 Zsh/modules.yo Zsh/modlist.yo Zsh/modmenu.yo Zsh/manmodmenu.yo $(MODDOCSRC) \
-Zsh/options.yo Zsh/params.yo Zsh/prompt.yo Zsh/redirect.yo Zsh/restricted.yo \
+Zsh/options.yo Zsh/params.yo Zsh/prompt.yo Zsh/redirect.yo \
 Zsh/seealso.yo Zsh/tcpsys.yo Zsh/zftpsys.yo Zsh/zle.yo
 
 # ========== DEPENDENCIES FOR BUILDING ==========
@@ -219,7 +219,7 @@ $(MAN): zmacros.yo zman.yo
 
 zsh.1 zshall.1: Zsh/intro.yo Zsh/metafaq.yo Zsh/invoke.yo Zsh/files.yo \
                 Zsh/filelist.yo Zsh/filelist.yo Zsh/seealso.yo \
-                Zsh/compat.yo Zsh/restricted.yo
+                Zsh/compat.yo
 
 zshbuiltins.1: Zsh/builtins.yo
 
diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
index c322cee77..c63d66e0c 100644
--- a/Doc/Zsh/builtins.yo
+++ b/Doc/Zsh/builtins.yo
@@ -570,8 +570,7 @@ change.
 
 The var(flags) may be any of the invocation-time flags described in
 sectref(Invocation)(zsh),
-except that `tt(-o EMACS)' and `tt(-o VI)' may not be used.  Flags such
-as `tt(+r)'/`tt(+o RESTRICTED)' may be prohibited in some circumstances.
+except that `tt(-o EMACS)' and `tt(-o VI)' may not be used.
 
 If tt(-c) var(arg) appears in var(flags), var(arg) is evaluated while the
 requested emulation is temporarily in effect.  In this case the emulation
diff --git a/Doc/Zsh/compat.yo b/Doc/Zsh/compat.yo
index 4d3567d45..df0ace63d 100644
--- a/Doc/Zsh/compat.yo
+++ b/Doc/Zsh/compat.yo
@@ -1,12 +1,11 @@
-texinode(Compatibility)(Restricted Shell)()(Invocation)
+texinode(Compatibility)()()(Invocation)
 sect(Compatibility)
 cindex(compatibility)
 cindex(sh compatibility)
 cindex(ksh compatibility)
 Zsh tries to emulate bf(sh) or bf(ksh) when it is invoked as
 tt(sh) or tt(ksh) respectively; more precisely, it looks at the first
-letter of the name by which it was invoked, excluding any initial `tt(r)'
-(assumed to stand for `restricted'), and if that is `tt(b)', `tt(s)' or `tt(k)' it
+letter of the name by which it was invoked, and if that is `tt(b)', `tt(s)' or `tt(k)' it
 will emulate bf(sh) or bf(ksh).  Furthermore, if invoked as tt(su) (which
 happens on certain systems when the shell is executed by the tt(su)
 command), the shell will try to find an alternative name from the tt(SHELL)
diff --git a/Doc/Zsh/grammar.yo b/Doc/Zsh/grammar.yo
index e75e66a6c..8dbfd1164 100644
--- a/Doc/Zsh/grammar.yo
+++ b/Doc/Zsh/grammar.yo
@@ -531,7 +531,6 @@ itemiz(Execution of incorrectly positioned loop control structures
 (tt(continue), tt(break)))
 itemiz(Attempts to use regular expression with no regular expression
 module available)
-itemiz(Disallowed operations when the tt(RESTRICTED) options is set)
 itemiz(Failure to create a pipe needed for a pipeline)
 itemiz(Failure to create a multio)
 itemiz(Failure to autoload a module needed for a declared shell feature)
diff --git a/Doc/Zsh/invoke.yo b/Doc/Zsh/invoke.yo
index 9c589b278..b6ed73fe5 100644
--- a/Doc/Zsh/invoke.yo
+++ b/Doc/Zsh/invoke.yo
@@ -105,8 +105,6 @@ can be stacked after the `tt(-b)' and will take effect as normal.
 
 startmenu()
 menu(Compatibility)
-menu(Restricted Shell)
 endmenu()
 
 includefile(Zsh/compat.yo)
-includefile(Zsh/restricted.yo)
diff --git a/Doc/Zsh/manual.yo b/Doc/Zsh/manual.yo
index 8cbe2cfd2..c7882cebd 100644
--- a/Doc/Zsh/manual.yo
+++ b/Doc/Zsh/manual.yo
@@ -64,7 +64,6 @@ menu(See Also)
 Invocation
 
 menu(Compatibility)
-menu(Restricted Shell)
 
 Shell Grammar
 
diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo
index a7e862c70..729a6ac26 100644
--- a/Doc/Zsh/options.yo
+++ b/Doc/Zsh/options.yo
@@ -1837,8 +1837,8 @@ pindex(NOLOCALOPTIONS)
 item(tt(LOCAL_OPTIONS) <K>)(
 If this option is set at the point of return from a shell function,
 most options (including this one) which were in force upon entry to
-the function are restored; options that are not restored are
-tt(PRIVILEGED) and tt(RESTRICTED).  Otherwise, only this option,
+the function are restored; the tt(PRIVILEGED) option is not restored.
+Otherwise, only this option,
 and the tt(LOCAL_LOOPS), tt(XTRACE) and tt(PRINT_EXIT_VALUE) options are
 restored.  Hence if this is explicitly unset by a shell function the
 other options in force at the point of return will remain so.
@@ -2471,10 +2471,8 @@ pindex(NO_RESTRICTED)
 pindex(NORESTRICTED)
 cindex(restricted shell)
 item(tt(RESTRICTED) (tt(-r)))(
-Enables restricted mode.  This option cannot be changed using
-tt(unsetopt), and setting it inside a function always changes it
-globally regardless of the tt(LOCAL_OPTIONS) option.  See
-sectref(Restricted Shell)(zsh).
+This option is ignored and only exists for compatibility. Support
+for restricted mode has been removed.
 )
 pindex(SHIN_STDIN)
 pindex(NO_SHIN_STDIN)
diff --git a/Doc/Zsh/restricted.yo b/Doc/Zsh/restricted.yo
deleted file mode 100644
index a84fd28ea..000000000
--- a/Doc/Zsh/restricted.yo
+++ /dev/null
@@ -1,84 +0,0 @@
-texinode(Restricted Shell)()(Compatibility)(Invocation)
-sect(Restricted Shell)
-cindex(restricted shell)
-pindex(RESTRICTED)
-When the basename of the command used to invoke zsh starts with the letter
-`tt(r)' or the `tt(-r)' command line option is supplied at invocation, the
-shell becomes restricted.  Emulation mode is determined after stripping the
-letter `tt(r)' from the invocation name.  The following are disabled in
-restricted mode:
-
-startitemize()
-itemiz(changing directories with the tt(cd) builtin)
-itemiz(changing or unsetting the tt(EGID), tt(EUID), tt(GID),
-tt(HISTFILE), tt(HISTSIZE), tt(IFS), tt(LD_AOUT_LIBRARY_PATH),
-tt(LD_AOUT_PRELOAD), tt(LD_LIBRARY_PATH), tt(LD_PRELOAD),
-tt(MODULE_PATH), tt(module_path), tt(PATH), tt(path), tt(SHELL),
-tt(UID) and tt(USERNAME) parameters)
-itemiz(specifying command names containing tt(/))
-itemiz(specifying command pathnames using tt(hash))
-itemiz(redirecting output to files)
-itemiz(using the tt(exec) builtin command to replace the shell with another
-command)
-itemiz(using tt(jobs -Z) to overwrite the shell process' argument and
-environment space)
-itemiz(using the tt(ARGV0) parameter to override tt(argv[0]) for external
-commands)
-itemiz(turning off restricted mode with tt(set +r) or tt(unsetopt
-RESTRICTED))
-enditemize()
-
-These restrictions are enforced after processing the startup files.  The
-startup files should set up tt(PATH) to point to a directory of commands
-which can be safely invoked in the restricted environment.  They may also
-add further restrictions by disabling selected builtins.
-
-Restricted mode can also be activated any time by setting the
-tt(RESTRICTED) option.  This immediately enables all the restrictions
-described above even if the shell still has not processed all startup
-files.
-
-A shell em(Restricted Mode) is an outdated way to restrict what users may
-do:  modern systems have better, safer and more reliable ways to
-confine user actions, such as em(chroot jails), em(containers) and
-em(zones).
-
-A restricted shell is very difficult to implement safely.  The feature
-may be removed in a future version of zsh.
-
-It is important to realise that the restrictions only apply to the shell,
-not to the commands it runs (except for some shell builtins).  While a
-restricted shell can only run the restricted list of commands accessible
-via the predefined `tt(PATH)' variable, it does not prevent those
-commands from running any other command.
-
-As an example, if `tt(env)' is among the list of em(allowed) commands,
-then it allows the user to run any command as `tt(env)' is not a shell
-builtin command and can run arbitrary executables.
-
-So when implementing a restricted shell framework it is important to be
-fully aware of what actions each of the em(allowed) commands or features
-(which may be regarded as em(modules)) can perform.
-
-Many commands can have their behaviour affected by environment
-variables.  Except for the few listed above, zsh does not restrict
-the setting of environment variables.
-
-If a `tt(perl)', `tt(python)', `tt(bash)', or other general purpose
-interpreted script is treated as a restricted
-command, the user can work around the restriction by
-setting specially crafted `tt(PERL5LIB)', `tt(PYTHONPATH)',
-`tt(BASH_ENV)' (etc.) environment variables. On GNU systems, any
-command can be made to run arbitrary code when performing character set
-conversion (including zsh itself) by setting a `tt(GCONV_PATH)'
-environment variable.  Those are only a few examples.
-
-Bear in mind that, contrary to some other shells, `tt(readonly)' is not a
-security feature in zsh as it can be undone and so cannot be used to
-mitigate the above.
-
-A restricted shell only works if the allowed commands are few
-and carefully written so as not to grant more access to users than
-intended.  It is also important to restrict what zsh module the user may
-load as some of them, such as `tt(zsh/system)', `tt(zsh/mapfile)' and
-`tt(zsh/files)', allow bypassing most of the restrictions.
diff --git a/README b/README
index 64b0f4e4a..e546af267 100644
--- a/README
+++ b/README
@@ -52,6 +52,11 @@ or, if your $VISUAL and $EDITOR environment variables vary,
 to your .zshrc file.  These snippets are compatible with previous
 versions of the shell.
 
+Restricted mode has been removed.  This was associated with the option
+RESTRICTED (-r).  This was an outdated way to restrict what users may do and
+was very difficult to apply safely.  Furthermore, modern systems have better,
+safer and more reliable ways to confine user actions.
+
 The ERR_EXIT and ERR_RETURN options were refined to be more self-
 consistent and better aligned with the POSIX-2017 specification of
 `set -e`:
diff --git a/Src/Modules/db_gdbm.c b/Src/Modules/db_gdbm.c
index 7d1720de5..34f577e30 100644
--- a/Src/Modules/db_gdbm.c
+++ b/Src/Modules/db_gdbm.c
@@ -150,7 +150,7 @@ bin_ztie(char *nam, char **args, Options ops, UNUSED(int func))
 	 * We need to do this before attempting to open the DB
 	 * in case this variable is already tied to a DB.
 	 *
-	 * This can fail if the variable is readonly or restricted.
+	 * This can fail if the variable is readonly.
 	 * We could call unsetparam() and check errflag instead
 	 * of the return status.
 	 */
diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c
index 10e4ffc5c..0743e6323 100644
--- a/Src/Modules/parameter.c
+++ b/Src/Modules/parameter.c
@@ -151,17 +151,12 @@ scanpmparameters(UNUSED(HashTable ht), ScanFunc func, int flags)
 static void
 setpmcommand(Param pm, char *value)
 {
-    if (isset(RESTRICTED)) {
-	zwarn("restricted: %s", value);
-	zsfree(value);
-    } else {
-	Cmdnam cn = zshcalloc(sizeof(*cn));
+    Cmdnam cn = zshcalloc(sizeof(*cn));
 
-	cn->node.flags = HASHED;
-	cn->u.cmd = value;
+    cn->node.flags = HASHED;
+    cn->u.cmd = value;
 
-	cmdnamtab->addnode(cmdnamtab, ztrdup(pm->node.nam), &cn->node);
-    }
+    cmdnamtab->addnode(cmdnamtab, ztrdup(pm->node.nam), &cn->node);
 }
 
 /**/
diff --git a/Src/builtin.c b/Src/builtin.c
index 49fab93da..b097414fb 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -841,10 +841,6 @@ bin_cd(char *nam, char **argv, Options ops, int func)
 {
     LinkNode dir;
 
-    if (isset(RESTRICTED)) {
-	zwarnnam(nam, "restricted");
-	return 1;
-    }
     doprintdir = (doprintdir == -1);
 
     chasinglinks = OPT_ISSET(ops,'P') ||
@@ -2249,10 +2245,6 @@ typeset_single(char *cname, char *pname, Param pm, int func,
 		paramtab->printnode(&pm->node, PRINT_INCLUDEVALUE|with_ns);
 	    return pm;
 	}
-	if ((pm->node.flags & PM_RESTRICTED) && isset(RESTRICTED)) {
-	    zerrnam(cname, "%s: restricted", pname);
-	    return pm;
-	}
 	if ((pm->node.flags & PM_READONLY) && !(off & PM_READONLY) &&
 	    /* It seems as though these checks should not be specific to
 	     * PM_NAMEREF, but changing that changes historic behavior */
@@ -2387,10 +2379,6 @@ typeset_single(char *cname, char *pname, Param pm, int func,
 
     if (newspecial != NS_NONE) {
 	Param tpm, pm2;
-	if ((pm->node.flags & PM_RESTRICTED) && isset(RESTRICTED)) {
-	    zerrnam(cname, "%s: restricted", pname);
-	    return pm;
-	}
 	if (pm->node.flags & PM_SINGLE) {
 	    zerrnam(cname, "%s: can only have a single instance", pname);
 	    return pm;
@@ -2631,12 +2619,7 @@ typeset_single(char *cname, char *pname, Param pm, int func,
 	    pm->gsu.s->setfn(pm, ztrdup(""));
 	    break;
 	case PM_INTEGER:
-	    /*
-	     * Restricted integers are dangerous to initialize to 0,
-	     * so don't do that.
-	     */
-	    if (!(pm->old->node.flags & PM_RESTRICTED))
-		pm->gsu.i->setfn(pm, 0);
+	    pm->gsu.i->setfn(pm, 0);
 	    break;
 	case PM_EFLOAT:
 	case PM_FFLOAT:
@@ -3096,8 +3079,7 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func)
 	    for (i = 0; i < paramtab->hsize; i++) {
 		for (pm = (Param) paramtab->nodes[i]; pm;
 		     pm = (Param) pm->node.next) {
-		    if (((pm->node.flags & PM_RESTRICTED) && isset(RESTRICTED)) ||
-			(pm->node.flags & PM_UNSET))
+		    if (pm->node.flags & PM_UNSET)
 			continue;
 		    if (pattry(pprog, pm->node.nam))
 			addlinknode(pmlist, pm);
@@ -3855,9 +3837,7 @@ bin_unset(char *name, char **argv, Options ops, int func)
 		    for (pm = (Param) paramtab->nodes[i]; pm; pm = next) {
 			/* record pointer to next, since we may free this one */
 			next = (Param) pm->node.next;
-			if ((!(pm->node.flags & PM_RESTRICTED) ||
-			     unset(RESTRICTED)) &&
-			    pattry(pprog, pm->node.nam)) {
+			if (pattry(pprog, pm->node.nam)) {
 			    if (!OPT_ISSET(ops,'n') &&
 				(pm->node.flags & PM_NAMEREF) && pm->u.str)
 				unsetparam(pm->u.str);
@@ -3910,10 +3890,7 @@ bin_unset(char *name, char **argv, Options ops, int func)
 	 */
 	if (!pm)
 	    continue;
-	else if ((pm->node.flags & PM_RESTRICTED) && isset(RESTRICTED)) {
-	    zerrnam(name, "%s: restricted", pm->node.nam);
-	    returnval = 1;
-	} else if (ss) {
+	else if (ss) {
 	    if ((pm->node.flags & PM_NAMEREF) &&
 		(!(pm = (Param)resolve_nameref(pm, NULL)) || pm->width)) {
 		/* warning? */
@@ -4315,34 +4292,28 @@ bin_hash(char *name, char **argv, Options ops, UNUSED(int func))
 	    returnval = 1;
 	    break;
         } else if (ASG_VALUEP(asg)) {
-	    if(isset(RESTRICTED)) {
-		zwarnnam(name, "restricted: %s", asg->value.scalar);
-		returnval = 1;
-	    } else {
-		/* The argument is of the form foo=bar, *
-		 * so define an entry for the table.    */
-		if(OPT_ISSET(ops,'d')) {
-		    /* shouldn't return NULL if asg->name is not NULL */
-		    if (*itype_end(asg->name, IUSER, 0)) {
-			zwarnnam(name,
-				 "invalid character in directory name: %s",
-				 asg->name);
-			returnval = 1;
-			continue;
-		    } else {
-			Nameddir nd = hn = zshcalloc(sizeof *nd);
-			nd->node.flags = 0;
-			nd->dir = ztrdup(asg->value.scalar);
-		    }
+	    /* The argument is of the form foo=bar, *
+	     * so define an entry for the table.    */
+	    if (OPT_ISSET(ops, 'd')) {
+		/* shouldn't return NULL if asg->name is not NULL */
+		if (*itype_end(asg->name, IUSER, 0)) {
+		    zwarnnam(name, "invalid character in directory name: %s",
+			    asg->name);
+		    returnval = 1;
+		    continue;
 		} else {
-		    Cmdnam cn = hn = zshcalloc(sizeof *cn);
-		    cn->node.flags = HASHED;
-		    cn->u.cmd = ztrdup(asg->value.scalar);
+		    Nameddir nd = hn = zshcalloc(sizeof *nd);
+		    nd->node.flags = 0;
+		    nd->dir = ztrdup(asg->value.scalar);
 		}
-		ht->addnode(ht, ztrdup(asg->name), hn);
-		if(OPT_ISSET(ops,'v'))
-		    ht->printnode(hn, 0);
+	    } else {
+		Cmdnam cn = hn = zshcalloc(sizeof *cn);
+		cn->node.flags = HASHED;
+		cn->u.cmd = ztrdup(asg->value.scalar);
 	    }
+	    ht->addnode(ht, ztrdup(asg->name), hn);
+	    if (OPT_ISSET(ops, 'v'))
+		ht->printnode(hn, 0);
 	} else if (!(hn = ht->getnode2(ht, asg->name))) {
 	    /* With no `=value' part to the argument, *
 	     * work out what it ought to be.          */
diff --git a/Src/exec.c b/Src/exec.c
index 27bca110c..93ee7d1da 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -35,8 +35,6 @@
 enum {
     /* Export the variable for "VAR=val cmd ..." */
     ADDVAR_EXPORT =   1 << 0,
-    /* Apply restrictions for variable */
-    ADDVAR_RESTRICT = 1 << 1,
     /* Variable list is being restored later */
     ADDVAR_RESTORE =  1 << 2
 };
@@ -731,10 +729,6 @@ execute(LinkList args, int flags, int defpath)
     int eno = 0, ee;
 
     arg0 = (char *) peekfirst(args);
-    if (isset(RESTRICTED) && (strchr(arg0, '/') || defpath)) {
-	zerr("%s: restricted", arg0);
-	_exit(1);
-    }
 
     /* If the parameter STTY is set in the command's environment, *
      * we first run the stty command with the value of this       *
@@ -755,7 +749,7 @@ execute(LinkList args, int flags, int defpath)
 
     /* If ARGV0 is in the commands environment, we use *
      * that as argv[0] for this external command       */
-    if (unset(RESTRICTED) && (z = zgetenv("ARGV0"))) {
+    if ((z = zgetenv("ARGV0"))) {
 	setdata(firstnode(args), (void *) ztrdup(z));
 	/*
 	 * Note we don't do anything with the parameter structure
@@ -2588,14 +2582,6 @@ addvars(Estate state, Wordcode pc, int addflags)
 		fputc(' ', xtrerr);
 	    }
 	    if ((addflags & ADDVAR_EXPORT) && !strchr(name, '[')) {
-		if ((addflags & ADDVAR_RESTRICT) && isset(RESTRICTED) &&
-		    (pm = (Param) paramtab->removenode(paramtab, name)) &&
-		    (pm->node.flags & PM_RESTRICTED)) {
-		    zerr("%s: restricted", pm->node.nam);
-		    zsfree(val);
-		    state->pc = opc;
-		    return;
-		}
 		if (strcmp(name, "STTY") == 0) {
 		    zsfree(STTYval);
 		    STTYval = ztrdup(val);
@@ -2604,7 +2590,7 @@ addvars(Estate state, Wordcode pc, int addflags)
 		opts[ALLEXPORT] = 1;
 		if (isset(KSHARRAYS))
 		    unsetparam(name);
-	    	pm = assignsparam(name, val, myflags);
+		pm = assignsparam(name, val, myflags);
 		opts[ALLEXPORT] = allexp;
 	    } else
 	    	pm = assignsparam(name, val, myflags);
@@ -3418,15 +3404,6 @@ execcmd_exec(Estate state, Execcmd_params eparams,
 			shelltime(&shti, &chti, &then, 1);
 		    return;
 		}
-	    } else if (isset(RESTRICTED) && (cflags & BINF_EXEC) && do_exec) {
-		zerrnam("exec", "%s: restricted",
-			(char *) getdata(firstnode(args)));
-		lastval = 1;
-		if (forked)
-		    _realexit();
-		if (how & Z_TIMED)
-		    shelltime(&shti, &chti, &then, 1);
-		return;
 	    }
 
 	    /*
@@ -3783,10 +3760,6 @@ execcmd_exec(Estate state, Execcmd_params eparams,
 		fixfds(save);
 		execerr();
 	    }
-	    if (isset(RESTRICTED) && IS_WRITE_FILE(fn->type)) {
-		zwarn("writing redirection not allowed in restricted mode");
-		execerr();
-	    }
 	    if (unset(EXECOPT))
 		continue;
 	    switch(fn->type) {
@@ -4314,7 +4287,7 @@ execcmd_exec(Estate state, Execcmd_params eparams,
 	    }
 	    if (type == WC_SIMPLE || type == WC_TYPESET) {
 		if (varspc) {
-		    int addflags = ADDVAR_EXPORT|ADDVAR_RESTRICT;
+		    int addflags = ADDVAR_EXPORT;
 		    if (forked)
 			addflags |= ADDVAR_RESTORE;
 		    addvars(state, varspc, addflags);
@@ -4463,8 +4436,7 @@ save_params(Estate state, Wordcode pc, LinkList *restore_p, LinkList *remove_p)
 		tpm = (Param) zshcalloc(sizeof *tpm);
 		tpm->node.nam = ztrdup(pm->node.nam);
 		copyparam(tpm, pm, 0);
-	    } else if (!(pm->node.flags & PM_READONLY) &&
-		       (unset(RESTRICTED) || !(pm->node.flags & PM_RESTRICTED))) {
+	    } else if (!(pm->node.flags & PM_READONLY)) {
 		/*
 		 * In this case we're just saving parts of
 		 * the parameter in a temporary, so use heap allocation
@@ -6113,9 +6085,8 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval)
 	    /* take care of SUNKEYBOARDHACK but not of EMACS/VI */
 	    if (funcsave->opts[SUNKEYBOARDHACK] != opts[SUNKEYBOARDHACK])
 		keyboardhackchar = funcsave->opts[SUNKEYBOARDHACK] ? '`' : '\0';
-	    /* restore all shell options except PRIVILEGED and RESTRICTED */
+	    /* restore all shell options except PRIVILEGED */
 	    funcsave->opts[PRIVILEGED] = opts[PRIVILEGED];
-	    funcsave->opts[RESTRICTED] = opts[RESTRICTED];
 	    memcpy(opts, funcsave->opts, sizeof(opts));
 	    emulation = funcsave->emulation;
 	    if (init_typtab)
diff --git a/Src/init.c b/Src/init.c
index 20b8cc7fd..beb9b2c3c 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -255,8 +255,6 @@ loop(int toplevel, int justonce)
     return LOOP_OK;
 }
 
-static int restricted;
-
 /* original argv[0]. This is already metafied */
 static char *argv0;
 
@@ -494,8 +492,6 @@ parseopts(char *nam, char ***argvp, char *new_opts, char **cmdp,
 		if (!(optno = optlookup(*argv))) {
 		    WARN_OPTION("no such option: %s", *argv);
 		    return 1;
-		} else if (optno == RESTRICTED && toplevel) {
-		    restricted = action;
 		} else if ((optno == EMACSMODE || optno == VIMODE) && !toplevel) {
 		    WARN_OPTION("can't change option: %s", *argv);
 		} else {
@@ -524,8 +520,6 @@ parseopts(char *nam, char ***argvp, char *new_opts, char **cmdp,
 	    	if (!(optno = optlookupc(**argv))) {
 		    WARN_OPTION("bad option: -%c", **argv);
 		    return 1;
-		} else if (optno == RESTRICTED && toplevel) {
-		    restricted = action;
 		} else if ((optno == EMACSMODE || optno == VIMODE) &&
 			   !toplevel) {
 		    WARN_OPTION("can't change option: %s", *argv);
@@ -1529,12 +1523,6 @@ run_init_scripts(void)
 void
 init_misc(char *cmd, char *zsh_name)
 {
-#ifndef RESTRICTED_R
-    if ( restricted )
-#else
-    if (*zsh_name == 'r' || restricted)
-#endif
-	dosetopt(RESTRICTED, 1, 0, opts);
     if (cmd) {
 	if (SHIN >= 10)
 	    close(SHIN);
diff --git a/Src/jobs.c b/Src/jobs.c
index 4905ae925..94c0679b1 100644
--- a/Src/jobs.c
+++ b/Src/jobs.c
@@ -2425,10 +2425,6 @@ bin_fg(char *name, char **argv, Options ops, int func)
     if (OPT_ISSET(ops,'Z')) {
 	int len;
 
-	if(isset(RESTRICTED)) {
-	    zwarnnam(name, "-Z is restricted");
-	    return 1;
-	}
 	if(!argv[0] || argv[1]) {
 	    zwarnnam(name, "-Z requires one argument");
 	    return 1;
diff --git a/Src/options.c b/Src/options.c
index 8b13f0c5d..649c654ba 100644
--- a/Src/options.c
+++ b/Src/options.c
@@ -240,7 +240,7 @@ static struct optname optns[] = {
 {{NULL, "rcs",		      OPT_ALL},			 RCS},
 {{NULL, "recexact",	      0},			 RECEXACT},
 {{NULL, "rematchpcre",	      0},			 REMATCHPCRE},
-{{NULL, "restricted",	      OPT_SPECIAL},		 RESTRICTED},
+{{NULL, "restricted",	      0},			 RESTRICTED},
 {{NULL, "rmstarsilent",	      OPT_BOURNE},		 RMSTARSILENT},
 {{NULL, "rmstarwait",	      0},			 RMSTARWAIT},
 {{NULL, "sharehistory",	      OPT_KSH},			 SHAREHISTORY},
@@ -727,25 +727,6 @@ optlookupc(char c)
     return optletters[c - FIRST_OPT];
 }
 
-/**/
-static void
-restrictparam(char *nam)
-{
-    Param pm = (Param) paramtab->getnode(paramtab, nam);
-
-    if (pm) {
-	pm->node.flags |= PM_SPECIAL | PM_RESTRICTED;
-	return;
-    }
-    createparam(nam, PM_SCALAR | PM_UNSET | PM_SPECIAL | PM_RESTRICTED);
-}
-
-/* list of restricted parameters which are not otherwise special */
-static char *rparams[] = {
-    "SHELL", "HISTFILE", "LD_LIBRARY_PATH", "LD_AOUT_LIBRARY_PATH",
-    "LD_PRELOAD", "LD_AOUT_PRELOAD", NULL
-};
-
 /* Set or unset an option, as a result of user request.  The option *
  * number may be negative, indicating that the sense is reversed    *
  * from the usual meaning of the option.                            */
@@ -760,16 +741,7 @@ dosetopt(int optno, int value, int force, char *new_opts)
 	optno = -optno;
 	value = !value;
     }
-    if (optno == RESTRICTED) {
-	if (isset(RESTRICTED))
-	    return value ? 0 : -1;
-	if (value) {
-	    char **s;
-
-	    for (s = rparams; *s; s++)
-		restrictparam(*s);
-	}
-    } else if(!force && optno == EXECOPT && !value && interact) {
+    if (!force && optno == EXECOPT && !value && interact) {
 	/* cannot set noexec when interactive */
 	return -1;
     } else if(!force && (optno == INTERACTIVE || optno == SHINSTDIN ||
diff --git a/Src/params.c b/Src/params.c
index 9d7fbbee1..7179dd793 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -296,18 +296,18 @@ static initparam special_params[] ={
 #define IPDEF1(A,B,C) {{NULL,A,PM_INTEGER|PM_SPECIAL|C},BR(NULL),GSU(B),10,0,NULL,NULL,NULL,0}
 IPDEF1("#", pound_gsu, PM_READONLY_SPECIAL),
 IPDEF1("ERRNO", errno_gsu, PM_UNSET),
-IPDEF1("GID", gid_gsu, PM_DONTIMPORT | PM_RESTRICTED),
-IPDEF1("EGID", egid_gsu, PM_DONTIMPORT | PM_RESTRICTED),
-IPDEF1("HISTSIZE", histsize_gsu, PM_RESTRICTED),
+IPDEF1("GID", gid_gsu, PM_DONTIMPORT),
+IPDEF1("EGID", egid_gsu, PM_DONTIMPORT),
+IPDEF1("HISTSIZE", histsize_gsu, 0),
 IPDEF1("RANDOM", random_gsu, 0),
-IPDEF1("SAVEHIST", savehist_gsu, PM_RESTRICTED),
+IPDEF1("SAVEHIST", savehist_gsu, 0),
 IPDEF1("SECONDS", intseconds_gsu, 0),
-IPDEF1("UID", uid_gsu, PM_DONTIMPORT | PM_RESTRICTED),
-IPDEF1("EUID", euid_gsu, PM_DONTIMPORT | PM_RESTRICTED),
+IPDEF1("UID", uid_gsu, PM_DONTIMPORT),
+IPDEF1("EUID", euid_gsu, PM_DONTIMPORT),
 IPDEF1("TTYIDLE", ttyidle_gsu, PM_READONLY_SPECIAL),
 
 #define IPDEF2(A,B,C) {{NULL,A,PM_SCALAR|PM_SPECIAL|C},BR(NULL),GSU(B),0,0,NULL,NULL,NULL,0}
-IPDEF2("USERNAME", username_gsu, PM_DONTIMPORT|PM_RESTRICTED),
+IPDEF2("USERNAME", username_gsu, PM_DONTIMPORT),
 IPDEF2("-", dash_gsu, PM_READONLY_SPECIAL),
 IPDEF2("histchars", histchars_gsu, PM_DONTIMPORT),
 IPDEF2("HOME", home_gsu, PM_UNSET),
@@ -315,7 +315,7 @@ IPDEF2("TERM", term_gsu, PM_UNSET),
 IPDEF2("TERMINFO", terminfo_gsu, PM_UNSET),
 IPDEF2("TERMINFO_DIRS", terminfodirs_gsu, PM_UNSET),
 IPDEF2("WORDCHARS", wordchars_gsu, 0),
-IPDEF2("IFS", ifs_gsu, PM_DONTIMPORT | PM_RESTRICTED),
+IPDEF2("IFS", ifs_gsu, PM_DONTIMPORT),
 IPDEF2("_", underscore_gsu, PM_DONTIMPORT),
 IPDEF2("KEYBOARD_HACK", keyboard_hack_gsu, PM_DONTIMPORT),
 IPDEF2("0", argzero_gsu, 0),
@@ -396,12 +396,12 @@ IPDEF8("CDPATH", &cdpath, "cdpath", PM_TIED),
 IPDEF8("FIGNORE", &fignore, "fignore", PM_TIED),
 IPDEF8("FPATH", &fpath, "fpath", PM_TIED),
 IPDEF8("MAILPATH", &mailpath, "mailpath", PM_TIED),
-IPDEF8("PATH", &path, "path", PM_RESTRICTED|PM_TIED),
+IPDEF8("PATH", &path, "path", PM_TIED),
 IPDEF8("PSVAR", &psvar, "psvar", PM_TIED),
 IPDEF8("ZSH_EVAL_CONTEXT", &zsh_eval_context, "zsh_eval_context", PM_READONLY_SPECIAL|PM_TIED),
 
 /* MODULE_PATH is not imported for security reasons */
-IPDEF8("MODULE_PATH", &module_path, "module_path", PM_DONTIMPORT|PM_RESTRICTED|PM_TIED),
+IPDEF8("MODULE_PATH", &module_path, "module_path", PM_DONTIMPORT|PM_TIED),
 
 #define IPDEF10(A,B) {{NULL,A,PM_ARRAY|PM_SPECIAL},BR(NULL),GSU(B),10,0,NULL,NULL,NULL,0}
 
@@ -430,8 +430,8 @@ IPDEF9("psvar", &psvar, "PSVAR", PM_TIED),
 
 IPDEF9("zsh_eval_context", &zsh_eval_context, "ZSH_EVAL_CONTEXT", PM_TIED|PM_READONLY_SPECIAL),
 
-IPDEF9("module_path", &module_path, "MODULE_PATH", PM_TIED|PM_RESTRICTED),
-IPDEF9("path", &path, "PATH", PM_TIED|PM_RESTRICTED),
+IPDEF9("module_path", &module_path, "MODULE_PATH", PM_TIED),
+IPDEF9("path", &path, "PATH", PM_TIED),
 
 /* These are known to zsh alone. */
 
@@ -449,12 +449,12 @@ IPDEF8("CDPATH", &cdpath, NULL, 0),
 IPDEF8("FIGNORE", &fignore, NULL, 0),
 IPDEF8("FPATH", &fpath, NULL, 0),
 IPDEF8("MAILPATH", &mailpath, NULL, 0),
-IPDEF8("PATH", &path, NULL, PM_RESTRICTED),
+IPDEF8("PATH", &path, NULL, 0),
 IPDEF8("PSVAR", &psvar, NULL, 0),
 IPDEF8("ZSH_EVAL_CONTEXT", &zsh_eval_context, NULL, PM_READONLY_SPECIAL),
 
 /* MODULE_PATH is not imported for security reasons */
-IPDEF8("MODULE_PATH", &module_path, NULL, PM_DONTIMPORT|PM_RESTRICTED),
+IPDEF8("MODULE_PATH", &module_path, NULL, PM_DONTIMPORT),
 
 {{NULL,NULL,0},BR(NULL),NULL_GSU,0,0,NULL,NULL,NULL,0},
 };
@@ -1083,10 +1083,6 @@ createparam(char *name, int flags)
 		zerr("read-only variable: %s", name);
 		return NULL;
 	    }
-	    if ((oldpm->node.flags & PM_RESTRICTED) && isset(RESTRICTED)) {
-		zerr("%s: restricted", name);
-		return NULL;
-	    }
 	    if (!(oldpm->node.flags & PM_UNSET) ||
 		(oldpm->node.flags & PM_SPECIAL) ||
 		/* POSIXBUILTINS horror: we need to retain 'export' flags */
@@ -2678,11 +2674,6 @@ assignstrvalue(Value v, char *val, int flags)
 	zsfree(val);
 	return;
     }
-    if ((v->pm->node.flags & PM_RESTRICTED) && isset(RESTRICTED)) {
-	zerr("%s: restricted", v->pm->node.nam);
-	zsfree(val);
-	return;
-    }
     if ((v->pm->node.flags & PM_HASHED) &&
 	(v->scanflags & (SCANPM_MATCHMANY|SCANPM_ARRONLY))) {
 	zerr("%s: attempt to set slice of associative array", v->pm->node.nam);
@@ -2847,10 +2838,6 @@ setnumvalue(Value v, mnumber val)
 	zerr("read-only variable: %s", v->pm->node.nam);
 	return;
     }
-    if ((v->pm->node.flags & PM_RESTRICTED) && isset(RESTRICTED)) {
-	zerr("%s: restricted", v->pm->node.nam);
-	return;
-    }
     switch (PM_TYPE(v->pm->node.flags)) {
     case PM_SCALAR:
     case PM_ARRAY:
@@ -2888,11 +2875,6 @@ setarrvalue(Value v, char **val)
 	freearray(val);
 	return;
     }
-    if ((v->pm->node.flags & PM_RESTRICTED) && isset(RESTRICTED)) {
-	zerr("%s: restricted", v->pm->node.nam);
-	freearray(val);
-	return;
-    }
     if (!(PM_TYPE(v->pm->node.flags) & (PM_ARRAY|PM_HASHED))) {
 	freearray(val);
 	zerr("%s: attempt to assign array value to non-array",
@@ -3839,10 +3821,6 @@ unsetparam_pm(Param pm, int altflag, int exp)
 	     pm->node.nam);
 	return 1;
     }
-    if ((pm->node.flags & PM_RESTRICTED) && isset(RESTRICTED)) {
-	zerr("%s: restricted", pm->node.nam);
-	return 1;
-    }
 
     if (pm->ename && !altflag)
 	altremove = ztrdup(pm->ename);
diff --git a/Src/signals.c b/Src/signals.c
index 2257f862f..ff9797f35 100644
--- a/Src/signals.c
+++ b/Src/signals.c
@@ -451,7 +451,7 @@ zhandler(int sig)
  
     case SIGINT:
         if (!handletrap(SIGINT)) {
-	    if ((isset(PRIVILEGED) || isset(RESTRICTED)) &&
+	    if (isset(PRIVILEGED) &&
 		isset(INTERACTIVE) && (noerrexit & NOERREXIT_SIGNAL))
 		zexit(SIGINT, ZEXIT_SIGNAL);
             errflag |= ERRFLAG_INT;
diff --git a/Src/zsh.h b/Src/zsh.h
index 5bda04e88..9fcbeb1cb 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -1926,7 +1926,7 @@ struct tieddata {
 #define PM_READONLY_SPECIAL (PM_SPECIAL|PM_READONLY|PM_RO_BY_DESIGN)
 #define PM_DONTIMPORT	(1<<22)	/* do not import this variable              */
 #define PM_DECLARED	(1<<22) /* explicitly named with typeset            */
-#define PM_RESTRICTED	(1<<23) /* cannot be changed in restricted mode     */
+#define PM_RESTRICTED	(1<<23) /* only used in the param/private module    */
 #define PM_UNSET	(1<<24)	/* has null value                           */
 #define PM_DEFAULTED	(PM_DECLARED|PM_UNSET)
 #define PM_REMOVABLE	(1<<25)	/* special can be removed from paramtab     */
diff --git a/Test/E01options.ztst b/Test/E01options.ztst
index 969bd42d5..dcb14e013 100644
--- a/Test/E01options.ztst
+++ b/Test/E01options.ztst
@@ -1013,24 +1013,6 @@
 >one'quoted'expression
 >anotherquotedexpression
 
-# too lazy to test jobs -Z and ARGV0.
-  (setopt restricted; cd /)
-  (setopt restricted; PATH=/bin:/usr/bin)
-  (setopt restricted; /bin/ls)
-  (setopt restricted; hash ls=/bin/ls)
-  (setopt restricted; print ha >outputfile)
-  (setopt restricted; exec ls)
-  (setopt restricted; unsetopt restricted)
-  :
-0:RESTRICTED option
-?(eval):cd:1: restricted
-?(eval):2: PATH: restricted
-?(eval):3: /bin/ls: restricted
-?(eval):hash:4: restricted: /bin/ls
-?(eval):5: writing redirection not allowed in restricted mode
-?(eval):exec:6: ls: restricted
-?(eval):unsetopt:7: can't change option: restricted
-
 # ' emacs deconfusion
 
   fn() {
diff --git a/configure.ac b/configure.ac
index dee62dd5e..5002cca8b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -248,20 +248,6 @@ AC_ARG_ENABLE(dynamic,
 AS_HELP_STRING([--disable-dynamic],[turn off dynamically loaded binary modules]),
 [dynamic="$enableval"], [dynamic=yes])
 
-dnl Do you want to disable restricted on r* commands
-ifdef([restricted-r],[undefine([restricted-r])])dnl
-AH_TEMPLATE([RESTRICTED_R],
-[Undefine this if you don't want to get a restricted shell
- when zsh is exec'd with basename that starts with r.
- By default this is defined.])
-AC_ARG_ENABLE(restricted-r,
-AS_HELP_STRING([--disable-restricted-r],[turn off r* invocation for restricted shell]),
-[if test x$enableval = xyes; then
-  AC_DEFINE(RESTRICTED_R)
-fi],
-AC_DEFINE(RESTRICTED_R)
-)
-
 dnl Do you want to disable use of locale functions
 AH_TEMPLATE([CONFIG_LOCALE],
 [Undefine if you don't want local features.  By default this is defined.])




Messages sorted by: Reverse Date, Date, Thread, Author