setuid shell scripts (was: Re: Running processes as root)
Maarten Litmaath
maart at cs.vu.nl
Tue Oct 24 08:40:38 AEST 1989
chris at mimsy.umd.edu (Chris Torek) writes:
\...
\On all of the BSD derivatives on which setuid scripts run setuid,
\all such setuid scripts are not secure.
It almost never happens, but this time you seem to be wrong, Chris!
\>... you must think ahead to restrict the user to executing
\>only the script you've choosen
\
\With the existing implementations, this is not possible. (Sorry.)
Ahum.
\You have to write at least one C program.
Indeed: /bin/indir! (Formerly /bin/setuid.)
Here's the manpage. Source available soon in comp.sources.unix.
INDIR(1) USER COMMANDS INDIR(1)
NAME
indir - run (setuid) (shell) scripts indirectly
SYNOPSIS
#!/bin/indir
#?...
DESCRIPTION
Indir is not executed from a shell normally. Instead it can
be used as the interpreter for shell scripts that:
1) need to be run setuid to someone else, or
2) fail to meet the constraints for a `#!' line (see
execve(2)).
Indir is invoked by making the first line of the script
#!/bin/indir
rather than the usual
#!/bin/sh
Indir tries to open the script for reading. If successful it
discards the first line (containing `#!/bin/indir') and
tries to read a line formatted as follows:
#?absolute-path-of-interpreter arguments
Whitespace around the `#?' magic number is discarded. The
interpreter as well as the arguments are subject to the
`tilde convention': a leading string `~user' is expanded to
the home directory of `user', where `user' is the longest
string of alphanumeric characters immediately following the
`~'. If this string equals the null string, the login name
of the effective uid is used.
Furthermore an argument consisting of a single `%' is
expanded to the name of the script. However, if the file
being executed is a setuid script, the expansion is inhi-
bited (see below). Examples:
#?/bin/csh -bf /usr/etc/setuid_script -v
#? ~/bin/my_interpreter -f ~john/foo/bar
#?/bin/sed -n -f %
A `#?' line is limited to 256 characters. However, if the
line ends in a backslash (`\'), the next line is assumed to
contain further arguments after a mandatory leading `#?',
Sun Release 4.0 Last change: Oct 21, 1989 1
INDIR(1) USER COMMANDS INDIR(1)
and so on. There is a system-imposed limit on the total
number of characters present in the argument list.
To avoid `linking tricks' through which uncontrolled
privileges of the owner of the file could be acquired, 3
measures have been taken for setuid scripts:
1) the script must contain its own safe invocation,
that is the `#?' line; `%' arguments will not be
expanded;
2) the environment is reset to a simple default:
PATH=/bin:/usr/bin:/usr/ucb
3) before the final execv(2) indir checks if the owner
and mode of the script are still what they are supposed
to be (using fstat(2)); if there is a discrepancy,
indir will abort with an error message.
Indir will only exec a pathname beginning with a `/'. Of
course indir can be `fooled' by supplying dubious arguments
to the interpreter, like relative pathnames. Furthermore it
is a mistake to let any of the directory components of an
ultimate path be writable by others. In our first example
`/', `/bin', `/usr' and `/usr/etc' should not be writable
for ordinary users.
AUTHOR
Maarten Litmaath @ VU Informatika Amsterdam (maart at cs.vu.nl)
SEE ALSO
sh(1), csh(1)
BUGS
The maintenance of setuid scripts is a bit annoying: if a
script is moved, one must not forget to change the path men-
tioned in the script. Possibly the editing causes the setuid
bit to get turned off.
--
A symbolic link is a POINTER to a file, | Maarten Litmaath @ VU Amsterdam:
a hard link is the file system's GOTO. | maart at cs.vu.nl, mcsun!botter!maart
More information about the Comp.unix.questions
mailing list