rm -r fails to delete entire hierarchy when path goes in and out of it

Gian Ntzik gian.ntzik08 at imperial.ac.uk
Wed Sep 17 04:46:37 UTC 2014


Hello,

It seems that using rm -r with a path that goes into the hierarchy
intended for removal (and back up e.g. using dot-dots) fails to remove
the entire hierarchy.

For example,

$ mkdir -p /tmp/a/b/c
$ mkdir -p /tmp/a/e
$ rm -r /tmp/a/b/../../a
rm: can't remove 'a/b/../../a/e': No such file or directory
rm: can't remove 'a/b/../../a': No such file or directory

Then,

$ ls /tmp/a
e

in this case /tmp/a/b/c and /tmp/a/b have been removed but not /tmp/a/e.
I have tested this with the latest busybox-i686 binary available for
download (09-Jul-2013 02:02).

I believe this is a bug and not the intended behaviour of rm -r.

Looking at the source code, I think this behavior is due to the function
remove_file (in /libbb/remove_file.c), which implements the recursive
remove, appends each entry name read by readdir() to the remove_file's
path argument to form the argument of the recursive call.

In the example above, remove_file will first remove /tmp/a/b/e using the
path /tmp/a/b/../../a/b/e, then it will remove /tmp/a/b by using
/tmp/a/b/../../a/b. Next, it will try to remove /tmp/a/e by using the
path /tmp/a/b/../../a/e which fails since /tmp/a/b no longer exists.

A simple solution to this problem would be to canonicallise the initial
path argument to remove_file when called by rr_main, by using realpath()
or some equivalent.

Kind regards,

Gian Ntzik


More information about the busybox mailing list