Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 5 Jun 2002 22:14:38 -0400 (EDT)
From:      Robert Watson <rwatson@freebsd.org>
To:        Lars Eggert <larse@ISI.EDU>
Cc:        hackers@freebsd.org
Subject:   Re: get/setuid used instead of get/seteuid?
Message-ID:  <Pine.NEB.3.96L.1020605220536.62978Q-100000@fledge.watson.org>
In-Reply-To: <3CFEAFBD.8090603@isi.edu>

next in thread | previous in thread | raw e-mail | index | archive | help

On Wed, 5 Jun 2002, Lars Eggert wrote:

> there's a large number of system programs that use get/setuid() to limit
> what a non-root user can do (route, killall, ping, etc.) 
> 
> This may be a really dumb question, but shouldn't they be using
> get/seteuid() instead, to base their decision on the effective uid? 
> Otherwise setting the setuid flag on the binary has no effect. 

Setting the setuid bit on the binary results in the real uid being
preserved, but the file's owner being adopted as the effective uid.  When
invoking one of the various set*uid()-related calls, the set of available
uids to pick from is based on the real, saved, and effective uid.
Programs that run with root privilege by virtue of the setuid bit on their
binary will frequently call setuid(getuid()) to set all three uids to the
real uid, reducing the privileges that they have access to (i.e.,
restoring aspects of the pre-exec() security environment).  For example,
ping will bind a raw socket which permits it to send ICMP, and monitor
incoming ICMP, and then restore the original uid.  This means that it will
no longer be able to bind new raw sockets.  The kernel will provide some
additional protections for the process since the process may have cached
privileged data, and we don't want other processes gaining access to that,
or any other privileges (such as access to the raw socket), but the actual
effective uid is reset.

> For example, setting the setuid flag on ping (so non-root users can use
> flood pings - I am aware of the security implications, this is for a
> prototype system that will never go live) does not work - ping checks
> the real uid instead. 

The setuid bit is set on the ping command by default so that non-root
users can generate and monitor ICMP; you describe enabling that bit, but
it's probably already enabled on your system if it's a default install.
Removing the setuid bit will prevent non-root users from being able to use
the command properly, as they won't have access to the raw socket that is
needed for ping to operate properly in most of its operating modes. 
Setting the setuid bit does not permit non-root users to flood ping, since
the getuid() call returns the real uid, which is not modified by the
setuid bit on the binary.  This is intentional.  In order to permit
non-root users to flood ping, you must remove the check from the binary. 

FWIW, I think that the flood ping check is a bit bogus :-).  Users can
generate floods of non-ICMP packets trivially using the normal application
APIs.  The current behavior is probably largely to prevent mostly clueless
users from doing stupid things.

> Or is this deliberate? If so, there's other system programs (e.g. 
> reboot) that check the euid instead. (Or is the inconsistency
> deliberate?) 

It depends a lot on the context.  Generally, applications should check the
uid that is appropriate for what they want to do, and that can depend a
lot on how the applicaton behaves.  Applications may check the effective
uid to *see* if they were run setuid, for example, and behave differently
if they were (i.e., at start of execution, getuid() != geteuid() &&
geteuid() == 0).  For example, they may generate an error if they believe
they don't have the privilege they need to run properly.  There are some
decent arguments that that behavior is a bit flawed if you start to employ
different privilege models, needless to say. 

> Can someone shed some light on this? 

Although I wouldn't preclude bugs existing in the handling of uid's and
gid's across various applications, what you are describing is intentional.

Robert N M Watson             FreeBSD Core Team, TrustedBSD Projects
robert@fledge.watson.org      Network Associates Laboratories



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.NEB.3.96L.1020605220536.62978Q-100000>