S[UG]ID files and s[re][ug]id() system calls

utzoo!decvax!ucbvax!unix-wizards utzoo!decvax!ucbvax!unix-wizards
Fri Oct 16 00:58:29 AEST 1981


>From decvax!ittvax!swatt at Berkeley Thu Oct 15 21:14:38 1981
Re: S[UG]ID files and [sg][re][ug]id() system calls.

Back in my hacking days, we ran into similar limitations of the
standard UNIX handling of SUID/SGID bits and suid()/getuid() calls.
The approach we adopted was:

	S[UG]ID works for ALL users (no exceptions for root)

	S[UG]ID NEVER works for files being exec'd from insecure
		devices.
	
	open()	NEVER works for special files residing on insecure
		devices.

		The above two prohibitions were to support user-
		mountable filesystems (floppies).  In our
		implementation, a device was "insecure" if its major
		device number was not the same as the root device major
		device number.  That way we could boot a UNIX system
		off a floppy and access special files (handy to do; we
		had only 1 rp05 drive which was often flakey).

		The check on the major device number is a clumsy way to
		do it.  Someone (I think Bill Plaugher) suggested an
		extra argument to the mount command, only honored for
		the super-user, to say that the mounted filesystem was
		"secure".  If you allow user-mountable filesystems and
		don't check for SUID/SGID and special files, your
		system is not secure.

	setuid(),setgid().
		This was back in the V6 days where a uid/gid was
		only one byte.  But the principle applies:

		Any process may change its real/effective permissions
		to any combination of permissions it already
		possesses.  The rational behind this was that the only
		place the REAL user id information was ever checked was
		in the sgid() system call; all checks for file
		permissions and the like used the effective
		permissions.
		
		The previous rule said that any process could set its
		effective permissions to its real permissions.  The new
		rule thus did not permit any new kind of access but
		made certain kinds of operations for SUID/SGID programs
		much more convenient.  Specifically you could have a
		"swapid()" subroutine which would switch real and
		effective permissions AND REVERSE THEM AT A LATER
		TIME.  Thus a program SUID to "jones" being run by
		"smith" would have the ability to do anything either
		"jones" OR "smith" could do.

		An important application was the creation of priviliged
		commands which could temporarily "de-privilege"
		themselves.  The later addition of the "access" system
		call has not (I believe) totally obviated the need
		this.

		In fact what we added were "getid" and "setid" system
		calls which returned/took a 4-byte array containing
		user and group, real and effective ids.  Given these
		two, subroutines to mimic "getuid", "getgid", "setuid",
		and "setgid" are easy (I think we left the system calls
		in to keep some binaries happy though).
	
In short, I think the UNIX handling of S[UG]ID files and s[ug]id()
system calls could be improved.

We also changed the relationship between group and user ID's to be a
hierarchy instead of an overlay (mostly to overcome the 256 user
limit).  A rather nice (I think) side effect of this was the creation
of a Group Super User, who had all the powers of "root", but only on
files and processes owned by that group.

All this was done without changing the tty driver.

I would like to see the idea of a group super user made part of V7
UNIX; it considerably simplifies system management in allowing most
aspects of administering a group to be divested from administering the
system as a whole.  In an academic environment, it is also good
training for eventual super-users.  However, without changing the
"overlay" relationship of group and user ID's, I can't suggest a
reasonable way to do it.

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



More information about the Comp.unix.wizards mailing list