Re: rm(1) bug, possibly serious



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

_______________________________________________
freebsd-stable@xxxxxxxxxxx mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-stable
To unsubscribe, send any mail to "freebsd-stable-unsubscribe@xxxxxxxxxxx"



Relevant Pages

  • Re: List of Linux commands??
    ... shell execution environment (see \fIShell Execution Environment\fP ... If the first component of the \fIdirectory\fP operand is dot or dot-dot, ... Starting with the first pathname in the colon-separated pathnames ...
    (alt.os.linux)
  • Re: rename() a directory over a symlink
    ... "If the old argument points to the pathname of a directory, ... "In the second synopsis form, mv shall move each file named by a source_file ... operand to a destination file in the existing directory named by the target_dir ... operand, or referenced if target_dir is a symbolic link referring to an existing ...
    (Linux-Kernel)
  • Re: Strange behavior of mv(1)
    ... The destination path for each operand is the pathname produced by the ... mkdir -p t/a/b ... However, with different filesystems: ...
    (freebsd-current)
  • Re: ls
    ... end in a symlink that refers to a directory. ... pathname must match a directory. ... If a symbolic link is encountered during pathname resolution, ... a trailing slash forces symlinks to ...
    (comp.unix.shell)
  • Re: access() is a security hole?
    ... >> to securely get to the final pathname component. ... >> have to use lstatto detect a symlink and there is a gap between ... >> the lstat() and subsequent open. ... there ought to be a version of the open syscall that takes ...
    (FreeBSD-Security)

Quantcast