Subject: Re: Addition to force open to open only regular files
To: None <tech-kern@netbsd.org>
From: Noriyuki Soda <soda@sra.co.jp>
List: tech-kern
Date: 11/23/2000 22:25:39
[NOTE: tech-net@netbsd.org is removed from Cc:]

soda> I cannot understand the above statement.
soda> If I understand correctly,
soda> 
soda> 	fd = open_as(filename, ...., real_uid);
soda> 
soda> is just same with the following code:
soda> 
soda> 	if ((euid = geteuid()) == real_uid) {
soda> 		fd = open(filename, ...);
soda> 	} else {
soda> 		seteuid(real_uid);
soda> 		fd = open(filename, ...);
soda> 		seteuid(euid);
soda> 	}
soda> 
soda> So, saved-uid/gid feature can do what open_as() can do.

>>>>> On Wed, 22 Nov 2000 16:51:50 -0500 (EST),
	woods@weird.com (Greg A. Woods) said:

woods> Of course it can.

soda> And, open_as() cannot do what saved-uid/gid can do.

woods> Exactly -- this is why open_as() is better.  Saved-set-ID swapping has
woods> directly caused several successful exploits in the past in at least two
woods> different implementations that I'm aware of, and given its nature it
woods> makes other kinds of vulnerabilities much more dangerous.

According to your next message, it seems you are misunderstanding
how saved-uid/gid works.
The exploits of saved-set-ID do not really exist.
Please read below.

soda> (*) The reason that our saved-uid/gid feature is not compatible
soda>	with POSIX_SAVED_ID is:
soda>	In POSIX_SAVED_ID, only root-setuid program can drop
soda>	it's saved uid by setuid(2), normal-user-setuid program
soda>	cannot drop it's saved uid.
soda>	In NetBSD, normal-user-setuid program can drop it's
soda>	saved uid privilege.

woods> No, that's wrong because even in NetBSD a setuid-non-root program can
woods> drop its saved-set-ID privs.

???
Yes, "setuid-non-root program can drop its saved-set-ID privilege in NetBSD".
That's what I said.

Hmm, probably my poor english ability confused you?

But, "setuid-non-root program cannot drop its saved-set-ID privilege
in POSIX". That's is why NetBSD doesn't conform to POSIX about
saved-set-ID.

woods> The difference in POSIX is that seteuid() also sets the saved
woods> set-user-ID value for the current process if the effective user-ID is
woods> that of the superuser.  I.e. in POSIX a setuid-root process can never
woods> regain its root privs after calling seteuid(getuid());

No. The above your sentence is completely wrong.
Please re-read POSIX.1 carefully.

First, POSIX doesn't define seteuid() at all.
POSIX only defines setuid().

Second, in NetBSD (and also in all POSIX based systems I know),
setuid-root process can regain its root privilege by the following code:
	euid = geteuid();
	seteuid(real_uid);
	... do something which should be done in real-uid privilege ...
	seteuid(euid);
This is what "saved-set-ID" intended, although because POSIX doesn't
define seteuid(), this behaviour is implementation-defined.

Third, in both POSIX and NetBSD, setuid-root process can permanently
revoke its set-ID privilege by the following code:
	setuid(real_uid);
Thus, in both POSIX and NetBSD, the buffer-overflow exploit example
is impossible against setuid-root process after the process did
the setuid(real_uid).
I think the comment about this in our <sys/unistd.h> leads
misunderstandings. Perhaps this is why you misunderstood.
I believe we should rewrite the first half of the comment.

Fourth, in NetBSD, setuid-non-root process can permanently revoke
its set-ID privilege by the following code:
	setuid(real_uid);
Thus, in NetBSD, the buffer-overflow exploit example is impossible
against even setuid-non-root process after the process did the
setuid(real_uid).
In POSIX, the buffer-overflow exploit is *possible* against
setuid-non-root process, because setuid-non-root process *cannot*
permanently revoke its saved-set-ID in POSIX.
This is what NetBSD and POSIX differs, and why NetBSD never
defines _POSIX_SAVED_IDS.

woods> I.e. in POSIX the buffer-overflow exploit example above is impossible
woods> against setuid-root processes, but still possible against
woods> setuid-non-root processes.

The above your sentence is correct.

woods> In *BSD even a setuid-root program can regain its root privileges,
woods> i.e. *BSD allows all saved-set-ID swapping, thus the vulnerability in
woods> face of a buffer overflow is always possible, even for setuid-root
woods> programs.

The above your sentence is wrong.
As written in the above my sentence, *BSD can permanently revoke its
set-ID privilege by calling setuid(real_uid).
If an application program intended to revoke its set-ID privilege
permanently, the application program should call setuid(real_uid).

There is no exploit that open_as() can fix but saved-ID feature
cannot fix. Thus, open_as() is not needed.
--
soda