drm: virtio_gpu: add support for ARGB8888 primary plane
[platform/kernel/linux-rpi.git] / security / commoncap.c
index 3f810d3..bc751fa 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/user_namespace.h>
 #include <linux/binfmts.h>
 #include <linux/personality.h>
+#include <linux/mnt_idmapping.h>
 
 /*
  * If a non-root user executes a setuid-root binary in
@@ -400,8 +401,10 @@ int cap_inode_getsecurity(struct user_namespace *mnt_userns,
                                      &tmpbuf, size, GFP_NOFS);
        dput(dentry);
 
-       if (ret < 0 || !tmpbuf)
-               return ret;
+       if (ret < 0 || !tmpbuf) {
+               size = ret;
+               goto out_free;
+       }
 
        fs_ns = inode->i_sb->s_user_ns;
        cap = (struct vfs_cap_data *) tmpbuf;
@@ -418,7 +421,7 @@ int cap_inode_getsecurity(struct user_namespace *mnt_userns,
        kroot = make_kuid(fs_ns, root);
 
        /* If this is an idmapped mount shift the kuid. */
-       kroot = kuid_into_mnt(mnt_userns, kroot);
+       kroot = mapped_kuid_fs(mnt_userns, fs_ns, kroot);
 
        /* If the root kuid maps to a valid uid in current ns, then return
         * this as a nscap. */
@@ -488,6 +491,7 @@ out_free:
  * @size:      size of @ivalue
  * @task_ns:   user namespace of the caller
  * @mnt_userns:        user namespace of the mount the inode was found from
+ * @fs_userns: user namespace of the filesystem
  *
  * If the inode has been found through an idmapped mount the user namespace of
  * the vfsmount must be passed through @mnt_userns. This function will then
@@ -497,7 +501,8 @@ out_free:
  */
 static kuid_t rootid_from_xattr(const void *value, size_t size,
                                struct user_namespace *task_ns,
-                               struct user_namespace *mnt_userns)
+                               struct user_namespace *mnt_userns,
+                               struct user_namespace *fs_userns)
 {
        const struct vfs_ns_cap_data *nscap = value;
        kuid_t rootkid;
@@ -507,7 +512,7 @@ static kuid_t rootid_from_xattr(const void *value, size_t size,
                rootid = le32_to_cpu(nscap->rootid);
 
        rootkid = make_kuid(task_ns, rootid);
-       return kuid_from_mnt(mnt_userns, rootkid);
+       return mapped_kuid_user(mnt_userns, fs_userns, rootkid);
 }
 
 static bool validheader(size_t size, const struct vfs_cap_data *cap)
@@ -553,12 +558,12 @@ int cap_convert_nscap(struct user_namespace *mnt_userns, struct dentry *dentry,
                return -EINVAL;
        if (!capable_wrt_inode_uidgid(mnt_userns, inode, CAP_SETFCAP))
                return -EPERM;
-       if (size == XATTR_CAPS_SZ_2 && (mnt_userns == &init_user_ns))
+       if (size == XATTR_CAPS_SZ_2 && (mnt_userns == fs_ns))
                if (ns_capable(inode->i_sb->s_user_ns, CAP_SETFCAP))
                        /* user is privileged, just write the v2 */
                        return size;
 
-       rootid = rootid_from_xattr(*ivalue, size, task_ns, mnt_userns);
+       rootid = rootid_from_xattr(*ivalue, size, task_ns, mnt_userns, fs_ns);
        if (!uid_valid(rootid))
                return -EINVAL;
 
@@ -699,7 +704,7 @@ int get_vfs_caps_from_disk(struct user_namespace *mnt_userns,
        /* Limit the caps to the mounter of the filesystem
         * or the more limited uid specified in the xattr.
         */
-       rootkuid = kuid_into_mnt(mnt_userns, rootkuid);
+       rootkuid = mapped_kuid_fs(mnt_userns, fs_ns, rootkuid);
        if (!rootid_owns_currentns(rootkuid))
                return -ENODATA;