SGID/SUID on scripts

perryh at pluto.rain.com perryh at pluto.rain.com
Thu Jul 23 05:44:40 UTC 2009


DarkSoul <darksoul at darkbsd.org> wrote:
> Anthony Pankov wrote:
> > SGID/SUID bits don't work with shell scripts, do they?
>
> They don't.
>
> ... if they were applied, the following would occur :
> - execve() syscall reads your script's shebang line, and
> the script interpreter is executed, receiving the specified
> arguments along with the script name.
> - The interpreter then open()s the script file to read it,
> and run the code.
>
> The problem you then are faced with, is that you have a time
> frame defined by the moment between the aforementioned execve()
> and open(), during which it could be possible to unlink/move/
> whatever the shell script the interpreter is going to open.
>
> You guess where this is going, you have no absolute way of
> guaranteeing you are executing the file you initially planned
> on opening because execution/opening/reading is not, and can't
> be done atomically for shell scripts.

In principle, it should be possible to fix this exposure by
improving the interface between execve() and the interpreter:

The execve() syscall already has the script file open to read the
shebang line.  Leave it open, and ensure that the interpreter
receives the open descriptor as fd#3 just as 0, 1, and 2 are already
used for stdin, stdout, and stderr.  An interpreter supporting this
approach would check whether stdscr (fd#3) is already open, and if
so read from it instead of open()ing the script file.  This should
ensure that the script which gets executed is the same inode on
which execve() saw the SGID/SUID bits set, even if the filesystem
has been changed by the time the interpreter has gotten started.
It would be the responsibility of whomever decided to set the
SGID/SUID bits on a particular script to ensure that the interpreter
involved supports the mechanism.

I vaguely recall having seen a similar (or even identical) approach
suggested some years ago.  It may even have been implemented in some
variant of Un*x.


More information about the freebsd-hackers mailing list