mirror of
https://git.code.sf.net/p/zsh/code
synced 2026-04-18 06:53:35 -04:00
54181, 54331: remove support for restricted shell
This is in response to a security report. There are too many potential ways to break out of a restricted shell and more secure, modern alternatives exist.
This commit is contained in:
11
ChangeLog
11
ChangeLog
@@ -1,3 +1,14 @@
|
|||||||
|
2026-04-14 Oliver Kiddle <opk@zsh.org>
|
||||||
|
|
||||||
|
* 54181, 54331: Completion/Zsh/Command/_set,
|
||||||
|
Doc/Makefile.in, Doc/Zsh/builtins.yo, Doc/Zsh/compat.yo,
|
||||||
|
Doc/Zsh/grammar.yo, Doc/Zsh/invoke.yo, Doc/Zsh/manual.yo,
|
||||||
|
Doc/Zsh/options.yo, Doc/Zsh/restricted.yo, README,
|
||||||
|
Src/Modules/db_gdbm.c, Src/Modules/parameter.c, Src/builtin.c,
|
||||||
|
Src/exec.c, Src/init.c, Src/jobs.c, Src/options.c, Src/params.c,
|
||||||
|
Src/signals.c, Test/E01options.ztst, configure.ac:
|
||||||
|
remove support for restricted shell
|
||||||
|
|
||||||
2026-04-13 dana <dana@dana.is>
|
2026-04-13 dana <dana@dana.is>
|
||||||
|
|
||||||
* dana + Jun T: 54329 + 54339: Doc/Makefile.in, Doc/intro.ms:
|
* dana + Jun T: 54329 + 54339: Doc/Makefile.in, Doc/intro.ms:
|
||||||
|
|||||||
@@ -21,5 +21,5 @@ noglob _arguments -s -S \
|
|||||||
{-,+}d[no-globalrcs] {-,+}e[errexit] {-,+}f[no-rcs] {-,+}g[histignorespace] \
|
{-,+}d[no-globalrcs] {-,+}e[errexit] {-,+}f[no-rcs] {-,+}g[histignorespace] \
|
||||||
{-,+}h[histignoredups] {-,+}i[interactive] {-,+}k[interactivecomments] \
|
{-,+}h[histignoredups] {-,+}i[interactive] {-,+}k[interactivecomments] \
|
||||||
{-,+}l[login] {-,+}m[monitor] {-,+}n[no-exec] {-,+}p[privileged] \
|
{-,+}l[login] {-,+}m[monitor] {-,+}n[no-exec] {-,+}p[privileged] \
|
||||||
{-,+}r[restricted] {-,+}t[singlecommand] {-,+}u[no-unset] {-,+}v[verbose] \
|
{-,+}t[singlecommand] {-,+}u[no-unset] {-,+}v[verbose] \
|
||||||
{-,+}w[chaselinks] {-,+}x[xtrace] {-,+}y[shwordsplit]
|
{-,+}w[chaselinks] {-,+}x[xtrace] {-,+}y[shwordsplit]
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ Zsh/filelist.yo Zsh/files.yo \
|
|||||||
Zsh/func.yo Zsh/grammar.yo Zsh/manual.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/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/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
|
Zsh/seealso.yo Zsh/tcpsys.yo Zsh/zftpsys.yo Zsh/zle.yo
|
||||||
|
|
||||||
# ========== DEPENDENCIES FOR BUILDING ==========
|
# ========== 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.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/filelist.yo Zsh/filelist.yo Zsh/seealso.yo \
|
||||||
Zsh/compat.yo Zsh/restricted.yo
|
Zsh/compat.yo
|
||||||
|
|
||||||
zshbuiltins.1: Zsh/builtins.yo
|
zshbuiltins.1: Zsh/builtins.yo
|
||||||
|
|
||||||
|
|||||||
@@ -570,8 +570,7 @@ change.
|
|||||||
|
|
||||||
The var(flags) may be any of the invocation-time flags described in
|
The var(flags) may be any of the invocation-time flags described in
|
||||||
sectref(Invocation)(zsh),
|
sectref(Invocation)(zsh),
|
||||||
except that `tt(-o EMACS)' and `tt(-o VI)' may not be used. Flags such
|
except that `tt(-o EMACS)' and `tt(-o VI)' may not be used.
|
||||||
as `tt(+r)'/`tt(+o RESTRICTED)' may be prohibited in some circumstances.
|
|
||||||
|
|
||||||
If tt(-c) var(arg) appears in var(flags), var(arg) is evaluated while the
|
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
|
requested emulation is temporarily in effect. In this case the emulation
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
texinode(Compatibility)(Restricted Shell)()(Invocation)
|
texinode(Compatibility)()()(Invocation)
|
||||||
sect(Compatibility)
|
sect(Compatibility)
|
||||||
cindex(compatibility)
|
cindex(compatibility)
|
||||||
cindex(sh compatibility)
|
cindex(sh compatibility)
|
||||||
cindex(ksh compatibility)
|
cindex(ksh compatibility)
|
||||||
Zsh tries to emulate bf(sh) or bf(ksh) when it is invoked as
|
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
|
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)'
|
letter of the name by which it was invoked, and if that is `tt(b)', `tt(s)' or `tt(k)' it
|
||||||
(assumed to stand for `restricted'), 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
|
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)
|
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)
|
command), the shell will try to find an alternative name from the tt(SHELL)
|
||||||
|
|||||||
@@ -531,7 +531,6 @@ itemiz(Execution of incorrectly positioned loop control structures
|
|||||||
(tt(continue), tt(break)))
|
(tt(continue), tt(break)))
|
||||||
itemiz(Attempts to use regular expression with no regular expression
|
itemiz(Attempts to use regular expression with no regular expression
|
||||||
module available)
|
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 pipe needed for a pipeline)
|
||||||
itemiz(Failure to create a multio)
|
itemiz(Failure to create a multio)
|
||||||
itemiz(Failure to autoload a module needed for a declared shell feature)
|
itemiz(Failure to autoload a module needed for a declared shell feature)
|
||||||
|
|||||||
@@ -105,8 +105,6 @@ can be stacked after the `tt(-b)' and will take effect as normal.
|
|||||||
|
|
||||||
startmenu()
|
startmenu()
|
||||||
menu(Compatibility)
|
menu(Compatibility)
|
||||||
menu(Restricted Shell)
|
|
||||||
endmenu()
|
endmenu()
|
||||||
|
|
||||||
includefile(Zsh/compat.yo)
|
includefile(Zsh/compat.yo)
|
||||||
includefile(Zsh/restricted.yo)
|
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ menu(See Also)
|
|||||||
Invocation
|
Invocation
|
||||||
|
|
||||||
menu(Compatibility)
|
menu(Compatibility)
|
||||||
menu(Restricted Shell)
|
|
||||||
|
|
||||||
Shell Grammar
|
Shell Grammar
|
||||||
|
|
||||||
|
|||||||
@@ -1837,8 +1837,8 @@ pindex(NOLOCALOPTIONS)
|
|||||||
item(tt(LOCAL_OPTIONS) <K>)(
|
item(tt(LOCAL_OPTIONS) <K>)(
|
||||||
If this option is set at the point of return from a shell function,
|
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
|
most options (including this one) which were in force upon entry to
|
||||||
the function are restored; options that are not restored are
|
the function are restored; the tt(PRIVILEGED) option is not restored.
|
||||||
tt(PRIVILEGED) and tt(RESTRICTED). Otherwise, only this option,
|
Otherwise, only this option,
|
||||||
and the tt(LOCAL_LOOPS), tt(XTRACE) and tt(PRINT_EXIT_VALUE) options are
|
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
|
restored. Hence if this is explicitly unset by a shell function the
|
||||||
other options in force at the point of return will remain so.
|
other options in force at the point of return will remain so.
|
||||||
@@ -2466,16 +2466,6 @@ tt(-m) option of tt(setopt) and tt(unsetopt), and changing it inside a
|
|||||||
function always changes it globally regardless of the tt(LOCAL_OPTIONS)
|
function always changes it globally regardless of the tt(LOCAL_OPTIONS)
|
||||||
option.
|
option.
|
||||||
)
|
)
|
||||||
pindex(RESTRICTED)
|
|
||||||
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).
|
|
||||||
)
|
|
||||||
pindex(SHIN_STDIN)
|
pindex(SHIN_STDIN)
|
||||||
pindex(NO_SHIN_STDIN)
|
pindex(NO_SHIN_STDIN)
|
||||||
pindex(SHINSTDIN)
|
pindex(SHINSTDIN)
|
||||||
|
|||||||
@@ -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.
|
|
||||||
5
README
5
README
@@ -52,6 +52,11 @@ or, if your $VISUAL and $EDITOR environment variables vary,
|
|||||||
to your .zshrc file. These snippets are compatible with previous
|
to your .zshrc file. These snippets are compatible with previous
|
||||||
versions of the shell.
|
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-
|
The ERR_EXIT and ERR_RETURN options were refined to be more self-
|
||||||
consistent and better aligned with the POSIX-2017 specification of
|
consistent and better aligned with the POSIX-2017 specification of
|
||||||
`set -e`:
|
`set -e`:
|
||||||
|
|||||||
@@ -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
|
* We need to do this before attempting to open the DB
|
||||||
* in case this variable is already tied to a 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
|
* We could call unsetparam() and check errflag instead
|
||||||
* of the return status.
|
* of the return status.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -150,17 +150,12 @@ scanpmparameters(UNUSED(HashTable ht), ScanFunc func, int flags)
|
|||||||
static void
|
static void
|
||||||
setpmcommand(Param pm, char *value)
|
setpmcommand(Param pm, char *value)
|
||||||
{
|
{
|
||||||
if (isset(RESTRICTED)) {
|
Cmdnam cn = zshcalloc(sizeof(*cn));
|
||||||
zwarn("restricted: %s", value);
|
|
||||||
zsfree(value);
|
|
||||||
} else {
|
|
||||||
Cmdnam cn = zshcalloc(sizeof(*cn));
|
|
||||||
|
|
||||||
cn->node.flags = HASHED;
|
cn->node.flags = HASHED;
|
||||||
cn->u.cmd = value;
|
cn->u.cmd = value;
|
||||||
|
|
||||||
cmdnamtab->addnode(cmdnamtab, ztrdup(pm->node.nam), &cn->node);
|
cmdnamtab->addnode(cmdnamtab, ztrdup(pm->node.nam), &cn->node);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
@@ -841,10 +841,6 @@ bin_cd(char *nam, char **argv, Options ops, int func)
|
|||||||
{
|
{
|
||||||
LinkNode dir;
|
LinkNode dir;
|
||||||
|
|
||||||
if (isset(RESTRICTED)) {
|
|
||||||
zwarnnam(nam, "restricted");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
doprintdir = (doprintdir == -1);
|
doprintdir = (doprintdir == -1);
|
||||||
|
|
||||||
chasinglinks = OPT_ISSET(ops,'P') ||
|
chasinglinks = OPT_ISSET(ops,'P') ||
|
||||||
@@ -2250,10 +2246,6 @@ typeset_single(char *cname, char *pname, Param pm, int func,
|
|||||||
paramtab->printnode(&pm->node, PRINT_INCLUDEVALUE|with_ns);
|
paramtab->printnode(&pm->node, PRINT_INCLUDEVALUE|with_ns);
|
||||||
return pm;
|
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) &&
|
if ((pm->node.flags & PM_READONLY) && !(off & PM_READONLY) &&
|
||||||
/* It seems as though these checks should not be specific to
|
/* It seems as though these checks should not be specific to
|
||||||
* PM_NAMEREF, but changing that changes historic behavior */
|
* PM_NAMEREF, but changing that changes historic behavior */
|
||||||
@@ -2388,10 +2380,6 @@ typeset_single(char *cname, char *pname, Param pm, int func,
|
|||||||
|
|
||||||
if (newspecial != NS_NONE) {
|
if (newspecial != NS_NONE) {
|
||||||
Param tpm, pm2;
|
Param tpm, pm2;
|
||||||
if ((pm->node.flags & PM_RESTRICTED) && isset(RESTRICTED)) {
|
|
||||||
zerrnam(cname, "%s: restricted", pname);
|
|
||||||
return pm;
|
|
||||||
}
|
|
||||||
if (pm->node.flags & PM_SINGLE) {
|
if (pm->node.flags & PM_SINGLE) {
|
||||||
zerrnam(cname, "%s: can only have a single instance", pname);
|
zerrnam(cname, "%s: can only have a single instance", pname);
|
||||||
return pm;
|
return pm;
|
||||||
@@ -2633,12 +2621,7 @@ typeset_single(char *cname, char *pname, Param pm, int func,
|
|||||||
pm->gsu.s->setfn(pm, ztrdup(""));
|
pm->gsu.s->setfn(pm, ztrdup(""));
|
||||||
break;
|
break;
|
||||||
case PM_INTEGER:
|
case PM_INTEGER:
|
||||||
/*
|
pm->gsu.i->setfn(pm, 0);
|
||||||
* 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);
|
|
||||||
break;
|
break;
|
||||||
case PM_EFLOAT:
|
case PM_EFLOAT:
|
||||||
case PM_FFLOAT:
|
case PM_FFLOAT:
|
||||||
@@ -3098,8 +3081,7 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func)
|
|||||||
for (i = 0; i < paramtab->hsize; i++) {
|
for (i = 0; i < paramtab->hsize; i++) {
|
||||||
for (pm = (Param) paramtab->nodes[i]; pm;
|
for (pm = (Param) paramtab->nodes[i]; pm;
|
||||||
pm = (Param) pm->node.next) {
|
pm = (Param) pm->node.next) {
|
||||||
if (((pm->node.flags & PM_RESTRICTED) && isset(RESTRICTED)) ||
|
if (pm->node.flags & PM_UNSET)
|
||||||
(pm->node.flags & PM_UNSET))
|
|
||||||
continue;
|
continue;
|
||||||
if (pattry(pprog, pm->node.nam))
|
if (pattry(pprog, pm->node.nam))
|
||||||
addlinknode(pmlist, pm);
|
addlinknode(pmlist, pm);
|
||||||
@@ -3857,9 +3839,7 @@ bin_unset(char *name, char **argv, Options ops, int func)
|
|||||||
for (pm = (Param) paramtab->nodes[i]; pm; pm = next) {
|
for (pm = (Param) paramtab->nodes[i]; pm; pm = next) {
|
||||||
/* record pointer to next, since we may free this one */
|
/* record pointer to next, since we may free this one */
|
||||||
next = (Param) pm->node.next;
|
next = (Param) pm->node.next;
|
||||||
if ((!(pm->node.flags & PM_RESTRICTED) ||
|
if (pattry(pprog, pm->node.nam)) {
|
||||||
unset(RESTRICTED)) &&
|
|
||||||
pattry(pprog, pm->node.nam)) {
|
|
||||||
if (!OPT_ISSET(ops,'n') &&
|
if (!OPT_ISSET(ops,'n') &&
|
||||||
(pm->node.flags & PM_NAMEREF) && pm->u.str)
|
(pm->node.flags & PM_NAMEREF) && pm->u.str)
|
||||||
unsetparam(pm->u.str);
|
unsetparam(pm->u.str);
|
||||||
@@ -3912,10 +3892,7 @@ bin_unset(char *name, char **argv, Options ops, int func)
|
|||||||
*/
|
*/
|
||||||
if (!pm)
|
if (!pm)
|
||||||
continue;
|
continue;
|
||||||
else if ((pm->node.flags & PM_RESTRICTED) && isset(RESTRICTED)) {
|
else if (ss) {
|
||||||
zerrnam(name, "%s: restricted", pm->node.nam);
|
|
||||||
returnval = 1;
|
|
||||||
} else if (ss) {
|
|
||||||
if ((pm->node.flags & PM_NAMEREF) &&
|
if ((pm->node.flags & PM_NAMEREF) &&
|
||||||
(!(pm = resolve_nameref(pm)) || pm->width)) {
|
(!(pm = resolve_nameref(pm)) || pm->width)) {
|
||||||
/* warning? */
|
/* warning? */
|
||||||
@@ -4317,34 +4294,28 @@ bin_hash(char *name, char **argv, Options ops, UNUSED(int func))
|
|||||||
returnval = 1;
|
returnval = 1;
|
||||||
break;
|
break;
|
||||||
} else if (ASG_VALUEP(asg)) {
|
} else if (ASG_VALUEP(asg)) {
|
||||||
if(isset(RESTRICTED)) {
|
/* The argument is of the form foo=bar, *
|
||||||
zwarnnam(name, "restricted: %s", asg->value.scalar);
|
* so define an entry for the table. */
|
||||||
returnval = 1;
|
if (OPT_ISSET(ops, 'd')) {
|
||||||
} else {
|
/* shouldn't return NULL if asg->name is not NULL */
|
||||||
/* The argument is of the form foo=bar, *
|
if (*itype_end(asg->name, IUSER, 0)) {
|
||||||
* so define an entry for the table. */
|
zwarnnam(name, "invalid character in directory name: %s",
|
||||||
if(OPT_ISSET(ops,'d')) {
|
asg->name);
|
||||||
/* shouldn't return NULL if asg->name is not NULL */
|
returnval = 1;
|
||||||
if (*itype_end(asg->name, IUSER, 0)) {
|
continue;
|
||||||
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);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Cmdnam cn = hn = zshcalloc(sizeof *cn);
|
Nameddir nd = hn = zshcalloc(sizeof *nd);
|
||||||
cn->node.flags = HASHED;
|
nd->node.flags = 0;
|
||||||
cn->u.cmd = ztrdup(asg->value.scalar);
|
nd->dir = ztrdup(asg->value.scalar);
|
||||||
}
|
}
|
||||||
ht->addnode(ht, ztrdup(asg->name), hn);
|
} else {
|
||||||
if(OPT_ISSET(ops,'v'))
|
Cmdnam cn = hn = zshcalloc(sizeof *cn);
|
||||||
ht->printnode(hn, 0);
|
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))) {
|
} else if (!(hn = ht->getnode2(ht, asg->name))) {
|
||||||
/* With no `=value' part to the argument, *
|
/* With no `=value' part to the argument, *
|
||||||
* work out what it ought to be. */
|
* work out what it ought to be. */
|
||||||
|
|||||||
39
Src/exec.c
39
Src/exec.c
@@ -35,8 +35,6 @@
|
|||||||
enum {
|
enum {
|
||||||
/* Export the variable for "VAR=val cmd ..." */
|
/* Export the variable for "VAR=val cmd ..." */
|
||||||
ADDVAR_EXPORT = 1 << 0,
|
ADDVAR_EXPORT = 1 << 0,
|
||||||
/* Apply restrictions for variable */
|
|
||||||
ADDVAR_RESTRICT = 1 << 1,
|
|
||||||
/* Variable list is being restored later */
|
/* Variable list is being restored later */
|
||||||
ADDVAR_RESTORE = 1 << 2
|
ADDVAR_RESTORE = 1 << 2
|
||||||
};
|
};
|
||||||
@@ -731,10 +729,6 @@ execute(LinkList args, int flags, int defpath)
|
|||||||
int eno = 0, ee;
|
int eno = 0, ee;
|
||||||
|
|
||||||
arg0 = (char *) peekfirst(args);
|
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, *
|
/* If the parameter STTY is set in the command's environment, *
|
||||||
* we first run the stty command with the value of this *
|
* 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 *
|
/* If ARGV0 is in the commands environment, we use *
|
||||||
* that as argv[0] for this external command */
|
* that as argv[0] for this external command */
|
||||||
if (unset(RESTRICTED) && (z = zgetenv("ARGV0"))) {
|
if ((z = zgetenv("ARGV0"))) {
|
||||||
setdata(firstnode(args), (void *) ztrdup(z));
|
setdata(firstnode(args), (void *) ztrdup(z));
|
||||||
/*
|
/*
|
||||||
* Note we don't do anything with the parameter structure
|
* Note we don't do anything with the parameter structure
|
||||||
@@ -2588,14 +2582,6 @@ addvars(Estate state, Wordcode pc, int addflags)
|
|||||||
fputc(' ', xtrerr);
|
fputc(' ', xtrerr);
|
||||||
}
|
}
|
||||||
if ((addflags & ADDVAR_EXPORT) && !strchr(name, '[')) {
|
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) {
|
if (strcmp(name, "STTY") == 0) {
|
||||||
zsfree(STTYval);
|
zsfree(STTYval);
|
||||||
STTYval = ztrdup(val);
|
STTYval = ztrdup(val);
|
||||||
@@ -2604,7 +2590,7 @@ addvars(Estate state, Wordcode pc, int addflags)
|
|||||||
opts[ALLEXPORT] = 1;
|
opts[ALLEXPORT] = 1;
|
||||||
if (isset(KSHARRAYS))
|
if (isset(KSHARRAYS))
|
||||||
unsetparam(name);
|
unsetparam(name);
|
||||||
pm = assignsparam(name, val, myflags);
|
pm = assignsparam(name, val, myflags);
|
||||||
opts[ALLEXPORT] = allexp;
|
opts[ALLEXPORT] = allexp;
|
||||||
} else
|
} else
|
||||||
pm = assignsparam(name, val, myflags);
|
pm = assignsparam(name, val, myflags);
|
||||||
@@ -3418,15 +3404,6 @@ execcmd_exec(Estate state, Execcmd_params eparams,
|
|||||||
shelltime(&shti, &chti, &then, 1);
|
shelltime(&shti, &chti, &then, 1);
|
||||||
return;
|
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);
|
fixfds(save);
|
||||||
execerr();
|
execerr();
|
||||||
}
|
}
|
||||||
if (isset(RESTRICTED) && IS_WRITE_FILE(fn->type)) {
|
|
||||||
zwarn("writing redirection not allowed in restricted mode");
|
|
||||||
execerr();
|
|
||||||
}
|
|
||||||
if (unset(EXECOPT))
|
if (unset(EXECOPT))
|
||||||
continue;
|
continue;
|
||||||
switch(fn->type) {
|
switch(fn->type) {
|
||||||
@@ -4314,7 +4287,7 @@ execcmd_exec(Estate state, Execcmd_params eparams,
|
|||||||
}
|
}
|
||||||
if (type == WC_SIMPLE || type == WC_TYPESET) {
|
if (type == WC_SIMPLE || type == WC_TYPESET) {
|
||||||
if (varspc) {
|
if (varspc) {
|
||||||
int addflags = ADDVAR_EXPORT|ADDVAR_RESTRICT;
|
int addflags = ADDVAR_EXPORT;
|
||||||
if (forked)
|
if (forked)
|
||||||
addflags |= ADDVAR_RESTORE;
|
addflags |= ADDVAR_RESTORE;
|
||||||
addvars(state, varspc, addflags);
|
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 = (Param) zshcalloc(sizeof *tpm);
|
||||||
tpm->node.nam = ztrdup(pm->node.nam);
|
tpm->node.nam = ztrdup(pm->node.nam);
|
||||||
copyparam(tpm, pm, 0);
|
copyparam(tpm, pm, 0);
|
||||||
} else if (!(pm->node.flags & PM_READONLY) &&
|
} else if (!(pm->node.flags & PM_READONLY)) {
|
||||||
(unset(RESTRICTED) || !(pm->node.flags & PM_RESTRICTED))) {
|
|
||||||
/*
|
/*
|
||||||
* In this case we're just saving parts of
|
* In this case we're just saving parts of
|
||||||
* the parameter in a temporary, so use heap allocation
|
* the parameter in a temporary, so use heap allocation
|
||||||
@@ -6114,9 +6086,8 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval)
|
|||||||
/* take care of SUNKEYBOARDHACK but not of EMACS/VI */
|
/* take care of SUNKEYBOARDHACK but not of EMACS/VI */
|
||||||
if (funcsave->opts[SUNKEYBOARDHACK] != opts[SUNKEYBOARDHACK])
|
if (funcsave->opts[SUNKEYBOARDHACK] != opts[SUNKEYBOARDHACK])
|
||||||
keyboardhackchar = funcsave->opts[SUNKEYBOARDHACK] ? '`' : '\0';
|
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[PRIVILEGED] = opts[PRIVILEGED];
|
||||||
funcsave->opts[RESTRICTED] = opts[RESTRICTED];
|
|
||||||
memcpy(opts, funcsave->opts, sizeof(opts));
|
memcpy(opts, funcsave->opts, sizeof(opts));
|
||||||
emulation = funcsave->emulation;
|
emulation = funcsave->emulation;
|
||||||
if (init_typtab)
|
if (init_typtab)
|
||||||
|
|||||||
16
Src/init.c
16
Src/init.c
@@ -255,8 +255,6 @@ loop(int toplevel, int justonce)
|
|||||||
return LOOP_OK;
|
return LOOP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int restricted;
|
|
||||||
|
|
||||||
/* original argv[0]. This is already metafied */
|
/* original argv[0]. This is already metafied */
|
||||||
static char *argv0;
|
static char *argv0;
|
||||||
|
|
||||||
@@ -494,8 +492,6 @@ parseopts(char *nam, char ***argvp, char *new_opts, char **cmdp,
|
|||||||
if (!(optno = optlookup(*argv))) {
|
if (!(optno = optlookup(*argv))) {
|
||||||
WARN_OPTION("no such option: %s", *argv);
|
WARN_OPTION("no such option: %s", *argv);
|
||||||
return 1;
|
return 1;
|
||||||
} else if (optno == RESTRICTED && toplevel) {
|
|
||||||
restricted = action;
|
|
||||||
} else if ((optno == EMACSMODE || optno == VIMODE) && !toplevel) {
|
} else if ((optno == EMACSMODE || optno == VIMODE) && !toplevel) {
|
||||||
WARN_OPTION("can't change option: %s", *argv);
|
WARN_OPTION("can't change option: %s", *argv);
|
||||||
} else {
|
} else {
|
||||||
@@ -524,8 +520,6 @@ parseopts(char *nam, char ***argvp, char *new_opts, char **cmdp,
|
|||||||
if (!(optno = optlookupc(**argv))) {
|
if (!(optno = optlookupc(**argv))) {
|
||||||
WARN_OPTION("bad option: -%c", **argv);
|
WARN_OPTION("bad option: -%c", **argv);
|
||||||
return 1;
|
return 1;
|
||||||
} else if (optno == RESTRICTED && toplevel) {
|
|
||||||
restricted = action;
|
|
||||||
} else if ((optno == EMACSMODE || optno == VIMODE) &&
|
} else if ((optno == EMACSMODE || optno == VIMODE) &&
|
||||||
!toplevel) {
|
!toplevel) {
|
||||||
WARN_OPTION("can't change option: %s", *argv);
|
WARN_OPTION("can't change option: %s", *argv);
|
||||||
@@ -1529,12 +1523,10 @@ run_init_scripts(void)
|
|||||||
void
|
void
|
||||||
init_misc(char *cmd, char *zsh_name)
|
init_misc(char *cmd, char *zsh_name)
|
||||||
{
|
{
|
||||||
#ifndef RESTRICTED_R
|
if (*zsh_name == 'r') {
|
||||||
if ( restricted )
|
zerrnam(zsh_name, "no support for restricted mode");
|
||||||
#else
|
exit(1);
|
||||||
if (*zsh_name == 'r' || restricted)
|
}
|
||||||
#endif
|
|
||||||
dosetopt(RESTRICTED, 1, 0, opts);
|
|
||||||
if (cmd) {
|
if (cmd) {
|
||||||
if (SHIN >= 10)
|
if (SHIN >= 10)
|
||||||
close(SHIN);
|
close(SHIN);
|
||||||
|
|||||||
@@ -2425,10 +2425,6 @@ bin_fg(char *name, char **argv, Options ops, int func)
|
|||||||
if (OPT_ISSET(ops,'Z')) {
|
if (OPT_ISSET(ops,'Z')) {
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if(isset(RESTRICTED)) {
|
|
||||||
zwarnnam(name, "-Z is restricted");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if(!argv[0] || argv[1]) {
|
if(!argv[0] || argv[1]) {
|
||||||
zwarnnam(name, "-Z requires one argument");
|
zwarnnam(name, "-Z requires one argument");
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -240,7 +240,6 @@ static struct optname optns[] = {
|
|||||||
{{NULL, "rcs", OPT_ALL}, RCS},
|
{{NULL, "rcs", OPT_ALL}, RCS},
|
||||||
{{NULL, "recexact", 0}, RECEXACT},
|
{{NULL, "recexact", 0}, RECEXACT},
|
||||||
{{NULL, "rematchpcre", 0}, REMATCHPCRE},
|
{{NULL, "rematchpcre", 0}, REMATCHPCRE},
|
||||||
{{NULL, "restricted", OPT_SPECIAL}, RESTRICTED},
|
|
||||||
{{NULL, "rmstarsilent", OPT_BOURNE}, RMSTARSILENT},
|
{{NULL, "rmstarsilent", OPT_BOURNE}, RMSTARSILENT},
|
||||||
{{NULL, "rmstarwait", 0}, RMSTARWAIT},
|
{{NULL, "rmstarwait", 0}, RMSTARWAIT},
|
||||||
{{NULL, "sharehistory", OPT_KSH}, SHAREHISTORY},
|
{{NULL, "sharehistory", OPT_KSH}, SHAREHISTORY},
|
||||||
@@ -357,7 +356,7 @@ static short zshletters[LAST_OPT - FIRST_OPT + 1] = {
|
|||||||
/* o */ 0, /* long option name follows */
|
/* o */ 0, /* long option name follows */
|
||||||
/* p */ PRIVILEGED,
|
/* p */ PRIVILEGED,
|
||||||
/* q */ 0,
|
/* q */ 0,
|
||||||
/* r */ RESTRICTED,
|
/* r */ 0, /* formerly RESTRICTED */
|
||||||
/* s */ SHINSTDIN,
|
/* s */ SHINSTDIN,
|
||||||
/* t */ SINGLECOMMAND,
|
/* t */ SINGLECOMMAND,
|
||||||
/* u */ -UNSET,
|
/* u */ -UNSET,
|
||||||
@@ -434,7 +433,7 @@ static short kshletters[LAST_OPT - FIRST_OPT + 1] = {
|
|||||||
/* o */ 0,
|
/* o */ 0,
|
||||||
/* p */ PRIVILEGED,
|
/* p */ PRIVILEGED,
|
||||||
/* q */ 0,
|
/* q */ 0,
|
||||||
/* r */ RESTRICTED,
|
/* r */ 0,
|
||||||
/* s */ SHINSTDIN,
|
/* s */ SHINSTDIN,
|
||||||
/* t */ SINGLECOMMAND,
|
/* t */ SINGLECOMMAND,
|
||||||
/* u */ -UNSET,
|
/* u */ -UNSET,
|
||||||
@@ -727,25 +726,6 @@ optlookupc(char c)
|
|||||||
return optletters[c - FIRST_OPT];
|
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 *
|
/* Set or unset an option, as a result of user request. The option *
|
||||||
* number may be negative, indicating that the sense is reversed *
|
* number may be negative, indicating that the sense is reversed *
|
||||||
* from the usual meaning of the option. */
|
* from the usual meaning of the option. */
|
||||||
@@ -760,16 +740,7 @@ dosetopt(int optno, int value, int force, char *new_opts)
|
|||||||
optno = -optno;
|
optno = -optno;
|
||||||
value = !value;
|
value = !value;
|
||||||
}
|
}
|
||||||
if (optno == RESTRICTED) {
|
if (!force && optno == EXECOPT && !value && interact) {
|
||||||
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) {
|
|
||||||
/* cannot set noexec when interactive */
|
/* cannot set noexec when interactive */
|
||||||
return -1;
|
return -1;
|
||||||
} else if(!force && (optno == INTERACTIVE || optno == SHINSTDIN ||
|
} else if(!force && (optno == INTERACTIVE || optno == SHINSTDIN ||
|
||||||
|
|||||||
50
Src/params.c
50
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}
|
#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("#", pound_gsu, PM_READONLY_SPECIAL),
|
||||||
IPDEF1("ERRNO", errno_gsu, PM_UNSET),
|
IPDEF1("ERRNO", errno_gsu, PM_UNSET),
|
||||||
IPDEF1("GID", gid_gsu, PM_DONTIMPORT | PM_RESTRICTED),
|
IPDEF1("GID", gid_gsu, PM_DONTIMPORT),
|
||||||
IPDEF1("EGID", egid_gsu, PM_DONTIMPORT | PM_RESTRICTED),
|
IPDEF1("EGID", egid_gsu, PM_DONTIMPORT),
|
||||||
IPDEF1("HISTSIZE", histsize_gsu, PM_RESTRICTED),
|
IPDEF1("HISTSIZE", histsize_gsu, 0),
|
||||||
IPDEF1("RANDOM", random_gsu, 0),
|
IPDEF1("RANDOM", random_gsu, 0),
|
||||||
IPDEF1("SAVEHIST", savehist_gsu, PM_RESTRICTED),
|
IPDEF1("SAVEHIST", savehist_gsu, 0),
|
||||||
IPDEF1("SECONDS", intseconds_gsu, 0),
|
IPDEF1("SECONDS", intseconds_gsu, 0),
|
||||||
IPDEF1("UID", uid_gsu, PM_DONTIMPORT | PM_RESTRICTED),
|
IPDEF1("UID", uid_gsu, PM_DONTIMPORT),
|
||||||
IPDEF1("EUID", euid_gsu, PM_DONTIMPORT | PM_RESTRICTED),
|
IPDEF1("EUID", euid_gsu, PM_DONTIMPORT),
|
||||||
IPDEF1("TTYIDLE", ttyidle_gsu, PM_READONLY_SPECIAL),
|
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}
|
#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("-", dash_gsu, PM_READONLY_SPECIAL),
|
||||||
IPDEF2("histchars", histchars_gsu, PM_DONTIMPORT),
|
IPDEF2("histchars", histchars_gsu, PM_DONTIMPORT),
|
||||||
IPDEF2("HOME", home_gsu, PM_UNSET),
|
IPDEF2("HOME", home_gsu, PM_UNSET),
|
||||||
@@ -315,7 +315,7 @@ IPDEF2("TERM", term_gsu, PM_UNSET),
|
|||||||
IPDEF2("TERMINFO", terminfo_gsu, PM_UNSET),
|
IPDEF2("TERMINFO", terminfo_gsu, PM_UNSET),
|
||||||
IPDEF2("TERMINFO_DIRS", terminfodirs_gsu, PM_UNSET),
|
IPDEF2("TERMINFO_DIRS", terminfodirs_gsu, PM_UNSET),
|
||||||
IPDEF2("WORDCHARS", wordchars_gsu, 0),
|
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("_", underscore_gsu, PM_DONTIMPORT),
|
||||||
IPDEF2("KEYBOARD_HACK", keyboard_hack_gsu, PM_DONTIMPORT),
|
IPDEF2("KEYBOARD_HACK", keyboard_hack_gsu, PM_DONTIMPORT),
|
||||||
IPDEF2("0", argzero_gsu, 0),
|
IPDEF2("0", argzero_gsu, 0),
|
||||||
@@ -396,12 +396,12 @@ IPDEF8("CDPATH", &cdpath, "cdpath", PM_TIED),
|
|||||||
IPDEF8("FIGNORE", &fignore, "fignore", PM_TIED),
|
IPDEF8("FIGNORE", &fignore, "fignore", PM_TIED),
|
||||||
IPDEF8("FPATH", &fpath, "fpath", PM_TIED),
|
IPDEF8("FPATH", &fpath, "fpath", PM_TIED),
|
||||||
IPDEF8("MAILPATH", &mailpath, "mailpath", 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("PSVAR", &psvar, "psvar", PM_TIED),
|
||||||
IPDEF8("ZSH_EVAL_CONTEXT", &zsh_eval_context, "zsh_eval_context", PM_READONLY_SPECIAL|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 */
|
/* 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}
|
#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("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("module_path", &module_path, "MODULE_PATH", PM_TIED),
|
||||||
IPDEF9("path", &path, "PATH", PM_TIED|PM_RESTRICTED),
|
IPDEF9("path", &path, "PATH", PM_TIED),
|
||||||
|
|
||||||
/* These are known to zsh alone. */
|
/* These are known to zsh alone. */
|
||||||
|
|
||||||
@@ -449,12 +449,12 @@ IPDEF8("CDPATH", &cdpath, NULL, 0),
|
|||||||
IPDEF8("FIGNORE", &fignore, NULL, 0),
|
IPDEF8("FIGNORE", &fignore, NULL, 0),
|
||||||
IPDEF8("FPATH", &fpath, NULL, 0),
|
IPDEF8("FPATH", &fpath, NULL, 0),
|
||||||
IPDEF8("MAILPATH", &mailpath, NULL, 0),
|
IPDEF8("MAILPATH", &mailpath, NULL, 0),
|
||||||
IPDEF8("PATH", &path, NULL, PM_RESTRICTED),
|
IPDEF8("PATH", &path, NULL, 0),
|
||||||
IPDEF8("PSVAR", &psvar, NULL, 0),
|
IPDEF8("PSVAR", &psvar, NULL, 0),
|
||||||
IPDEF8("ZSH_EVAL_CONTEXT", &zsh_eval_context, NULL, PM_READONLY_SPECIAL),
|
IPDEF8("ZSH_EVAL_CONTEXT", &zsh_eval_context, NULL, PM_READONLY_SPECIAL),
|
||||||
|
|
||||||
/* MODULE_PATH is not imported for security reasons */
|
/* 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},
|
{{NULL,NULL,0},BR(NULL),NULL_GSU,0,0,NULL,NULL,NULL,0},
|
||||||
};
|
};
|
||||||
@@ -1110,10 +1110,6 @@ createparam(char *name, int flags)
|
|||||||
zerr("read-only variable: %s", name);
|
zerr("read-only variable: %s", name);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if ((oldpm->node.flags & PM_RESTRICTED) && isset(RESTRICTED)) {
|
|
||||||
zerr("%s: restricted", name);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (!(oldpm->node.flags & PM_UNSET) ||
|
if (!(oldpm->node.flags & PM_UNSET) ||
|
||||||
(oldpm->node.flags & PM_SPECIAL) ||
|
(oldpm->node.flags & PM_SPECIAL) ||
|
||||||
/* POSIXBUILTINS horror: we need to retain 'export' flags */
|
/* POSIXBUILTINS horror: we need to retain 'export' flags */
|
||||||
@@ -2702,11 +2698,6 @@ assignstrvalue(Value v, char *val, int flags)
|
|||||||
zsfree(val);
|
zsfree(val);
|
||||||
return;
|
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) &&
|
if ((v->pm->node.flags & PM_HASHED) &&
|
||||||
(v->scanflags & (SCANPM_MATCHMANY|SCANPM_ARRONLY))) {
|
(v->scanflags & (SCANPM_MATCHMANY|SCANPM_ARRONLY))) {
|
||||||
zerr("%s: attempt to set slice of associative array", v->pm->node.nam);
|
zerr("%s: attempt to set slice of associative array", v->pm->node.nam);
|
||||||
@@ -2872,10 +2863,6 @@ setnumvalue(Value v, mnumber val)
|
|||||||
zerr("read-only variable: %s", v->pm->node.nam);
|
zerr("read-only variable: %s", v->pm->node.nam);
|
||||||
return;
|
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)) {
|
switch (PM_TYPE(v->pm->node.flags)) {
|
||||||
case PM_SCALAR:
|
case PM_SCALAR:
|
||||||
case PM_NAMEREF:
|
case PM_NAMEREF:
|
||||||
@@ -2914,11 +2901,6 @@ setarrvalue(Value v, char **val)
|
|||||||
freearray(val);
|
freearray(val);
|
||||||
return;
|
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))) {
|
if (!(PM_TYPE(v->pm->node.flags) & (PM_ARRAY|PM_HASHED))) {
|
||||||
freearray(val);
|
freearray(val);
|
||||||
zerr("%s: attempt to assign array value to non-array",
|
zerr("%s: attempt to assign array value to non-array",
|
||||||
@@ -3867,10 +3849,6 @@ unsetparam_pm(Param pm, int altflag, int exp)
|
|||||||
pm->node.nam);
|
pm->node.nam);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if ((pm->node.flags & PM_RESTRICTED) && isset(RESTRICTED)) {
|
|
||||||
zerr("%s: restricted", pm->node.nam);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pm->ename && !altflag)
|
if (pm->ename && !altflag)
|
||||||
altremove = ztrdup(pm->ename);
|
altremove = ztrdup(pm->ename);
|
||||||
|
|||||||
@@ -451,7 +451,7 @@ zhandler(int sig)
|
|||||||
|
|
||||||
case SIGINT:
|
case SIGINT:
|
||||||
if (!handletrap(SIGINT)) {
|
if (!handletrap(SIGINT)) {
|
||||||
if ((isset(PRIVILEGED) || isset(RESTRICTED)) &&
|
if (isset(PRIVILEGED) &&
|
||||||
isset(INTERACTIVE) && (noerrexit & NOERREXIT_SIGNAL))
|
isset(INTERACTIVE) && (noerrexit & NOERREXIT_SIGNAL))
|
||||||
zexit(SIGINT, ZEXIT_SIGNAL);
|
zexit(SIGINT, ZEXIT_SIGNAL);
|
||||||
errflag |= ERRFLAG_INT;
|
errflag |= ERRFLAG_INT;
|
||||||
|
|||||||
@@ -1013,24 +1013,6 @@
|
|||||||
>one'quoted'expression
|
>one'quoted'expression
|
||||||
>anotherquotedexpression
|
>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
|
# ' emacs deconfusion
|
||||||
|
|
||||||
fn() {
|
fn() {
|
||||||
|
|||||||
14
configure.ac
14
configure.ac
@@ -248,20 +248,6 @@ AC_ARG_ENABLE(dynamic,
|
|||||||
AS_HELP_STRING([--disable-dynamic],[turn off dynamically loaded binary modules]),
|
AS_HELP_STRING([--disable-dynamic],[turn off dynamically loaded binary modules]),
|
||||||
[dynamic="$enableval"], [dynamic=yes])
|
[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
|
dnl Do you want to disable use of locale functions
|
||||||
AH_TEMPLATE([CONFIG_LOCALE],
|
AH_TEMPLATE([CONFIG_LOCALE],
|
||||||
[Undefine if you don't want local features. By default this is defined.])
|
[Undefine if you don't want local features. By default this is defined.])
|
||||||
|
|||||||
Reference in New Issue
Block a user