}
 }
 
-void posix_acl_setxattr_idmapped_mnt(struct user_namespace *mnt_userns,
-                                    const struct inode *inode,
-                                    void *value, size_t size)
-{
-       struct posix_acl_xattr_header *header = value;
-       struct posix_acl_xattr_entry *entry = (void *)(header + 1), *end;
-       struct user_namespace *fs_userns = i_user_ns(inode);
-       int count;
-       vfsuid_t vfsuid;
-       vfsgid_t vfsgid;
-       kuid_t uid;
-       kgid_t gid;
-
-       if (no_idmapping(mnt_userns, i_user_ns(inode)))
-               return;
-
-       count = posix_acl_fix_xattr_common(value, size);
-       if (count <= 0)
-               return;
-
-       for (end = entry + count; entry != end; entry++) {
-               switch (le16_to_cpu(entry->e_tag)) {
-               case ACL_USER:
-                       uid = make_kuid(&init_user_ns, le32_to_cpu(entry->e_id));
-                       vfsuid = VFSUIDT_INIT(uid);
-                       uid = from_vfsuid(mnt_userns, fs_userns, vfsuid);
-                       entry->e_id = cpu_to_le32(from_kuid(&init_user_ns, uid));
-                       break;
-               case ACL_GROUP:
-                       gid = make_kgid(&init_user_ns, le32_to_cpu(entry->e_id));
-                       vfsgid = VFSGIDT_INIT(gid);
-                       gid = from_vfsgid(mnt_userns, fs_userns, vfsgid);
-                       entry->e_id = cpu_to_le32(from_kgid(&init_user_ns, gid));
-                       break;
-               default:
-                       break;
-               }
-       }
-}
-
 static void posix_acl_fix_xattr_userns(
        struct user_namespace *to, struct user_namespace *from,
        void *value, size_t size)
        int ret;
 
        if (value) {
-               acl = posix_acl_from_xattr(&init_user_ns, value, size);
+               /*
+                * By the time we end up here the {g,u}ids stored in
+                * ACL_{GROUP,USER} have already been mapped according to the
+                * caller's idmapping. The vfs_set_acl_prepare() helper will
+                * recover them and take idmapped mounts into account. The
+                * filesystem will receive the POSIX ACLs in in the correct
+                * format ready to be cached or written to the backing store
+                * taking the filesystem idmapping into account.
+                */
+               acl = vfs_set_acl_prepare(mnt_userns, i_user_ns(inode),
+                                         value, size);
                if (IS_ERR(acl))
                        return PTR_ERR(acl);
        }
 
 void posix_acl_getxattr_idmapped_mnt(struct user_namespace *mnt_userns,
                                     const struct inode *inode,
                                     void *value, size_t size);
-void posix_acl_setxattr_idmapped_mnt(struct user_namespace *mnt_userns,
-                                    const struct inode *inode,
-                                    void *value, size_t size);
 #else
 static inline void posix_acl_fix_xattr_from_user(void *value, size_t size)
 {
                                size_t size)
 {
 }
-static inline void
-posix_acl_setxattr_idmapped_mnt(struct user_namespace *mnt_userns,
-                               const struct inode *inode, void *value,
-                               size_t size)
-{
-}
 #endif
 
 struct posix_acl *posix_acl_from_xattr(struct user_namespace *user_ns, 
 
        int rc;
 
        /*
-        * user_ns is not relevant here, ACL_USER/ACL_GROUP don't have impact
-        * on the inode mode (see posix_acl_equiv_mode()).
+        * An earlier comment here mentioned that the idmappings for
+        * ACL_{GROUP,USER} don't matter since EVM is only interested in the
+        * mode stored as part of POSIX ACLs. Nonetheless, if it must translate
+        * from the uapi POSIX ACL representation to the VFS internal POSIX ACL
+        * representation it should do so correctly. There's no guarantee that
+        * we won't change POSIX ACLs in a way that ACL_{GROUP,USER} matters
+        * for the mode at some point and it's difficult to keep track of all
+        * the LSM and integrity modules and what they do to POSIX ACLs.
+        *
+        * Frankly, EVM shouldn't try to interpret the uapi struct for POSIX
+        * ACLs it received. It requires knowledge that only the VFS is
+        * guaranteed to have.
         */
-       acl = posix_acl_from_xattr(&init_user_ns, xattr_value, xattr_value_len);
+       acl = vfs_set_acl_prepare(mnt_userns, i_user_ns(inode),
+                                 xattr_value, xattr_value_len);
        if (IS_ERR_OR_NULL(acl))
                return 1;