Subversion Repositories livecd

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

diff -ur unionfs-1.1.5.ori/inode.c unionfs-1.1.5/inode.c
--- unionfs-1.1.5.ori/inode.c   2006-06-12 04:03:36.000000000 +0200
+++ unionfs-1.1.5/inode.c       2006-08-30 08:48:02.000000000 +0200
@@ -867,8 +867,43 @@
                retval = generic_permission(inode, submask, NULL);
 #endif
        }
-       
-       if (retval && retval != -EROFS) /* ignore EROFS */
+
+       /* XXX jg
+        * Ignore EROFS but still perform the DAC check.
+        * This block of code added to work around RHEL 4 U3 problem
+        * Where all permission checks would return EROFS on readonly 
+        * file system, and then be converted to 0 below.  The 
+        * result was anyone could write to any file before copyup!
+        * Code mostly lifted from fs/namei.c::vfs_permission().
+        */
+       if (retval == -EROFS) { 
+               umode_t mode = inode->i_mode;
+
+               BUG_ON(bindex == 0); /* handled above */
+               if (current->fsuid == inode->i_uid)
+                       mode >>= 6;
+               else if (in_group_p(inode->i_gid))
+                       mode >>= 3;
+               if (((mode & mask & (MAY_READ|MAY_WRITE|MAY_EXEC)) == mask)) {
+                       retval = 0;
+                       goto out;
+               }
+               if (!(mask & MAY_EXEC) ||
+                   (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode))
+                       if (capable(CAP_DAC_OVERRIDE)) {
+                               retval = 0;
+                               goto out;
+                       }
+               if (mask == MAY_READ || 
+                   (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE)))
+                       if (capable(CAP_DAC_READ_SEARCH)) {
+                               retval = 0;
+                               goto out;
+                       }
+               retval = -EACCES;
+       }
+out:
+               if (retval && retval != -EROFS) /* ignore EROFS */
                return retval;
 
        retval = security_inode_permission(inode, mask, nd);