Subject: Re: setreuid() and setregid()
To: matthew green <mrg@eterna.com.au>
From: Greg A. Woods <woods@most.weird.com>
List: tech-kern
Date: 05/27/1996 00:55:04
[ On Mon, May 27, 1996 at 12:15:31 (+1000), matthew green wrote: ]
> Subject: Re: setreuid() and setregid() 
>
>    A non-privileged process should not be able to give up all traces of its
>    origins, and thus should not be able to re-set p_ruid and especially not
> 
> why is this ?

To be able to do this is a privilege, and since a process that was
started with set-user-ID to other than root is, by definition, not
privileged, it cannot be allowed.

Yes this seems twisted at first glance, esp. since the process is trying
to give up its setuid-ness.  However, given the unix-like systems base
their entire security policy on the set-user-ID-on-exec feature, and the
fact that there is but one privileged user (i.e. uid==0), this actually
makes sense from a security requirements P.O.V.  The system *must* force
all processes to go through this one little knot-hole of security in
order to keep the implementation of the policy as simple as possible.

> if i have a program that i want to have "some" privileges
> (ie, it can read a file owned by user `foo'), i make it
> set-uid (to user foo). if, after i've read this file, i
> decide, being a security conscience coder, that i no longer
> need the ability to read this file (ie, it may be a start up
> file, say a license), i want to revoke these priviledges.
> 
> yes, i can use 'exec' to get around this but this is an evil
> hack.

The first trivial fix is to just call setuid(getruid()); and remember
never to call setuid() again.  If you exec() anything, the saved-uid
will be cleared for you, and you've really no worry of any risks,
assuming you've no stack-related bugs where your program might be
tricked into calling setuid("foo") and then doing nasty things as foo.

There's another almost trivial fix for your exact scenario:  You need
only write a wee tiny setuid-foo program that merely verifies its
authorisation in some way (if necessary), then opens the file owned by
foo and writes its contents to stdout.  Your larger program then need
not be setuid, and it need only start the setuid-foo program, provide it
the necessary authorisation if necessary, and read the file's contents
from the pipe.

Yes, the need for authorisation can get messy, and in fact is a similar
problem to that of providing secure communications channels on open
networks.

> NetBSD is extremely close to being POSIX.1 compliant. There
> are a few nits we know about: some we plan to fix, and
> others we plan to ignore until a future revision of POSIX.1
> ``fixes'' them for us.
> 
> 
> the last bit is especially relevant, as, this setuid discussion
> is part of what the above is saying.

It doesn't say that explictly, and I doubt there's any hope of POSIX.1a
ever "fixing" this particular "non-problem".

> in what way is not defining _POSIX_SAVID_IDS not conformant?

I didn't say it was, necessarily.  Stevens hints that it must be
supported in order to offer the proposed seteuid() function.  I'd have
to see the exact proposed changed to POSIX.1 in order to see if the
change then truely mandates _POSIX_SAVED_IDS be defined.  I can't find
any mention of the exact proposal in any of the USENIX ";login:"
standards snitch reports, nor anything relevant online through various
search engines....

-- 
							Greg A. Woods

+1 416 443-1734			VE3TCP			robohack!woods
Planix, Inc. <woods@planix.com>; Secrets of the Weird <woods@weird.com>