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);