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