Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 12 Dec 2001 22:01:42 +1100 (EST)
From:      Bruce Evans <bde@zeta.org.au>
To:        Hao Chen <haochen@uclink.berkeley.edu>
Cc:        <freebsd-audit@FreeBSD.ORG>, <freebsd-security@FreeBSD.ORG>
Subject:   Re: setuid() POSIX compliance
Message-ID:  <20011212211356.L34562-100000@gamplex.bde.org>
In-Reply-To: <3C15B736.7080605@uclink.berkeley.edu>

next in thread | previous in thread | raw e-mail | index | archive | help
> 1. The following comments are from /usr/src/sys/kern/kern_prot.c
>
> /*
>   * Use the clause in B.4.2.2 that allows setuid/setgid to be 4.2/4.3BSD
>   * compatable.  It says that setting the uid/gid to euid/egid is a special
>   * case of "appropriate privilege".  Once the rules are expanded out, this
>   * basically means that setuid(nnn) sets all three id's, in all permitted
>   * cases unless _POSIX_SAVED_IDS is enabled.  In that case, setuid(getuid())
>   * does not set the saved id - this is dangerous for traditional BSD
>   * programs.  For this reason, we *really* do not want to set
>   * _POSIX_SAVED_IDS and do not want to clear POSIX_APPENDIX_B_4_2_2.
>   */
>
> But according to POSIX 1003.1-1988, section 4.2.2.2:
>
>    If {_POSIX_SAVED_IDS} is defined:
>
>    (1) If the process has appropriate privileges, the setuid() function
>        sets the real user ID, effective user ID, and the saved set-user-ID
>        to uid.
>
> Does FreeBSD's interpretation of _POSIX_SAVED_IDS differ from POSIX?  Or did
> I misunderstand anything here?

There is no difference, because _POSIX_SAVED_IDS is intentionally not
defined, as permitted in all versions of POSIX up to at least the 1996
version.  POSIX.1-2001 requires it, so FreeBSD would need to be "fixed"
to conform with the current version of POSIX (unless everyone that can
change one of their ids using setuid() is considered to have
"appropriate privilege".

> But according to POSIX 1003.1-1988, section 4.2.2.2:
>
> 2. Also according to the above comment from /usr/src/sys/kern/kern_prot.c,
> setting _POSIX_SAVED_IDS will cause setuid(getuid()) NOT to set the saved
> id.

Setting _POSIX_SAVED_IDS is not a supported option.  The code has ifdefs
to support it for mostly historical reasons.

> However, according to the following code from setuid() in
> /usr/src/sys/kern/kern_prot.c, setuid(getuid()) will not set the saved id
> ONLY if:
>
> (1) _POSIX_SAVED_IDS is set, and
> (2) euid is not root, and
> (3) either
>    (3.1) POSIX_APPENDIX_B_4_2_2 is unset, or
>    (3.2) POSIX_APPENDIX_B_4_2_2 is set and the parameter to setuid() is not
> equal to the euid.

That seems about right (I didn't check the details).  When
POSIX_APPENDIX_B_4_2_2 is set, root (euid = 0) has "appropriate
privilege" to setuid() to anything, and all processes have "appropriate
privilege" to setuid() to their euid, so setuid() sets the saved id
even when _POSIX_SAVED_IDS is set.

> If POSIX_APPENDIX_B_4_2_2 is set, which is the case in the pre-compiled
> kernel (and is also the case for Linux), for setuid(getuid()), the above
> condition requires at least that euid!=0, ruid!=euid, and ruid!=0 (because
> the programmer intends to DROP privilege by setuid(getuid())).  Is there any
> real situation where this condition may arise?

Yes.  This is the usual case for processes that have execed a setuid-to-non-
root program.  When _POSIX_SAVED_IDS is set, it is impossible in previous
versions of POSIX to drop their saved id privilege using setuid() or any
other POSIX function, or even to know if they have extra privilege from
a saved id.  This problem is why _POSIX_SAVED_IDS is not defined in FreeBSD.
POSIX.1-200x has a 4.4BSD compatible seteuid(), so processes can try

	seteuid(getuid();		/* euid = ruid */
	setuid(geteuid());		/* hope this sets svuid = ruid too */

This sets all the ids to the same value in 4.4BSD and FreeBSD, but doesn't
seem to be required to do so in POSIX.1-200x (it depends on everyone
having "appropriate privilege" for setuid(geteuid()).

Bruce


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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20011212211356.L34562-100000>