if (ia_valid & ATTR_KILL_PRIV) {
                int error;
 
-               error = security_inode_killpriv(dentry);
+               error = security_inode_killpriv(mnt_userns, dentry);
                if (error)
                        return error;
        }
 
        if (error)
                return error;
 
-       error = security_inode_setxattr(dentry, name, value, size, flags);
+       error = security_inode_setxattr(mnt_userns, dentry, name, value, size,
+                                       flags);
        if (error)
                goto out;
 
 EXPORT_SYMBOL_GPL(vfs_setxattr);
 
 static ssize_t
-xattr_getsecurity(struct inode *inode, const char *name, void *value,
-                       size_t size)
+xattr_getsecurity(struct user_namespace *mnt_userns, struct inode *inode,
+                 const char *name, void *value, size_t size)
 {
        void *buffer = NULL;
        ssize_t len;
 
        if (!value || !size) {
-               len = security_inode_getsecurity(inode, name, &buffer, false);
+               len = security_inode_getsecurity(mnt_userns, inode, name,
+                                                &buffer, false);
                goto out_noalloc;
        }
 
-       len = security_inode_getsecurity(inode, name, &buffer, true);
+       len = security_inode_getsecurity(mnt_userns, inode, name, &buffer,
+                                        true);
        if (len < 0)
                return len;
        if (size < len) {
        if (!strncmp(name, XATTR_SECURITY_PREFIX,
                                XATTR_SECURITY_PREFIX_LEN)) {
                const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
-               int ret = xattr_getsecurity(inode, suffix, value, size);
+               int ret = xattr_getsecurity(mnt_userns, inode, suffix, value,
+                                           size);
                /*
                 * Only overwrite the return value if a security module
                 * is actually active.
        if (error)
                return error;
 
-       error = security_inode_removexattr(dentry, name);
+       error = security_inode_removexattr(mnt_userns, dentry, name);
        if (error)
                goto out;
 
 
 }
 
 /* audit system wants to get cap info from files as well */
-extern int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps);
+int get_vfs_caps_from_disk(struct user_namespace *mnt_userns,
+                          const struct dentry *dentry,
+                          struct cpu_vfs_cap_data *cpu_caps);
 
 int cap_convert_nscap(struct user_namespace *mnt_userns, struct dentry *dentry,
                      const void **ivalue, size_t size);
 
 LSM_HOOK(int, 0, inode_permission, struct inode *inode, int mask)
 LSM_HOOK(int, 0, inode_setattr, struct dentry *dentry, struct iattr *attr)
 LSM_HOOK(int, 0, inode_getattr, const struct path *path)
-LSM_HOOK(int, 0, inode_setxattr, struct dentry *dentry, const char *name,
-        const void *value, size_t size, int flags)
+LSM_HOOK(int, 0, inode_setxattr, struct user_namespace *mnt_userns,
+        struct dentry *dentry, const char *name, const void *value,
+        size_t size, int flags)
 LSM_HOOK(void, LSM_RET_VOID, inode_post_setxattr, struct dentry *dentry,
         const char *name, const void *value, size_t size, int flags)
 LSM_HOOK(int, 0, inode_getxattr, struct dentry *dentry, const char *name)
 LSM_HOOK(int, 0, inode_listxattr, struct dentry *dentry)
-LSM_HOOK(int, 0, inode_removexattr, struct dentry *dentry, const char *name)
+LSM_HOOK(int, 0, inode_removexattr, struct user_namespace *mnt_userns,
+        struct dentry *dentry, const char *name)
 LSM_HOOK(int, 0, inode_need_killpriv, struct dentry *dentry)
-LSM_HOOK(int, 0, inode_killpriv, struct dentry *dentry)
-LSM_HOOK(int, -EOPNOTSUPP, inode_getsecurity, struct inode *inode,
-        const char *name, void **buffer, bool alloc)
+LSM_HOOK(int, 0, inode_killpriv, struct user_namespace *mnt_userns,
+        struct dentry *dentry)
+LSM_HOOK(int, -EOPNOTSUPP, inode_getsecurity, struct user_namespace *mnt_userns,
+        struct inode *inode, const char *name, void **buffer, bool alloc)
 LSM_HOOK(int, -EOPNOTSUPP, inode_setsecurity, struct inode *inode,
         const char *name, const void *value, size_t size, int flags)
 LSM_HOOK(int, 0, inode_listsecurity, struct inode *inode, char *buffer,
 
  * @inode_killpriv:
  *     The setuid bit is being removed.  Remove similar security labels.
  *     Called with the dentry->d_inode->i_mutex held.
+ *     @mnt_userns: user namespace of the mount
  *     @dentry is the dentry being changed.
  *     Return 0 on success.  If error is returned, then the operation
  *     causing setuid bit removal is failed.
 
                      const kernel_cap_t *inheritable,
                      const kernel_cap_t *permitted);
 extern int cap_bprm_creds_from_file(struct linux_binprm *bprm, struct file *file);
-extern int cap_inode_setxattr(struct dentry *dentry, const char *name,
-                             const void *value, size_t size, int flags);
-extern int cap_inode_removexattr(struct dentry *dentry, const char *name);
-extern int cap_inode_need_killpriv(struct dentry *dentry);
-extern int cap_inode_killpriv(struct dentry *dentry);
-extern int cap_inode_getsecurity(struct inode *inode, const char *name,
-                                void **buffer, bool alloc);
+int cap_inode_setxattr(struct dentry *dentry, const char *name,
+                      const void *value, size_t size, int flags);
+int cap_inode_removexattr(struct user_namespace *mnt_userns,
+                         struct dentry *dentry, const char *name);
+int cap_inode_need_killpriv(struct dentry *dentry);
+int cap_inode_killpriv(struct user_namespace *mnt_userns,
+                      struct dentry *dentry);
+int cap_inode_getsecurity(struct user_namespace *mnt_userns,
+                         struct inode *inode, const char *name, void **buffer,
+                         bool alloc);
 extern int cap_mmap_addr(unsigned long addr);
 extern int cap_mmap_file(struct file *file, unsigned long reqprot,
                         unsigned long prot, unsigned long flags);
 int security_inode_permission(struct inode *inode, int mask);
 int security_inode_setattr(struct dentry *dentry, struct iattr *attr);
 int security_inode_getattr(const struct path *path);
-int security_inode_setxattr(struct dentry *dentry, const char *name,
+int security_inode_setxattr(struct user_namespace *mnt_userns,
+                           struct dentry *dentry, const char *name,
                            const void *value, size_t size, int flags);
 void security_inode_post_setxattr(struct dentry *dentry, const char *name,
                                  const void *value, size_t size, int flags);
 int security_inode_getxattr(struct dentry *dentry, const char *name);
 int security_inode_listxattr(struct dentry *dentry);
-int security_inode_removexattr(struct dentry *dentry, const char *name);
+int security_inode_removexattr(struct user_namespace *mnt_userns,
+                              struct dentry *dentry, const char *name);
 int security_inode_need_killpriv(struct dentry *dentry);
-int security_inode_killpriv(struct dentry *dentry);
-int security_inode_getsecurity(struct inode *inode, const char *name, void **buffer, bool alloc);
+int security_inode_killpriv(struct user_namespace *mnt_userns,
+                           struct dentry *dentry);
+int security_inode_getsecurity(struct user_namespace *mnt_userns,
+                              struct inode *inode, const char *name,
+                              void **buffer, bool alloc);
 int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags);
 int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size);
 void security_inode_getsecid(struct inode *inode, u32 *secid);
        return 0;
 }
 
-static inline int security_inode_setxattr(struct dentry *dentry,
-               const char *name, const void *value, size_t size, int flags)
+static inline int security_inode_setxattr(struct user_namespace *mnt_userns,
+               struct dentry *dentry, const char *name, const void *value,
+               size_t size, int flags)
 {
        return cap_inode_setxattr(dentry, name, value, size, flags);
 }
        return 0;
 }
 
-static inline int security_inode_removexattr(struct dentry *dentry,
-                       const char *name)
+static inline int security_inode_removexattr(struct user_namespace *mnt_userns,
+                                            struct dentry *dentry,
+                                            const char *name)
 {
-       return cap_inode_removexattr(dentry, name);
+       return cap_inode_removexattr(mnt_userns, dentry, name);
 }
 
 static inline int security_inode_need_killpriv(struct dentry *dentry)
        return cap_inode_need_killpriv(dentry);
 }
 
-static inline int security_inode_killpriv(struct dentry *dentry)
+static inline int security_inode_killpriv(struct user_namespace *mnt_userns,
+                                         struct dentry *dentry)
 {
-       return cap_inode_killpriv(dentry);
+       return cap_inode_killpriv(mnt_userns, dentry);
 }
 
-static inline int security_inode_getsecurity(struct inode *inode, const char *name, void **buffer, bool alloc)
+static inline int security_inode_getsecurity(struct user_namespace *mnt_userns,
+                                            struct inode *inode,
+                                            const char *name, void **buffer,
+                                            bool alloc)
 {
-       return cap_inode_getsecurity(inode, name, buffer, alloc);
+       return cap_inode_getsecurity(mnt_userns, inode, name, buffer, alloc);
 }
 
 static inline int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags)
 
        if (!dentry)
                return 0;
 
-       rc = get_vfs_caps_from_disk(dentry, &caps);
+       rc = get_vfs_caps_from_disk(&init_user_ns, dentry, &caps);
        if (rc)
                return rc;
 
        ax->d.next = context->aux;
        context->aux = (void *)ax;
 
-       get_vfs_caps_from_disk(bprm->file->f_path.dentry, &vcaps);
+       get_vfs_caps_from_disk(&init_user_ns,
+                              bprm->file->f_path.dentry, &vcaps);
 
        ax->fcap.permitted = vcaps.permitted;
        ax->fcap.inheritable = vcaps.inheritable;
 
 
 /**
  * cap_inode_killpriv - Erase the security markings on an inode
- * @dentry: The inode/dentry to alter
+ *
+ * @mnt_userns:        user namespace of the mount the inode was found from
+ * @dentry:    The inode/dentry to alter
  *
  * Erase the privilege-enhancing security markings on an inode.
  *
+ * 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
+ * take care to map the inode according to @mnt_userns before checking
+ * permissions. On non-idmapped mounts or if permission checking is to be
+ * performed on the raw inode simply passs init_user_ns.
+ *
  * Returns 0 if successful, -ve on error.
  */
-int cap_inode_killpriv(struct dentry *dentry)
+int cap_inode_killpriv(struct user_namespace *mnt_userns, struct dentry *dentry)
 {
        int error;
 
-       error = __vfs_removexattr(&init_user_ns, dentry, XATTR_NAME_CAPS);
+       error = __vfs_removexattr(mnt_userns, dentry, XATTR_NAME_CAPS);
        if (error == -EOPNOTSUPP)
                error = 0;
        return error;
  * by the integrity subsystem, which really wants the unconverted values -
  * so that's good.
  */
-int cap_inode_getsecurity(struct inode *inode, const char *name, void **buffer,
+int cap_inode_getsecurity(struct user_namespace *mnt_userns,
+                         struct inode *inode, const char *name, void **buffer,
                          bool alloc)
 {
        int size, ret;
                return -EINVAL;
 
        size = sizeof(struct vfs_ns_cap_data);
-       ret = (int)vfs_getxattr_alloc(&init_user_ns, dentry, XATTR_NAME_CAPS,
+       ret = (int)vfs_getxattr_alloc(mnt_userns, dentry, XATTR_NAME_CAPS,
                                      &tmpbuf, size, GFP_NOFS);
        dput(dentry);
 
        root = le32_to_cpu(nscap->rootid);
        kroot = make_kuid(fs_ns, root);
 
+       /* If this is an idmapped mount shift the kuid. */
+       kroot = kuid_into_mnt(mnt_userns, kroot);
+
        /* If the root kuid maps to a valid uid in current ns, then return
         * this as a nscap. */
        mappedroot = from_kuid(current_user_ns(), kroot);
        return *effective ? ret : 0;
 }
 
-/*
+/**
+ * get_vfs_caps_from_disk - retrieve vfs caps from disk
+ *
+ * @mnt_userns:        user namespace of the mount the inode was found from
+ * @dentry:    dentry from which @inode is retrieved
+ * @cpu_caps:  vfs capabilities
+ *
  * Extract the on-exec-apply capability sets for an executable file.
+ *
+ * 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
+ * take care to map the inode according to @mnt_userns before checking
+ * permissions. On non-idmapped mounts or if permission checking is to be
+ * performed on the raw inode simply passs init_user_ns.
  */
-int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps)
+int get_vfs_caps_from_disk(struct user_namespace *mnt_userns,
+                          const struct dentry *dentry,
+                          struct cpu_vfs_cap_data *cpu_caps)
 {
        struct inode *inode = d_backing_inode(dentry);
        __u32 magic_etc;
        /* 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);
        if (!rootid_owns_currentns(rootkuid))
                return -ENODATA;
 
        if (!current_in_userns(file->f_path.mnt->mnt_sb->s_user_ns))
                return 0;
 
-       rc = get_vfs_caps_from_disk(file->f_path.dentry, &vcaps);
+       rc = get_vfs_caps_from_disk(file_mnt_user_ns(file),
+                                   file->f_path.dentry, &vcaps);
        if (rc < 0) {
                if (rc == -EINVAL)
                        printk(KERN_NOTICE "Invalid argument reading file caps for %s\n",
 
 /**
  * cap_inode_removexattr - Determine whether an xattr may be removed
- * @dentry: The inode/dentry being altered
- * @name: The name of the xattr to be changed
+ *
+ * @mnt_userns:        User namespace of the mount the inode was found from
+ * @dentry:    The inode/dentry being altered
+ * @name:      The name of the xattr to be changed
  *
  * Determine whether an xattr may be removed from an inode, returning 0 if
  * permission is granted, -ve if denied.
  *
+ * 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
+ * take care to map the inode according to @mnt_userns before checking
+ * permissions. On non-idmapped mounts or if permission checking is to be
+ * performed on the raw inode simply passs init_user_ns.
+ *
  * This is used to make sure security xattrs don't get removed by those who
  * aren't privileged to remove them.
  */
-int cap_inode_removexattr(struct dentry *dentry, const char *name)
+int cap_inode_removexattr(struct user_namespace *mnt_userns,
+                         struct dentry *dentry, const char *name)
 {
        struct user_namespace *user_ns = dentry->d_sb->s_user_ns;
 
                struct inode *inode = d_backing_inode(dentry);
                if (!inode)
                        return -EINVAL;
-               if (!capable_wrt_inode_uidgid(&init_user_ns, inode,
-                                             CAP_SETFCAP))
+               if (!capable_wrt_inode_uidgid(mnt_userns, inode, CAP_SETFCAP))
                        return -EPERM;
                return 0;
        }
 
        return call_int_hook(inode_getattr, 0, path);
 }
 
-int security_inode_setxattr(struct dentry *dentry, const char *name,
+int security_inode_setxattr(struct user_namespace *mnt_userns,
+                           struct dentry *dentry, const char *name,
                            const void *value, size_t size, int flags)
 {
        int ret;
         * SELinux and Smack integrate the cap call,
         * so assume that all LSMs supplying this call do so.
         */
-       ret = call_int_hook(inode_setxattr, 1, dentry, name, value, size,
-                               flags);
+       ret = call_int_hook(inode_setxattr, 1, mnt_userns, dentry, name, value,
+                           size, flags);
 
        if (ret == 1)
                ret = cap_inode_setxattr(dentry, name, value, size, flags);
        return call_int_hook(inode_listxattr, 0, dentry);
 }
 
-int security_inode_removexattr(struct dentry *dentry, const char *name)
+int security_inode_removexattr(struct user_namespace *mnt_userns,
+                              struct dentry *dentry, const char *name)
 {
        int ret;
 
         * SELinux and Smack integrate the cap call,
         * so assume that all LSMs supplying this call do so.
         */
-       ret = call_int_hook(inode_removexattr, 1, dentry, name);
+       ret = call_int_hook(inode_removexattr, 1, mnt_userns, dentry, name);
        if (ret == 1)
-               ret = cap_inode_removexattr(dentry, name);
+               ret = cap_inode_removexattr(mnt_userns, dentry, name);
        if (ret)
                return ret;
        ret = ima_inode_removexattr(dentry, name);
        return call_int_hook(inode_need_killpriv, 0, dentry);
 }
 
-int security_inode_killpriv(struct dentry *dentry)
+int security_inode_killpriv(struct user_namespace *mnt_userns,
+                           struct dentry *dentry)
 {
-       return call_int_hook(inode_killpriv, 0, dentry);
+       return call_int_hook(inode_killpriv, 0, mnt_userns, dentry);
 }
 
-int security_inode_getsecurity(struct inode *inode, const char *name, void **buffer, bool alloc)
+int security_inode_getsecurity(struct user_namespace *mnt_userns,
+                              struct inode *inode, const char *name,
+                              void **buffer, bool alloc)
 {
        struct security_hook_list *hp;
        int rc;
         * Only one module will provide an attribute with a given name.
         */
        hlist_for_each_entry(hp, &security_hook_heads.inode_getsecurity, list) {
-               rc = hp->hook.inode_getsecurity(inode, name, buffer, alloc);
+               rc = hp->hook.inode_getsecurity(mnt_userns, inode, name, buffer, alloc);
                if (rc != LSM_RET_DEFAULT(inode_getsecurity))
                        return rc;
        }
 
        return true;
 }
 
-static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
+static int selinux_inode_setxattr(struct user_namespace *mnt_userns,
+                                 struct dentry *dentry, const char *name,
                                  const void *value, size_t size, int flags)
 {
        struct inode *inode = d_backing_inode(dentry);
        }
 
        if (!selinux_initialized(&selinux_state))
-               return (inode_owner_or_capable(&init_user_ns, inode) ? 0 : -EPERM);
+               return (inode_owner_or_capable(mnt_userns, inode) ? 0 : -EPERM);
 
        sbsec = inode->i_sb->s_security;
        if (!(sbsec->flags & SBLABEL_MNT))
                return -EOPNOTSUPP;
 
-       if (!inode_owner_or_capable(&init_user_ns, inode))
+       if (!inode_owner_or_capable(mnt_userns, inode))
                return -EPERM;
 
        ad.type = LSM_AUDIT_DATA_DENTRY;
        return dentry_has_perm(cred, dentry, FILE__GETATTR);
 }
 
-static int selinux_inode_removexattr(struct dentry *dentry, const char *name)
+static int selinux_inode_removexattr(struct user_namespace *mnt_userns,
+                                    struct dentry *dentry, const char *name)
 {
        if (strcmp(name, XATTR_NAME_SELINUX)) {
-               int rc = cap_inode_removexattr(dentry, name);
+               int rc = cap_inode_removexattr(mnt_userns, dentry, name);
                if (rc)
                        return rc;
 
  *
  * Permission check is handled by selinux_inode_getxattr hook.
  */
-static int selinux_inode_getsecurity(struct inode *inode, const char *name, void **buffer, bool alloc)
+static int selinux_inode_getsecurity(struct user_namespace *mnt_userns,
+                                    struct inode *inode, const char *name,
+                                    void **buffer, bool alloc)
 {
        u32 size;
        int error;
 static int selinux_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
 {
        int len = 0;
-       len = selinux_inode_getsecurity(inode, XATTR_SELINUX_SUFFIX,
-                                               ctx, true);
+       len = selinux_inode_getsecurity(&init_user_ns, inode,
+                                       XATTR_SELINUX_SUFFIX, ctx, true);
        if (len < 0)
                return len;
        *ctxlen = len;
 
  *
  * Returns 0 if access is permitted, an error code otherwise
  */
-static int smack_inode_setxattr(struct dentry *dentry, const char *name,
+static int smack_inode_setxattr(struct user_namespace *mnt_userns,
+                               struct dentry *dentry, const char *name,
                                const void *value, size_t size, int flags)
 {
        struct smk_audit_info ad;
  *
  * Returns 0 if access is permitted, an error code otherwise
  */
-static int smack_inode_removexattr(struct dentry *dentry, const char *name)
+static int smack_inode_removexattr(struct user_namespace *mnt_userns,
+                                  struct dentry *dentry, const char *name)
 {
        struct inode_smack *isp;
        struct smk_audit_info ad;
                if (!smack_privileged(CAP_MAC_ADMIN))
                        rc = -EPERM;
        } else
-               rc = cap_inode_removexattr(dentry, name);
+               rc = cap_inode_removexattr(mnt_userns, dentry, name);
 
        if (rc != 0)
                return rc;
  *
  * Returns the size of the attribute or an error code
  */
-static int smack_inode_getsecurity(struct inode *inode,
-                                  const char *name, void **buffer,
-                                  bool alloc)
+static int smack_inode_getsecurity(struct user_namespace *mnt_userns,
+                                  struct inode *inode, const char *name,
+                                  void **buffer, bool alloc)
 {
        struct socket_smack *ssp;
        struct socket *sock;