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

Reply via email to