Date: Wed, 26 Sep 2007 23:56:37 +1000 (EST) From: Bruce Evans <brde@optusnet.com.au> To: d@delphij.net Cc: torfinn.ingolfsen@broadpark.no, freebsd-stable@freebsd.org Subject: Re: rm(1) bug, possibly serious Message-ID: <20070926235630.M7545@besplex.bde.org> In-Reply-To: <46F953C4.1030707@delphij.net> References: <200709251743.l8PHhvlP012244@lurza.secnetix.de> <46F953C4.1030707@delphij.net>
next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 25 Sep 2007, LI Xin wrote: > I think this is a bug, here is a fix obtained from NetBSD. This bug, if any, cannot be fixed in rm. > The reasoning (from NetBSD's rm.c,v 1.16): Bugs can easily be added to rm. > Strip trailing slashes of operands in checkdot(). > > POSIX.2 requires that if "." or ".." are specified as the basename > portion of an operand, a diagnostic message be written to standard > error, etc. Note that POSIX only requires this for the rm utility. (See my previous mail about why this is bogus.) Pathname resolution and a similarly bogus restriction on rmdir(2) requires some operations with dot or dot-dot to fail, and any utility that uses these operations should then print a diagnostic, etc. > We strip the slashes because POSIX.2 defines basename > as the final portion of a pathname after trailing slashes have been > removed. POSIX says "the basename portion of the operand (that is, the final pathname component". This doesn't mean the operand mangled by basename(3). > This also makes rm "perform actions equivalent to" the POSIX.1 > rmdir() and unlink() functions when removing directories and files, > even when they do not follow POSIX.1's pathname resolution semantics > (which require trailing slashes be ignored). Which POSIX.1? POSIX.1-2001 actually requires "trailing slashes shall be resolved as if a single dot character were appended to the pathname". This is completely different from removing the slash: rm <regular file>/ # ENOTDIR rm <regular file> # success unless ENOENT etc. rm <directory>/ # success... rm <directory> # EISDIR rm <symlink to regular file>/ # ENOTDIR rm <symlink to regular file> # success (removes symlink) rm <symlink to directory>/ # EISDIR rm <symlink to directory> # success (removes symlink) rmdir ... # reverse most of above Anyway, mangling the operands makes the utilities perform actions different from the functions. The problem case is "rm -r <symlink to directory>/" which asks for removing the directory pointed to by the symlink and all its contents, and is useful -- you type the trailing symlink if you want to ensure that the removal is as recursive as possible. With breakage of rmdir(2) to POSIX spec, this gives removal the contents of the directory pointed to be the symlink and then fails to remove the directory. With breakage as in NetBSD, this gives removal of the symlink only. > If nobody complains about this I will request for commit approval from re@. ++ Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20070926235630.M7545>