Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 10 Dec 2001 23:35:18 -0800
From:      Hao Chen <haochen@uclink.berkeley.edu>
To:        freebsd-audit@freebsd.org, freebsd-security@freebsd.org
Subject:   setuid() POSIX compliance
Message-ID:  <3C15B736.7080605@uclink.berkeley.edu>

next in thread | raw e-mail | index | archive | help
Hi,

I am a graduate student doing computer security research and I am looking at 
the implementation of setuid() system call in FreeBSD 4.4 Release.  I have 
the following questions:

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?

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.  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.

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?

#ifdef _POSIX_SAVED_IDS
	/*
	 * Do we have "appropriate privileges" (are we root or uid == euid)
	 * If so, we are changing the real uid and/or saved uid.
	 */
	if (
#ifdef POSIX_APPENDIX_B_4_2_2	/* Use the clause from B.4.2.2 */
	    uid == pc->pc_ucred->cr_uid ||
#endif
	    suser_xxx(0, p, PRISON_ROOT) == 0) /* we are using privs */
#endif
	{
            // set saved id

Thank you in advance!

- Hao


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?3C15B736.7080605>