changing user id's

utzoo!decvax!ittvax!swatt utzoo!decvax!ittvax!swatt
Fri Jan 8 14:47:44 AEST 1982


In reply to: Lauren at UCLA-Security

We did exactly this with a V6 system.  The rule was: any process is
allowed to assume any combination of user and group id's it already
had, or could get under the old rules.  The usual case is:

	user "joe" executes a program SUID to "root"

The process has effective ID == "root" and real ID == "root" (I am
going to leave group id's out of this, but they are treated exactly the
same).  Now in this mode, for every single operation a process can
perform , this process has the permissions "root".  This allows the
process to setuid to anybody.  However, traditional UNIX systems set
BOTH real and effective ids on setuid().  So in the above case, the
process could setuid() to "steve", but would have lost both permissions
of "root", and "joe".  We implemented a "setid" system call that took
both real and effective user and group ids in one call according to the
rule of paragraph 1.  Thus the example process could:

	set real = "root" , effective = "joe"

Note that this does not violate the old rule, which would allow this
process to setuid to either "root" or "joe"; the only change is to
allow the process to retain rights to both id's.

Now the process is effectively "joe", but because of the existing rules
(you can always setuid() to your real uid), it still has the right to
setuid() to "root".  This allows a process to swap real and effective
permissions back and forth.

The somewhat more interesting case is a process with effective ID ==
"games" and real ID == "joe".  This process can modify a protected
score file owned by "games", but still write out a save file owned by
"joe" by swapping real and effective id's, writing the file, and
swapping them back.  The recent discussion about having a SUID news
program be unable to read a file in the user's area can also be solved
by this means.  The games problem can be solved by making the program
SGID instead, and having group write permission on the socre file.
The news situation cannot be solved this way becuase you want new
files created by the news system to be owned by the news id, not
the user who entered the news item.

This scheme is very easy to put in, becuase there is only one place in
the UNIX kernel that real id's are ever checked, which is in the
setuid() and setgid() system calls; everything else uses effective (the
"access()" call swaps them first, does an internal "access" call, and
swaps them back!).  We created two calls "setid()" and "getid()".
Given these, you can implement all of "get*id()" and "set*id()" as
subroutines.

Some people have suggested stacking uid's;  I have never seen this done.
I would enjoy a discussion of how it would work.

	- Alan S. Watt (decvax!ittvax!swatt)



More information about the Comp.unix.wizards mailing list