Subject: Re: setreuid() and setregid()
To: der Mouse <mouse@Collatz.McRCIM.McGill.EDU>
From: Greg A. Woods <email@example.com>
Date: 05/25/1996 13:27:23
[ On Sat, May 25, 1996 at 06:59:56 (-0400), der Mouse wrote: ]
> Subject: Re: setreuid() and setregid()
> >> Whether this upsets you according to the criterion you described
> > As I understand the DoD "orange book" C2 requirements (and especially
> > those of the Canadian equivalent to this document, the CTCPEC) state
> > that any "object" (such as a process) which lowers its clearance must
> > not be permitted to regain a higher level of clearance.
> Of course. The question is, does simply running with euid set to
> joe-user mean that the process has lowered its clearance? I don't
> think so, because as you say implicit in lowering clearance is that one
> not then be able to raise it again. Only an irrevocable change of uid
> can count as lowering clearance, meaning the setuid() call that sets
> all three uids the same.
Ah ha! I think I see where this long running debate might have gained
its sustaining energy.
Under C2, and more so under the higher levels, it is said that a process
has lowered its credentials if it has in any way changed the user-id it
is running as and thus the access permissions, etc. it has.
Under C2 evaluation, POSIX has two basic levels of trust: that of euid=0
(the superuser), and that of all other users. This implies, almost by
definition, that if a POSIX process changes its effective user-id from 0
to something else, then it mus no longer have permission to change back
to euid==0. It also implies that if the real-uid is changed then the
effective uid must also be changed to match (and also the saved uid).
> So, I can almost hear you saying, why bother with having multiple UIDs
> at all? The first need is for the ruid, so that a setuid program can
> tell who invoked it. The suid one arguably does not actually need; I
> don't quite understand why POSIX added it, but like the other POSIX
> braindamages, we appear to be stuck with it for now, because it's not
> quite braindamaged enough to make core dump it. The reasons for
> allowing a setuid process to switch its uid back to that of the invoker
> while still retaining the potential to return to what it had are (a)
> convenience of programming - it limits, to some extent, the damage bugs
> can do, and (b) the closing of some race windows.
Yes, but from the point of view of C2 and higher, it is important to
identify the difference between uid=0 and uid!=0. That's essentially
why the saved-uid was added (I think) [well the initial reason was that
it was already in the AT&T SVID ;-)] -- it makes it easy to safely allow
a setuid program (that's not setuid=0) to swap the euid between the ruid
and whatever the initial euid was (i.e. what the program is setuid to).
If I remember correctly SVIDv3 is careful to state that if the initial
euid==0 (i.e. for setuid-root), setuid() will change euid, ruid, and
suid to the new user-id, thus properly (according to C2) lowering the
credentials of the process once and for all.
> > Most interpretations of these requirements w.r.t. UNIX security, that
> > I'm aware of, suggest that when a process running with uid==0 changes
> > its uid (and the implicitly gives up superuser status), it must not
[[ I should have said "euid==0 changes its euid (and thus". ]]
> > be permitted to regain this status.
> And depending on what "changes its uid" means, this may or may not be
> true of the UNIX model. If it refers to any euid change, it's not true
> and probably never will be; if it means giving up all other IDs, then
> it is true and always has been.
That depends on which "UNIX" model you're thinking of. Only 4.2BSD and
newer BSDs allow a setuid-root process to temporarily become another and
euid and then return to euid==0. V7 didn't allow any swapping of euid
or ruid, and V10 only added a setruid(2) which allows an euid==0 process
to set only the ruid (I'm not sure why they did this either).
Greg A. Woods
+1 416 443-1734 VE3TCP robohack!woods
Planix, Inc. <firstname.lastname@example.org>; Secrets Of The Weird <email@example.com>