acl-check-assert.patch:
------------------------
This is a bug fix to the server side acl handling. It replaces an assertion with normal error handling to prevent a server from crashing if it encounters invalid acl information.

check-group.patch:
------------------
This follows up on some recent fixes to the server side group checking. I think the getpwuid_r() has the same issue that getpwuid_r() did, in that you have to check if the last argument is NULL before using the results of the function. There was also a double unlock in the function.

setgid-inherit-acl.patch:
-------------------------
This corrects setgid behavior if the "-o acl" mount option is used; previously the setgid bit was not being inherited by new subdirectories in this scenario.

root-squash.patch:
------------------
This is an update to the root squashing behavior. It is not a 100% correct fix, but I think it is an improvement. Prior to this patch, the root user could still write to an existing root owned file even when squashed. After this patch, all writes from root are disallowed. The basic problem is that there isn't enough permission information on servers at the individual write operation level to decide whether to allow or disallow the squashed write (I/O servers don't have owner or permission data). The easiest fix is to stop all root writes on a squashed file system. Normally a file system would allow root to write to files owned by "nobody" (or whatever uid the mapping points to), but this would be difficult to implement.

The above patch also fixes the get_fs_intent() function; it had a "default: " case that made it too easy to forget to add operations to the list. This patch removes the default case (so warnings show up at build time now) and adds the listattr and smallio operations. The former is needed for root squashing to work as well.

-Phil
Index: pvfs2_src/src/common/misc/pint-util.c
===================================================================
--- pvfs2_src/src/common/misc/pint-util.c	(revision 2755)
+++ pvfs2_src/src/common/misc/pint-util.c	(revision 2756)
@@ -635,7 +635,18 @@
 
     assert((attr->mask & perm_mask) == perm_mask);
     assert(acl_buf);
+#if 0
     assert(acl_size % sizeof(pvfs2_acl_entry) == 0);
+#else
+    /* if the acl format doesn't look valid, then return an error rather than
+     * asserting; we don't want the server to crash due to an invalid keyval
+     */
+    if((acl_size % sizeof(pvfs2_acl_entry)) != 0)
+    {
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "invalid acls on object\n");
+        return(-PVFS_EACCES);
+    }
+#endif
     count = acl_size / sizeof(pvfs2_acl_entry);
 
     for (i = 0; i < count; i++)
diff -Naur pvfs2-orig/src/common/misc/pint-util.c pvfs2/src/common/misc/pint-util.c
--- pvfs2-orig/src/common/misc/pint-util.c	2006-12-14 00:23:55.000000000 -0500
+++ pvfs2/src/common/misc/pint-util.c	2007-03-14 14:41:20.000000000 -0500
@@ -522,14 +522,18 @@
     ret = getpwuid_r(uid, &pwd, check_group_pw_buffer,
         check_group_pw_buffer_size,
         &pwd_p);
-    if(ret != 0)
+    if(ret != 0 || pwd_p == NULL)
     {
         gen_mutex_unlock(&check_group_mutex);
         return(-PVFS_EINVAL);
     }
 
     /* check primary group */
-    if(pwd.pw_gid == gid) return 0;
+    if(pwd.pw_gid == gid)
+    {
+        gen_mutex_unlock(&check_group_mutex);
+        return 0;
+    }
 
     /* get other group information */
     ret = getgrgid_r(gid, &grp, check_group_gr_buffer,
@@ -549,9 +553,6 @@
         return(-PVFS_EACCES);
     }
 
-    gen_mutex_unlock(&check_group_mutex);
-
-
     for(i = 0; grp.gr_mem[i] != NULL; i++)
     {
         if(0 == strcmp(pwd.pw_name, grp.gr_mem[i]) )
Index: pvfs2_src/src/server/prelude.sm
===================================================================
--- pvfs2_src/src/server/prelude.sm	(revision 3020)
+++ pvfs2_src/src/server/prelude.sm	(revision 3021)
@@ -201,10 +201,18 @@
             *fsid = req->u.io.fs_id;
             *read_only = (req->u.io.io_type == PVFS_IO_READ) ? 1 : 0;
             break;
+        case PVFS_SERV_SMALL_IO:
+            *fsid = req->u.small_io.fs_id;
+            *read_only = (req->u.small_io.io_type == PVFS_IO_READ) ? 1 : 0;
+            break;
         case PVFS_SERV_GETATTR:
             *fsid = req->u.getattr.fs_id;
             *read_only = 1;
             break;
+        case PVFS_SERV_LISTATTR:
+            *fsid = req->u.listattr.fs_id;
+            *read_only = 1;
+            break;
         case PVFS_SERV_SETATTR:
             *fsid = req->u.setattr.fs_id;
             *read_only = 0;
@@ -293,7 +301,8 @@
         case PVFS_SERV_MGMT_NOOP:
         case PVFS_SERV_WRITE_COMPLETION:
         case PVFS_SERV_GETCONFIG:
-        default:
+        case PVFS_SERV_NUM_OPS:
+        case PVFS_SERV_INVALID:
             *fsid = PVFS_FS_ID_NULL;
             *read_only = -1;
             break;
@@ -498,6 +508,7 @@
         js_p->error_code = 0;
     }
 #endif
+    
     get_fs_intent(s_op->req, &fsid, &rdonly);
     if (fsid != PVFS_FS_ID_NULL)
     {
Index: pvfs2_src/src/server/prelude.sm
===================================================================
--- pvfs2_src/src/server/prelude.sm	(revision 3024)
+++ pvfs2_src/src/server/prelude.sm	(revision 3025)
@@ -473,6 +473,8 @@
     PVFS_gid translated_gid = s_op->req->credentials.gid;
     PVFS_fs_id  fsid;
     int  rdonly = -1;
+    int squashed_flag = 0;
+    int skip_acl_flag = 0;
 
     /* moved gossip server debug output to end of state, so we can report
      * resulting status value.
@@ -527,6 +529,7 @@
             if (translate_ids(fsid, s_op->req->credentials.uid, s_op->req->credentials.gid,
                 &translated_uid, &translated_gid, s_op->addr) == 1)
             {
+                squashed_flag = 1;
                 s_op->req->credentials.uid = translated_uid;
                 s_op->req->credentials.gid = translated_gid;
                 /* in the case of a setattr, translate the ids as well right here */
@@ -629,7 +632,25 @@
             }
             break;
         case PINT_SERVER_CHECK_NONE:
-            js_p->error_code = 0;
+            if(squashed_flag && !rdonly && ((s_op->req->op == PVFS_SERV_IO) ||
+                (s_op->req->op == PVFS_SERV_SMALL_IO) ||
+                (s_op->req->op == PVFS_SERV_TRUNCATE)))
+            {
+                /* special case:
+                 * If we have been squashed, deny write permission to the
+                 * file system.  At the datafile level we don't have enough
+                 * attribute information to figure out if the nobody/guest
+                 * user has permission to write or not, so we disallow all
+                 * writes to be safe.  Not perfect semantics, but better
+                 * than being too permissive.
+                 */
+                skip_acl_flag = 1;
+                js_p->error_code = -PVFS_EACCES;
+            }
+            else
+            {
+                js_p->error_code = 0;
+            }
             break;
         case PINT_SERVER_CHECK_INVALID:
             js_p->error_code = -PVFS_EINVAL;
@@ -647,7 +668,7 @@
         PINT_map_server_op_to_string(s_op->req->op),
 	js_p->error_code);
     /* If regular checks fail, we need to run acl checks */
-    if (js_p->error_code == -PVFS_EACCES)
+    if (js_p->error_code == -PVFS_EACCES && !skip_acl_flag)
         js_p->error_code = PRELUDE_RUN_ACL_CHECKS;
     return 1;
 }
Index: pvfs2_src/src/kernel/linux-2.6/inode.c
===================================================================
--- pvfs2_src/src/kernel/linux-2.6/inode.c	(revision 3014)
+++ pvfs2_src/src/kernel/linux-2.6/inode.c	(revision 3015)
@@ -512,7 +512,22 @@
          * properly.
          */
         if (from_create)
-            inode->i_mode = mode;
+        {
+            /* the exception is when we are creating a directory that needs
+             * to inherit the setgid bit.  That much we need to preserve from
+             * the getattr's view of the mode.
+             */
+            if(inode->i_mode & S_ISGID)
+            {
+                gossip_debug(GOSSIP_INODE_DEBUG,
+                    "pvfs2_get_custom_inode_commmon: setting SGID bit.\n");
+                inode->i_mode = mode | S_ISGID;
+            }
+            else
+            {
+                inode->i_mode = mode;
+            }
+        }
         gossip_debug(GOSSIP_INODE_DEBUG, 
                 "pvfs2_get_custom_inode_common: inode: %p, inode->i_mode %o\n",
                 inode, inode->i_mode);
_______________________________________________
Pvfs2-developers mailing list
[email protected]
http://www.beowulf-underground.org/mailman/listinfo/pvfs2-developers

Reply via email to