btrfs: fix race between quota disable and quota assign ioctls
[platform/kernel/linux-rpi.git] / fs / posix_acl.c
index f5c25f5..ceb1e3b 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/export.h>
 #include <linux/user_namespace.h>
 #include <linux/namei.h>
+#include <linux/mnt_idmapping.h>
 
 static struct posix_acl **acl_by_type(struct inode *inode, int type)
 {
@@ -375,7 +376,9 @@ posix_acl_permission(struct user_namespace *mnt_userns, struct inode *inode,
                                         goto check_perm;
                                 break;
                         case ACL_USER:
-                               uid = kuid_into_mnt(mnt_userns, pa->e_uid);
+                               uid = mapped_kuid_fs(mnt_userns,
+                                                    i_user_ns(inode),
+                                                    pa->e_uid);
                                if (uid_eq(uid, current_fsuid()))
                                         goto mask;
                                break;
@@ -388,7 +391,9 @@ posix_acl_permission(struct user_namespace *mnt_userns, struct inode *inode,
                                 }
                                break;
                         case ACL_GROUP:
-                               gid = kgid_into_mnt(mnt_userns, pa->e_gid);
+                               gid = mapped_kgid_fs(mnt_userns,
+                                                    i_user_ns(inode),
+                                                    pa->e_gid);
                                if (in_group_p(gid)) {
                                        found = 1;
                                        if ((pa->e_perm & want) == want)
@@ -735,17 +740,17 @@ static void posix_acl_fix_xattr_userns(
                case ACL_USER:
                        uid = make_kuid(from, le32_to_cpu(entry->e_id));
                        if (from_user)
-                               uid = kuid_from_mnt(mnt_userns, uid);
+                               uid = mapped_kuid_user(mnt_userns, &init_user_ns, uid);
                        else
-                               uid = kuid_into_mnt(mnt_userns, uid);
+                               uid = mapped_kuid_fs(mnt_userns, &init_user_ns, uid);
                        entry->e_id = cpu_to_le32(from_kuid(to, uid));
                        break;
                case ACL_GROUP:
                        gid = make_kgid(from, le32_to_cpu(entry->e_id));
                        if (from_user)
-                               gid = kgid_from_mnt(mnt_userns, gid);
+                               gid = mapped_kgid_user(mnt_userns, &init_user_ns, gid);
                        else
-                               gid = kgid_into_mnt(mnt_userns, gid);
+                               gid = mapped_kgid_fs(mnt_userns, &init_user_ns, gid);
                        entry->e_id = cpu_to_le32(from_kgid(to, gid));
                        break;
                default:
@@ -755,9 +760,14 @@ static void posix_acl_fix_xattr_userns(
 }
 
 void posix_acl_fix_xattr_from_user(struct user_namespace *mnt_userns,
+                                  struct inode *inode,
                                   void *value, size_t size)
 {
        struct user_namespace *user_ns = current_user_ns();
+
+       /* Leave ids untouched on non-idmapped mounts. */
+       if (no_idmapping(mnt_userns, i_user_ns(inode)))
+               mnt_userns = &init_user_ns;
        if ((user_ns == &init_user_ns) && (mnt_userns == &init_user_ns))
                return;
        posix_acl_fix_xattr_userns(&init_user_ns, user_ns, mnt_userns, value,
@@ -765,9 +775,14 @@ void posix_acl_fix_xattr_from_user(struct user_namespace *mnt_userns,
 }
 
 void posix_acl_fix_xattr_to_user(struct user_namespace *mnt_userns,
+                                struct inode *inode,
                                 void *value, size_t size)
 {
        struct user_namespace *user_ns = current_user_ns();
+
+       /* Leave ids untouched on non-idmapped mounts. */
+       if (no_idmapping(mnt_userns, i_user_ns(inode)))
+               mnt_userns = &init_user_ns;
        if ((user_ns == &init_user_ns) && (mnt_userns == &init_user_ns))
                return;
        posix_acl_fix_xattr_userns(user_ns, &init_user_ns, mnt_userns, value,