Hi
I have made a small patch to rm, which I believe will work around the
problems wrt. translators placed by malicious or misguided users as
previously discussed on help-hurd. In my first attempt to create such a
patch, I have favoured simplicity over advanced features, so it could
probably be done much better.
With this patch, translators that present themselves as directories are
simply not touched by rm, beyond a necessary lstat(), and a warning
message is presented to the user. I believe that the code already
present in rm to prevent symlink race attacks should also be enough to
prevent similar translator attacks.
Demonstration:
dors:/tmp# mkdir dir
dors:/tmp# mkdir dir2
dors:/tmp# touch dir2/testfile
dors:/tmp# touch dir/to_be_deleted
dors:/tmp# settrans -c dir/null /hurd/null
dors:/tmp# settrans -c dir/firm /hurd/firmlink /tmp/dir2
dors:/tmp# ls dir/*
dir/null dir/to_be_deleted
dir/firm:
testfile
dors:/tmp# rm -Rf dir
rm: not removing directory translator `dir/firm'
rm: cannot remove directory `dir': Directory not empty
dors:/tmp# ls dir
firm
dors:/tmp# ls dir2
testfile
Testfile and dir simulate /, $HOME, or whatever else you really don't
want to rm -Rf. To delete "firm" it is necessary to settrans -fgap it
first. (Obviously, the race condition is a bit hard to test properly,
but I guess it can be forced by placing a sleep() in a strategically
good place. I have not done this, however.)
Any comments or suggestions are extremely welcome. I'm likely to have
forgotten something important.
Oystein
--
This message was brought to you by the letter � and the number e.
--- fileutils-4.1.orig/src/remove.c Mon May 6 19:32:06 2002
+++ fileutils-4.1/src/remove.c Mon May 6 19:38:37 2002
@@ -930,6 +930,15 @@ The following two directories have the s
int need_save_cwd = user_specified_name;
enum RM_status status;
+#ifdef S_ITRANS
+ if (filetype_mode & S_ITRANS)
+ {
+ error(0, 0, _("not removing directory translator %s"),
+ quote (full_filename (fs->filename)));
+ return RM_OK;
+ }
+#endif
+
if (need_save_cwd)
need_save_cwd = (strchr (fs->filename, '/') != NULL);