From owner-freebsd-arch Mon Jun 19 2:13:57 2000 Delivered-To: freebsd-arch@freebsd.org Received: from mailman.zeta.org.au (mailman.zeta.org.au [203.26.10.16]) by hub.freebsd.org (Postfix) with ESMTP id 3552737BC70 for ; Mon, 19 Jun 2000 02:13:52 -0700 (PDT) (envelope-from bde@zeta.org.au) Received: from bde.zeta.org.au (bde.zeta.org.au [203.2.228.102]) by mailman.zeta.org.au (8.8.7/8.8.7) with ESMTP id TAA05030; Mon, 19 Jun 2000 19:13:29 +1000 Date: Mon, 19 Jun 2000 19:13:28 +1000 (EST) From: Bruce Evans X-Sender: bde@besplex.bde.org To: Kirk McKusick Cc: Gregory Neil Shapiro , sendmail-questions@Sendmail.ORG, Eric Allman , arch@FreeBSD.ORG Subject: Re: Broken FreeBSD setuid(2)? In-Reply-To: <200006171745.KAA08559@beastie.mckusick.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-arch@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG On Sat, 17 Jun 2000, Kirk McKusick wrote: > My answer is at the bottom. I am copying the FreeBSD arch group > so they can complain if I am misrepresenting how this came to be. > > > Date: Thu, 15 Jun 2000 12:05:27 -0700 (PDT) > > From: Gregory Neil Shapiro > > ... > > POSIX Part I, section 4.2.2.2 states: > > > > If {_POSIX_SAVED_IDS} is defined: > > ... > > (2) If the process does not have appropriate privileges, but uid is > > equal to the real user ID or the saved set-user-ID, the setuid() > > function sets the effective user ID to uid; the real user ID and > > saved set-user-ID remain unchanged by this function call. > > > > This is the case demonstrated above. It does not have appropriate privileges > > since it is not running as root. The uid is equal to the real UID. This doesn't follow. "appropriate privilege" is implementation-defined. See POSIX.1-1996 section 2.2.2.4. In FreeBSD, appropriate privilege for setuid() is defined as (newuid == geteuid() || geteuid() == 0). This "fixes": 1) Programs that depend on pure !_POSIX_SAVED_IDS behaviour. 4.4BSD(Lite) saved ids are surprising for such programs. 2) There was no "standard" was of dropping the extra privileges given by 4.4BSD(Lite) saved ids using 4.4BSD(Lite) syscalls withoud exec'ing, except for root. In FreeBSD, this can be done using either setreuid(uid, uid)) or the newer setresuid(uid, uid, uid), but depending on setreuid() to do it is dangerous because setreuid() is just a wrapper for seteuid() in 4.4BSD(Lite). > > However, the setuid() function is setting the saved set-user-ID and not > > leaving it unchanged. If it were unchanged, then the second setuid() > > should not fail, again because of this statement and the fact that the uid > > is equal to the saved set-user-ID. > > > > Looking at other implementations, we have found that the second setuid only > > fails on FreeBSD. It succeeds and the program works as expected on > > Solaris, Linux, and OpenBSD. I think 4.4BSDLite-[1-2], NetBSD(at east last year's version), and BSD/OS4.1 have the same behaviour as FreeBSD[3-5] here (some versions of FreeBSD-2 implemented _POSIX_SAVED_IDS so they gave the behaviour that you expected). FreeBSD's definition of "appropriate privilege" is irrelevant in your example. The 4.4BSD(Lite) saved id gives "unappropriate" privilege for setuid() to succeed, and when it succeeds it sets all the ids to the same values. > > I checked /usr/src/sys/kern/kern_prot.c and see comments about appendix B > > but I do not believe they apply to this case. The setuid() man page > > states: Indeed, they don't quite apply. > > It's arguable whether or not you can follow the rules of !_POSIX_SAVED_IDS > > while still using saved IDs as it creates a subtle difference between > > FreeBSD and other operating systems that more than likely goes unnoticed by > > application writers and has the potential of breaking some of these > > programs. This is a 4.4BSD(Lite) feature, not a FreeBSD one. > I agree that FreeBSD does not implement saved id's according > to the Posix spec. And indeed they do not claim to do so as > {_POSIX_SAVED_IDS} is defined as false (see `sysctl kern.saved_ids'). > As released, 4.4BSD defined {_POSIX_SAVED_IDS} as true and had the > behavior of NetBSD and OpenBSD. Posix argues that a non-priviledged Is it really different from 4.4BSD(Lite) here? From in Lite1: --- /* * Although we have saved user/group IDs, we do not use them in setuid * as described in POSIX 1003.1, because the feature does not work for * root. We use the saved IDs in seteuid/setegid, which are not currently * part of the POSIX 1003.1 specification. */ #ifdef _NOT_AVAILABLE #define _POSIX_SAVED_IDS /* saved set-user-ID and set-group-ID */ #endif --- The Lite2 code in kern/kern_prot.c matches this comment. FreeBSD hasn't changed a single byte here in , but has changed kern/kern_prot.c so implement _POSIX_SAVED_IDS if the unsupported option _POSIX_SAVED_IDS is defined at kernel compile time. BSD/OS4.1 has a better comment without a "dontdef" ifdef. BTW, note that _POSIX_SAVED_IDS doesn't mean that there are no saved ids. It means that there are no POSIX ones, and more importantly, that setuid() has the POSIX semantics for the !_POSIX_SAVED_IDS case in setuid(), etc. > ... > The FreeBSD folks decided to change the semantics of setuid to > overwrite the saved user-id so that programs could protect themselves > from stack overflows, debugger attaches, etc. They argue that > seteuid is available if you just want to set the effective user-id > and it is stupid to have a second system call (setuid) which does > exactly the same thing when you are not root. Since Posix never setuid() is still good for setting all the ids to the same value. It goes well with using seteuid() to manipulate the euid. > bought into adding seteuid, they had to overload setuid to get the > equivalent functionality. This is a good example of why Posix options > were a bad idea. By letting each system ship with different option > settings, you end up with very subtilely different semantics. > Each vendor is well meaning, but makes for a programming nightmare > among application developers that have to deal with all the > combinations. POSIX options like _POSIX_SAVED_IDS are simple compared with meta-options like "appropriate privlege". Correct handling of "appropriate privilege" seems to require programs to read and understand the system documentation for it when they start up ;-(. Bruce To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-arch" in the body of the message