Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/5/84; site mnetor.UUCP Path: utzoo!utcs!mnetor!clewis From: clewis@mnetor.UUCP (Chris Lewis) Newsgroups: net.bugs.usg,net.bugs.4bsd Subject: A hidden gotcha in SCCS on non SYSIII or SYSV systems. Message-ID: <967@mnetor.UUCP> Date: Tue, 11-Jun-85 17:14:11 EDT Article-I.D.: mnetor.967 Posted: Tue Jun 11 17:14:11 1985 Date-Received: Tue, 11-Jun-85 18:41:50 EDT Organization: Computer X (CANADA) Ltd., Toronto, Ontario, Canada Lines: 69 Xref: utcs net.bugs.usg:243 net.bugs.4bsd:1476 To all you people using SCCS on a non-SYSIII, SYSV or PWB system. SCCS is relying upon a hidden "feature" of "setuid" for its operation. Description: In the SV kernel, when the user exec's a setuid program, the kernel remembers this fact and propagates the id of the program to the children, I think... (during forks). It certainly does it to the program that was the setuid program. Then, if the program or child setuids to the real userid, the SV kernel will ALSO let him setuid back to the effective id of the setuid program. Get -e uses something like: lock(z.file) (creates z.file, using effective id) holdid = geteuid(); setuid(getuid()); ... do the get -e ... setuid(holdid); unlock(z.file); (attempts to unlink, effective=realid) Of course, the "unlock" fails on a V7 or BSD system (or a Pyramid in either universe). Normally this is not a problem, because get is running: real = effective = user's id However, if "get" is being run setuid (so that you can cross userid boundaries for multiple userid projects), the unlink will fail, and the z.file will be left lying around. This "feature" is not documented in AT&T setuid(2), but it is easy to see in the kernel sources. (note: this may or not be a dramatic security hole depending upon what the kernel sets it to the first time. Make sure that /etc/init is not setuid!) Repeat-by: /* cc -o setutest setutest.c chown somebody setutest chmod 6755 setutest su somebody else Then run this program (in a directory owned by "somebody"). on an AT&T system, the file "setu" is created then deleted. On a BSD system (and pyramid att universe) "setu" is created but NOT deleted */ main() { /* here I am really you, effectively somebody else */ int fd; int oldu; oldu = geteuid(); fd = creat("setu", 0444); write(fd, "hello", 6); close(fd); setuid(getuid()); /* here's the trick, ATT remembers that you were chmod 6755'd, all children are then allowed to setuid BACK to the owner id of the setuid program */ setuid(oldu); printf("On Pyramid and vanilla BSD's this is -1: %d\n", unlink("setu")); } -- Chris Lewis, UUCP: {allegra, linus, ihnp4}!utzoo!mnetor!clewis BELL: (416)-475-8980 ext. 321