Whamcloud - gitweb
LU-10926 llite: avoid panic in ll_set_acl() 45/32045/2
authorJames Simmons <uja.ornl@yahoo.com>
Wed, 18 Apr 2018 14:28:48 +0000 (10:28 -0400)
committerOleg Drokin <oleg.drokin@intel.com>
Wed, 2 May 2018 02:21:08 +0000 (02:21 +0000)
While pushing the xattr work upstream Dan Carpenter noticed a bug
in ll_set_acl() that could panic a node. The problem is in the
case of default the code jumps to out: which calls the function
forget_cached_acl(). If you call forget_cached_acl() with a type
not related to ACLs it will crash the node via a BUG(). To avoid
this just test rc after the switch block and return since neither
the acl or xattr have been modified.

Change-Id: Ib6f3e5e818635c56cc4abbf37e7c63e6897a72a6
Signed-off-by: James Simmons <uja.ornl@yahoo.com>
Reviewed-on: https://review.whamcloud.com/32045
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Dmitry Eremin <dmitry.eremin@intel.com>
lustre/llite/file.c

index dbdbb9e..4877b80 100644 (file)
@@ -4436,28 +4436,28 @@ int ll_set_acl(struct inode *inode, struct posix_acl *acl, int type)
        const char *name = NULL;
        char *value = NULL;
        size_t value_size = 0;
-       int rc;
+       int rc = 0;
        ENTRY;
 
        switch (type) {
        case ACL_TYPE_ACCESS:
                name = XATTR_NAME_POSIX_ACL_ACCESS;
-               if (acl) {
+               if (acl)
                        rc = posix_acl_update_mode(inode, &inode->i_mode, &acl);
-                       if (rc)
-                               GOTO(out, rc);
-               }
-
                break;
+
        case ACL_TYPE_DEFAULT:
                name = XATTR_NAME_POSIX_ACL_DEFAULT;
                if (!S_ISDIR(inode->i_mode))
-                       GOTO(out, rc = acl ? -EACCES : 0);
-
+                       rc = acl ? -EACCES : 0;
                break;
+
        default:
-               GOTO(out, rc = -EINVAL);
+               rc = -EINVAL;
+               break;
        }
+       if (rc)
+               return rc;
 
        if (acl) {
                value_size = posix_acl_xattr_size(acl->a_count);
@@ -4478,10 +4478,10 @@ int ll_set_acl(struct inode *inode, struct posix_acl *acl, int type)
 out_value:
        kfree(value);
 out:
-       if (!rc)
-               set_cached_acl(inode, type, acl);
-       else
+       if (rc)
                forget_cached_acl(inode, type);
+       else
+               set_cached_acl(inode, type, acl);
        RETURN(rc);
 }
 #endif /* CONFIG_FS_POSIX_ACL */