ESC1332@ESOC.bitnet (K.Keyte) (07/14/87)
Of course everyone noticed, after a short time, that the 'cp' command doesn't maintain the SETUID bit. This is clearly for security. Setting the bit with chmod is no problem. There is another problem, however, with the mkdir and rmdir. They are not normally SETUID (at least, not on UNIX). The SETUID bit is needed on MINIX because they call the mknod system service which is reserved for super-user only. To check that the user actually has the required access to the parent directory, mkdir performs an 'access' call. This is almost entirely useless because the setting of the SETUID means that the caller automatically gets a protection mode permission of 07 (meaning that all access modes are granted). So, the overall effect is that mkdir and rmdir can be used by anyone to create and remove directories anywhere! This isn't right, and there are a number of possibilities. Has anyone tried anything, or got any ideas? I made an initial attempt by removing the effective super-user uid before the access call, but of course this means that real AND effective uids are then non super-user, i.e. you can't re-enable the super-user uid with setuid, and the subsequent mknod call fails! The access call makes a further call to 'forbidden' with a flag set to indicate that it should check the REAL uid and not the EFFECTIVE uid. This is ignored, since the file system 'init' program automatically sets the super-user flag for any caller having an effective uid of the super-user. It seems that the solution might be to steal access and modify it a bit, and use the new version inside mkdir and rmdir. Please give me your comments. Perhaps I'm overlooking a more obvious solution, but if I'm not I'm quite prepared to make the changes and post them out. PS: Are we actually allowed to mail Minix electronically (not the original source of course, but changes such as the one I've outlined above)? Karl Keyte
henry@utzoo.UUCP (Henry Spencer) (07/16/87)
> Of course everyone noticed, after a short time, that the 'cp' command > doesn't maintain the SETUID bit... The finger of shame points at whoever wrote cp, then. V7 cp preserves the setuid bit. > ... There is another problem, however, with the > mkdir and rmdir. They are not normally SETUID (at least, not on UNIX). Sorry, they *are* on Unixes (like V7) which do not have mkdir() and rmdir() system calls. Believe me -- utzoo is a V7. > ... To check that the user actually has > the required access to the parent directory, mkdir performs an 'access' call. > This is almost entirely useless because the setting of the SETUID means that > the caller automatically gets a protection mode permission of 07 (meaning that > all access modes are granted). So, the overall effect is that mkdir and rmdir > can be used by anyone to create and remove directories anywhere! ... Sorry, no, you have misunderstood the fine points of setuid bits and the access() system call. The access() call checks permissions against the "real" userid and groupid, which are *not* changed by the setuid bit. This is the way it works in V7 and true V7-compatible systems, anyway. Making mkdir and rmdir owned by root with the setuid bit on is precisely the right thing to do, unless Minix has done something bizarre. -- Support sustained spaceflight: fight | Henry Spencer @ U of Toronto Zoology the soi-disant "Planetary Society"! | {allegra,ihnp4,decvax,utai}!utzoo!henry
ESC1332%ESOC.BITNET@wiscvm.wisc.edu (K.Keyte) (07/22/87)
Let me straighten this mess out with regards to SETUID and mkdir/rmdir... MINIX WAS doing something wrong with the access() system call. The error itself was in forbidden() where it checks the permissions. It's supposed to allow the option to check REAL or EFFECTIVE uids, and access() always asks to check the REAL uid. HOWEVER, forbidden() looks at the global variable super_user (which is set TRUE iff the EFFECTIVE uid is that of the super-user) and grants FULL access if this is set. This is incorrect, the code in forbidden() should be changed FROM: if (super_user) perm_bits = 07; TO: if (test_uid == SU_UID) perm_bits = 07; I hope this stops the barrage of mis-understandings, and we can close the matter. Point 2 ------- I've written a noddy routine to load the MINIX clock from the CMOS battery- backed RAM on an AT. If anyone's interested in the code, let me know and I'll either send them out individually or back to the list depending on the response. Karl
rmtodd@uokmax.UUCP (Richard Michael Todd) (07/22/87)
In article <8308@utzoo.UUCP> henry@utzoo.UUCP (Henry Spencer) writes: >Sorry, no, you have misunderstood the fine points of setuid bits and the >access() system call. The access() call checks permissions against the >"real" userid and groupid, which are *not* changed by the setuid bit. >This is the way it works in V7 and true V7-compatible systems, anyway. Alas, MINIX access() is broke in a couple of ways. The problems lie in the forbidden() routine in the file server, which is supposed to check for given types of access against either real or effective uid, depending on a flag passed to the function. It is called by do_access to check against real uid, and everywhere else to check against euid. Problem 1: forbidden() should grant all access to the file if the uid being checked against (real or effective, depending on the flag) is 0. Alas, the code to do this takes the easy way out,testing a global flag: if (super_user) { (line 11800 of the book) perm_bits = 07; } else {... and this flag is set whenever euid==0. Since mkdir and rmdir always run as euid==0, this allows them access to everything. Problem 2: forbidden, to check if a file is accessible in a certain mode, has to have access to the inode data for the file. (Forbidden's first arg. is a pointer to the inode struct for the file being checked). To get the inode pointer for a given filename, the caller has to first call eat_path. Eat_path has to look in the various directories specified in the pathname, checking each step of the way if the directory is searchable. The checks are always done against effective uid. This is not quite correct. If we do an access("/foo/bar",2), our real uid is not root and our euid is, if our real uid won't allow us execute (search) permission for /foo, the access call should fail. It will succeed. (Admittedly these circumstances are rather unusual, but it is nonetheless a bug, and one that would be a bit tricky to fix.) >Making mkdir and rmdir owned by root with the setuid bit on is precisely >the right thing to do, unless Minix has done something bizarre. Not bizarre, just broken. -------------------------------------------------------------------------- Richard Todd USSnail:820 Annie Court,Norman OK 73069 UUCP: {allegra!cbosgd|ihnp4}!okstate!uokmax!rmtodd