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
- X-seq: zsh-workers 54182
- From: cyber security <cs7778503@xxxxxxxxx>
- To: Oliver Kiddle <opk@xxxxxxx>
- Cc: zsh-workers@xxxxxxx
- Subject: Re: Security issue in Zsh restricted mode (zsh -r) – escape via history built‑ins
- Date: Tue, 10 Feb 2026 22:14:32 -0800
- Arc-authentication-results: i=1; mx.google.com; arc=none
- Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=6zguUHfK4hEB7fEwtjWOMCbFRyN3EwGnDBTZ8U6rT3s=; fh=2tfr1lXayzVavkTg6fWPRiWcFKi2aZa5ShWfwjU9vZo=; b=IZAD0Dd3IhrcEq57soC58LXi+zoTPnQpXVh5RYyXp4ggo4saJncUvkA42LVRlmkhZH BleUSlMRAcKSU29ZSti8oyh54TEzYzUJ3X+efHpmwCvStjWDtjVi6HQk7NtD0AwHT0FW g8652X3Pe5NRMDtftMKxSJW00UmqN7nJB2JXJPTO6I97gszM/D1LwGc+L9Hu9aemQ9Du zhLWLGtGDjYNqoJVFUy/sBqsAmIMg33ziDyhbLgQsqxVBsENDf9jQmjuVYOdLVkILYGH qfjwRBasgRFdweE6z3opSEqPbkjfT39f1t1Vf4kjf546K+0BCrFDk2PYa9IDL5k+OZwG i5fg==; darn=zsh.org
- Arc-seal: i=1; a=rsa-sha256; t=1770790472; cv=none; d=google.com; s=arc-20240605; b=i9G0orAk6GkiYWNKy6Q4sUC2RxrpE9Bu148kUjSGjPpy83nurnGf8gbXS96HdeZtCS QCfketrjgCS4Np/4LJIgaTRo499VtoHbpqiVFDBl5Su+QpRvfYsnGp3OiQES1aJnM9Oz VDchlQfyj/YXl26FdX/ktuEuxljgXo3g3qTkj6UfPthWbuoctsGOYhrEnVqlR6czFUsf ljX6J1kkTRneXvHFiL6HpPNJq3TSbYe7qkLuYfNbCq/JLGI1FNAWadTTb9w89Gvb8wk1 zeYU+F+A5KH6xCedRpx34RpxidRZnxp1EP5FbKhv99QJELBv3eSB9oJyCjzyESpZkspI S2Mw==
- Archived-at: <https://zsh.org/workers/54182>
- In-reply-to: <59616-1770769280.438132@XTM7.n7uI.5s3U>
- List-id: <zsh-workers.zsh.org>
- References: <CAPmip_z18_wQBZ09GG7TEKZ0GsTqQ34iZRvhsMAExOLSCcdQsg@mail.gmail.com> <72787-1769800688.979791@U6Lk.sn9M.AyYc> <CAHYJk3T4W+U3mCzqGB7LUkJp-JuUSiEBNe4hx0e-=zMyZQuPGQ@mail.gmail.com> <62255-1769947817.277408@Fj-1.JoGb.8iVT> <59616-1770769280.438132@XTM7.n7uI.5s3U>
I agree with you. Yes disable those local functions!
On Tue, Feb 10, 2026 at 4:21 PM Oliver Kiddle <opk@xxxxxxx> wrote:
>
> 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