Subject: Re: Addition to force open to open only regular files
To: Noriyuki Soda <soda@sra.co.jp>
From: Warner Losh <imp@village.org>
List: tech-kern
Date: 11/22/2000 11:33:23
In message <200011221728.CAA26694@srapc342.sra.co.jp> Noriyuki Soda writes:
: Probably, I'm missing context (unfortunetely, I don't have time to
: read all mails), but...
: Why do you ignore the following option?
: 	Deprecate setreuid(2) and setregid(2).
: 	Use saved-uid/gid feature to drop privilege.
: Half-open, open-only-normal-files, fsetuid, open_as are all insufficient,
: because there are system calls other than open(2) which is related to
: user's privilege.
: The saved-uid/gid feature can do what those can do, and can cope with
: system calls other than open(2), too.

There are two reasons.  First, we have no knowledge of the saved uid
in userland.  There's no way to know what it is.

If we wanted to punt on the cases where setreuid had been abused, we
could do something like
	if ((oldeuid = geteuid()) != getuid())
		seteuid(getuid());
	do it
	if (oldeuid != getuid())
		seteuid(oldeuid);
would do the trick (ditto group stuff).

For most people and most applications, this would be sufficient.  If
we depricated the full functionality of setreuid, then it would be
sufficient for most cases.

Even if we didn't, it would then be up to the setreuid using program
to scrub their environment when necessary.  A simple library call
would make this portable and useful.

In the case where a setuid root program did something like:
	setreuid(12, 45)
for whatever reason (which is the example of why we can't just do the
above), then we'd require that it also add a call like:
	sanitize_environment();
	setreuid(12, 45);
which would solve nearly all, if not all, of these problems.  Once the
enviornment was sanitized, then the we'd know things are safe.  The
anti-make-it-safe folks would object, but when it is pointed out that
the number of programs that do this is vanishingly small (eg, I've
never actually seen one that set uids so arbitrarily) they might go
along with it so long as their HOSTALIASES work with rlogin again :-).
About the only uses of setreuid I've seen translate to approximately
	setreuid(geteuid(), getuid());
which can easily be replaced by seteuid(), but would cause problems
for the above code because we'd always switch in this case.  Since an
easy replacement is available, I don't worry too much about this.
Maybe it is time to put a warning into code that does this ala the
gets warning.

The above dances, with proper group handling, would need to be
enshrined in libc so code could look like:
	drop_privs(&drop_cookie);
	do it
	raise_privs(&drop_cookie);

We could even have sanitize_environment() set a flag.  We could then
have setreuid print an obnoxious message when it wasn't set and the
setreuid parameters appeared arbitrary, but that might be pushing
things too far.

Warner