diff options
Diffstat (limited to 'security/commoncap.c')
| -rw-r--r-- | security/commoncap.c | 15 | 
1 files changed, 9 insertions, 6 deletions
| diff --git a/security/commoncap.c b/security/commoncap.c index 3f810d37b71b..5fc8986c3c77 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -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 @@ -418,7 +419,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 +489,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 +499,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 +510,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 +556,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 +702,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; |