scl@virginia.UUCP (01/29/87)
I personally believe that /etc/mvdir, /etc/link, and /etc/unlink are all very risky programs to have lying around, even when they can only be used by root. I must admit that we have needed /etc/link on several occasions to restore . and .. in a few directories, but I think that SysV should never have allowed . and .. to disappear in the first place! (Has anyone else had this happen on a sysV system? Occasionally after a power failure we are left with directories missing . and/or ..) A big fault with /etc/mvdir is that it allows you to create recursive directories, i.e. move a directory into its own subtree. This is disastrous because it creates a structure that is unreachable from the root of the file system. I think that this is one reason why AT&T doesn't allow mv to do anything other than rename directories. The other reason is the hassle of changing .. to point to the new parent directory, which is trickier than it looks. We also have the problem of being careful not to allow anyone to move . or .. Suppose we want to allow mv to move directories. It must be setuid to root since only root can link(2) or unlink(2) directories. Suppose we want to move /a/b/d to another directory /a/b/c yielding a/b/c/d. We use the command "mv /a/b/d /a/b/c" Our mv command does extensive sanity checks and then performs the move with the following sequence of system calls. link("/a/b/d", "/a/b/c/d"); unlink("/a/b/d"); unlink("/a/b/c/d/.."); link ("/a/b/c", "/a/b/c/d/.."); This has the desired result. Looking at the same example, let's suppose our working directory is /a/b/d. We might be tempted to do the following: mv . /a/b/c This is certainly an error but it gets caught right away. link (".", "/a/b/c/."); /* fails because /a/b/c/. exists */ But what about "mv . /a/b/c/d" ? link (".", "/a/b/c/d"); unlink ("."); unlink ("/a/b/c/d/.."); link ("/a/b/c", "/a/b/c/d/.."); This is a distaster because a/b/d still exists. a/b/c/d also exists, but neither a/b/d/. nor a/b/c/d/. exist. What a mess! So we must never allow the last component of the source directory to be . (or .. for that matter). But how about the destination? As it turns out it is fine to move things to . or .. Our home directory is /a/b/c and the command is "mv ../d ." link ("../d", "./d"); unlink ("../d"); unlink ("./d/.."); link (".", "./d/.."); This works perfectly. But we still have a subtle bug. Our current directory is a/b/d. Our command is mv ../d ../c link ("../d", "../c/d"); unlink ("../d"); unlink ("../c/d/.."); link ("../c" "../c/d/.."); This fails! Note that after the first link and unlink our current working directory is now /a/b/c/d (What else could it be?) When we unlink ../c/d/.. we are unlinking a/b/c/d/.. and thus we are also unlinking .. ! The final link fails because .. no longer exists! To get around this last problem we must change our strategy somewhat. link ("../d", "../c/d"); unlink ("../d"); chdir ("../c"); unlink ("./d/.."); link (".", "./d/.."); And the problem is solved. I have rewritten mv on our system to allow directories to be moved, and avoided all the pitfalls mentioned above. I followed the strategy already used by AT&T. Mv itself is not set uid, but whenever a directory is being moved, mv employs a setuid-to-root program to do it. I also put in the Berkeley "-i" option which causes mv and cp to ask before clobbering a file. If you have a sysV source license I will gladly send you the sources. By the way, there's a bug in the SysV mv (at least on rel2) that I fixed. Suppose the following exist: a file x, and two directories y and y/x. If you are root you can "mv x y" and mv will unlink the directory y/x. Could be real fun if you inadvertently "mv etc /" I personally believe that AT&T limited mv to renaming directories because it avoids the recursion problem and the need to repair the .. entry. Besides, there's always "cpio -pl" (yuck). The convenience of moving directories around is outweighs any so-called "new" security problems. If a directory is writable by me then by god I should certainly be able move other directories in and out of there if I want. If you don't like it, don't give out write permission in that directory. -- Steve Losen
lou@hoxna.UUCP (02/17/87)
In article <138@virginia.acc.virginia.edu>, scl@virginia.UUCP writes: > [ intersting article discussing 'mv' deleted > Besides, there's always "cpio -pl" (yuck). > The convenience of moving directories around is outweighs any so-called > "new" security problems. A small quibble : Since niether your version nor the original appear to do more than rename the directory, what's the advantage ? If you really want to make new files, you still need 'yuckie' cpio. Anyway, link will still fail across file-systems, and most of the time I move directories it seems to be across file systems - users to new places, utilities to new homes, etc. lou @ hoxna