Subject: Re: SetUID scripts
To: Brett Lymn <blymn@awadi.com.AU>
From: Greg Hudson <ghudson@mit.edu>
List: netbsd-help
Date: 07/03/1996 11:45:46
"The well-known security problem with setuid scripts" is:

When you exec a file beginning with "#!foo bar", the kernel translates
that into an exec of "foo" with the arguments "bar" (if present), the
filename, and then the original arguments.  So, for instance, if
/usr/bin/script starts with "#!/bin/sh", and you run it as "script
myarg1 myarg2", what will be executed by the kernel is

	/bin/sh /usr/bin/script myarg1 myarg2

But suppose I make a symlink from /tmp/slink to /usr/bin/script, and
run it from there.  What will then be executed by the kernel is:

	/bin/sh /tmp/slink myarg1 myarg2

Obviously, there is a window before /bin/sh manages to open /tmp/slink
where I could replace the symbolic link to point to a different file.
If /bin/sh was executed setuid (because /usr/bin/script is setuid),
then I can run arbitrary code as root.

Modern operating systems can close the setuid script hole by opening a
file descriptor to the script and passing the interpreter a filename
of /dev/fd/4 instead of the name of the script.  Solaris, for
instance, does this for setuid scripts (but still passes the filename
for non-setuid scripts).

I honestly don't know whether NetBSD has ever supported this
mechanism, or whether it still does.  Even with this hole closed,
individual interpreters may have a host of inherent security issues
(like /bin/sh and IFS), so setuid scripts will probably never be a
very good idea.