Modern shells and running shell scripts while seteuid
You can't and shouldn't make a shell script setuid, but there are times when you can want to deliberately run a shell script from within a seteuid context, especially a seteuid root one. One case for this is if you want to kick off a script from PAM module that may be run for, eg, password changes.
I will cut to the chase: you probably don't want to do this today,
because modern Unixes or more exactly modern shells on Unixes are
making this harder and harder to do reliably. If at all possible,
transition fully to the new UID you want the shell script to operate
under, either by doing the appropriate setuid()
call in your own
code before you invoke the script or by changing how the entire
system is invoked (for example, by doing things through sudo
).
In the old days of Unix, shells were blithely unconcerned about
security issues; those were your problem, and it was up to you to
do things right. Over time, it became obvious that a certain number
of people were not going to do things right and that perhaps it
would be a good idea for shells to save people from themselves, at
least some of the time. For example, one fruitful source of security
issues here is setuid programs using popen()
to run things.
popen()
starts a shell, which was running seteuid, and there are
any number of ways to subvert a shell if you aren't careful (especially
modern shells, which can have their behavior influenced by any
number of environment variables).
So shells started saving people from themselves in this situation.
If you start a modern shell in a seteuid environment and don't give
it a special flag (people seem to have standardized on -p
), it
immediately drops seteuid privileges and generally also ignores a
number of environment variables that would normally influence its
behavior.
(Some shells in the Bourne family will do this all of the time,
even if they're being used as /bin/sh
, but some of them will do
this only if they're invoked under their own name and stick to the
traditional behavior when run as /bin/sh
. The latter is less
secure but more compatible with existing behavior.)
This presents not one but two problems if you intend to run a shell
script in such a seteuid environment on a modern Unix with such a
modern shell. The obvious and direct problem is that you have to
make sure to start the shell script with '#!/bin/sh -p
' or
'#!/bin/bash -p
' or the like; otherwise the shell will immediately
drop permissions on you. The good news is that you're probably going
to notice and fix this right away, at least once you work out what's
happening.
The less obvious problem is that running your own script with -p
has armed a gun that's pointed at any other shell scripts that your
script runs. Unless those scripts also start with -p
, they may
(or will) immediately drop seteuid when they start to run and will
quite possibly malfunction as a result. Effectively, running with
-p
poisons your environment in a subtle way. It's possible to
work around this in various ways, but it makes your whole shell
script fragile; all you need is one thing that your script runs
deciding to call a shell script that doesn't have a -p
and things
can blow up.
(And naturally many of the things that your script uses may not
ever have thought about this, because they're just regular scripts,
not special security-related scripts that ever expected to run in
a seteuid environment. Some of them may not even really be safe in
a seteuid environment in general, so just slapping a -p
on them
is dangerous in its own way.)
Given that running seteuid is now a taint as far as modern shells are concerned, it's more reliable to avoid this taint in the first place. In other words, run your initial shell script without it being seteuid (one way or another).
|
|