]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - fs/attr.c
UBUNTU: Ubuntu-4.13.0-45.50
[mirror_ubuntu-artful-kernel.git] / fs / attr.c
index 135304146120bc1230642784f93e3587b196abdc..f268fed37df44253005b392c53bc1dc2ff5e1b0b 100644 (file)
--- a/fs/attr.c
+++ b/fs/attr.c
 #include <linux/evm.h>
 #include <linux/ima.h>
 
+static bool chown_ok(const struct inode *inode, kuid_t uid)
+{
+       if (uid_eq(current_fsuid(), inode->i_uid) &&
+           uid_eq(uid, inode->i_uid))
+               return true;
+       if (capable_wrt_inode_uidgid(inode, CAP_CHOWN))
+               return true;
+       if (ns_capable(inode->i_sb->s_user_ns, CAP_CHOWN))
+               return true;
+       return false;
+}
+
+static bool chgrp_ok(const struct inode *inode, kgid_t gid)
+{
+       if (uid_eq(current_fsuid(), inode->i_uid) &&
+           (in_group_p(gid) || gid_eq(gid, inode->i_gid)))
+               return true;
+       if (capable_wrt_inode_uidgid(inode, CAP_CHOWN))
+               return true;
+       if (ns_capable(inode->i_sb->s_user_ns, CAP_CHOWN))
+               return true;
+       return false;
+}
+
 /**
  * setattr_prepare - check if attribute changes to a dentry are allowed
  * @dentry:    dentry to check
@@ -51,17 +75,11 @@ int setattr_prepare(struct dentry *dentry, struct iattr *attr)
                goto kill_priv;
 
        /* Make sure a caller can chown. */
-       if ((ia_valid & ATTR_UID) &&
-           (!uid_eq(current_fsuid(), inode->i_uid) ||
-            !uid_eq(attr->ia_uid, inode->i_uid)) &&
-           !capable_wrt_inode_uidgid(inode, CAP_CHOWN))
+       if ((ia_valid & ATTR_UID) && !chown_ok(inode, attr->ia_uid))
                return -EPERM;
 
        /* Make sure caller can chgrp. */
-       if ((ia_valid & ATTR_GID) &&
-           (!uid_eq(current_fsuid(), inode->i_uid) ||
-           (!in_group_p(attr->ia_gid) && !gid_eq(attr->ia_gid, inode->i_gid))) &&
-           !capable_wrt_inode_uidgid(inode, CAP_CHOWN))
+       if ((ia_valid & ATTR_GID) && !chgrp_ok(inode, attr->ia_gid))
                return -EPERM;
 
        /* Make sure a caller can chmod. */