Allowing users to set set[ug]id bits

Marek Michalkiewicz (marekm@i17linuxb.ists.pwr.wroc.pl)
Wed, 18 Dec 1996 19:10:51 +0100 (MET)


Thanks to everyone who responded to my original posting. I was wrong:
there _are_ reasons why ordinary users may need to be able to set the
setuid/setgid bits. My apologies to all ordinary users here - please
don't send me any more flames on this...

(There are other, safer ways to do CGI programs though - use cgiwrap.
It's a setuid CGI program installed by the system administrator to allow
users to install their own CGI programs without having to set the setuid
bit, and without compromising the UID the web server itself runs under.
But that's off topic for linux-kernel, so I'll stop here.)

But - I think there are legitimate reasons for disallowing setting
setuid/setgid bits as well. For example, if you remove a user from
a group, they can still access it if they created a program setgid to
that group. Or, some trojan program run by the user could create
a program setuid to the user, thus compromising the user's security
without the user knowing about it.

BTW, the idea is not mine - SCO UNIX supports something like this, so
I thought it would be good to have that in Linux too (SCO sucks when
it comes to performance, but they have some nice security features;
I think we can have both performance and security). Quoting from the
SCO man page:

setpriv(S) 6 January 1993 setpriv(S)

Name

setpriv - set system privileges for this process

[...]

int setpriv (privtype, privs)
int privtype;
priv_t *privs;

Description

The setpriv routine sets the system privilege vector for the current pro-
cess to that in the user-supplied privs vector. This vector should have
at least SEC_SPRIVVEC_SIZE (a system constant) entries. The privtype
argument may only contain the privilege type SEC_EFFECTIVE_PRIV (another
system constant).

At system initialization, all privileges are included. System privileges
are inherited by all children of any process and must call the setpriv
routines themselves to further restrict system privileges.

The system privilege vector contains per-process rivileges used by the
TCB. The following system privileges are defined:

[...]

[SETID] Allow a program to set the SUID or SGID bits on a file.
Turning this privilege off prevents a new user from acciden-
tally propagating his identity. Turning this privilege off
and running an untrusted program prevents that program from
secretly creating a file owned by you (like a copy of
/bin/sh) and setting the SUID bit so that it can run as you
unrestricted. There are other similar uses.

[...]

Standards conformance

The setpriv routine is an extension of AT&T System V provided by the
Santa Cruz Operation.

Other privileges include:
SETOWNER - allow giving files away using chown() (already disallowed
on Linux - and nobody seems to complain about it, even though it might
be useful for some people).
SUID - allow executing SUID programs not already owned by the user.

setpriv() is a non-standard SCO extension, but maybe something like
this could be done using the POSIX.6 privileges?

Nobody answered my original question: would it break any standards
(POSIX, XPG, ...) if users were not allowed to set set[ug]id bits?
Let's not discuss whether this is useful: it is for some people and
it isn't for others, but in any case it would be optional - so what's
the problem? (same goes for the link() debate: let's not discuss
whether it is useful or not - just implement a mount option that the
system administrator can turn on or off)

Marek