Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!mcvax!unido!tub!net From: net@tub.UUCP Newsgroups: comp.unix.wizards Subject: 4.2BSD: Bug in setreuid()? - (nf) Message-ID: <50100001@tub.UUCP> Date: Sun, 14-Dec-86 10:59:00 EST Article-I.D.: tub.50100001 Posted: Sun Dec 14 10:59:00 1986 Date-Received: Tue, 16-Dec-86 04:29:13 EST Lines: 54 Nf-ID: #N:tub:50100001:000:2210 Nf-From: tub!net Dec 14 16:59:00 1986 There seems to be a bug in the 4.2BSD setreuid(2) system call. Typically, setreuid() is used in set-userid (not necessarily set-uid root!) programs to temporarily switch back to the caller's userid (e.g. in order to create a temp file with the appropriate owner) as follows: int real = getuid(), eff = geteuid(); /* * The following call to setreuid() swaps the real and the * effective userids: */ setreuid (eff, real); /* * Now the effective userid is equal to the userid of the caller. * Thus, a file can be created with proper checking of permissions * and an owner equal to the caller of the program. */ ... /* Reset the userids to their original values: */ setreuid (real, eff); One might expect that the two consecutive calls to setreuid() do not affect the rest of the program, i.e. code that works before the first call to setreuid() should as well work after the userids have been swapped the second time. Alas, this is not true. Compile and test the following program (the executable must have the set-userid bit set and should have an owner different from the caller): main () { int real = getuid(), eff = geteuid(); setreuid (eff, real); /* This isn't even necessary to get the effect */ setreuid (real, eff); if (kill (getpid(), SIGTSTP) == -1) perror ("kill"); } You will find out that the call to kill() fails ("Not owner"). This must be a bug (not necessarily in kill()), because the man page for kill(2) says that the sending and receiving processes must have the same effective userid. Inspection of the kernel source reveals that setreuid() sets u.u_procp->p_uid to the *real* userid, while the kill() syscall expects that p->p_uid holds the *effective* userid (in fact, kill checks if p->p_uid==u.u_uid). Note that u.u_procp->p_uid is always set to the effective userid by the exec() syscall. Is this a bug or a feature? Are processes that have to switch between two userids not supposed to send themselves signals? Is this ``Fixed In 4.3''? Comments and/or help are appreciated. -- Regards, Oliver Laumann, Technical University of Berlin, Germany. ...pyramid!tub!net or net@TUB.BITNET