GNU bug report logs -
#12339
Bug: rm -fr . doesn't dir depth first deletion yet it is documented to do so.
Previous Next
Reported by: Linda Walsh <coreutils <at> tlinx.org>
Date: Mon, 3 Sep 2012 00:34:02 UTC
Severity: normal
Done: Assaf Gordon <assafgordon <at> gmail.com>
Bug is archived. No further changes may be made.
Full log
Message #50 received at 12339 <at> debbugs.gnu.org (full text, mbox):
On 09/03/2012 10:04 PM, Paul Eggert wrote:
> I was about to suggest the following, on GNU/Linux:
>
> # Don't do this unless you know what you're doing!
> rm -fr /proc/self/cwd/
>
> Except it doesn't work! Not even if I append '.':
>
> $ mkdir /tmp/victim
> $ cd /tmp/victim
> $ touch foo
> $ rm -fr /proc/self/cwd/
> rm: cannot remove `/proc/self/cwd': Too many levels of symbolic links
That is in rm_fts():
/* Perform checks that can apply only for command-line arguments. */
if (ent->fts_level == FTS_ROOTLEVEL)
{
if (strip_trailing_slashes (ent->fts_path))
ent->fts_pathlen = strlen (ent->fts_path);
ent->fts_path is stripped from /proc/self/cwd/ to /proc/self/cwd.
Then this:
Ternary is_empty_directory;
enum RM_status s = prompt (fts, ent, true /*is_dir*/, x,
PA_DESCEND_INTO_DIR, &is_empty_directory);
if (s == RM_OK && is_empty_directory == T_YES)
{
/* When we know (from prompt when in interactive mode)
that this is an empty directory, don't prompt twice. */
s = excise (fts, ent, x, true);
fts_skip_tree (fts, ent);
}
s is RM_OK, but is_empty_directory is T_NO, because it's no DIR ...
The FTS loop continues and diagnoses ELOOP. That's the strace output:
newfstatat(AT_FDCWD, "/proc/self/cwd/", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0
openat(AT_FDCWD, "/proc/self/cwd", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_DIRECTORY|O_NOFOLLOW) = -1 ELOOP (Too many levels of
symbolic links)
openat(AT_FDCWD, "/proc/self/cwd", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_DIRECTORY|O_NOFOLLOW) = -1 ELOOP (Too many levels of
symbolic links)
unlinkat(AT_FDCWD, "/proc/self/cwd", AT_REMOVEDIR) = -1 EACCES (Permission denied)
The example applies to all symlinks to directories (i.e. not only
to /proc/self/cwd):
$ mkdir d
$ touch d/file
$ ln -s d dl
$ rm -rv dl/
/home/berny/cu/src/rm: cannot remove ‘dl’: Too many levels of symbolic links
However, in this case, unlinkat returns ENOTDIR:
unlinkat(AT_FDCWD, "dl", AT_REMOVEDIR) = -1 ENOTDIR (Not a directory)
> $ rm -fr /proc/self/cwd/.
> rm: cannot remove directory: `/proc/self/cwd/.'
> $ ls
> foo
That's the dot case.
> Aren't these bugs, at least?
The latter: no, because dot must not be removed.
The former: maybe, but the question is what rm should remove:
the symlink or the target? The info page is quiet about this.
I tend to say it's okay as it is, because if someone wants to
remove the target of a symlink,(s)he can always to
$ rm -rv $(readlink -f dl)
Only the diagnostic (ELOOP) looks a bit strange ...
Have a nice day,
Berny
This bug report was last modified 6 years and 186 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.