mirror of https://github.com/torvalds/linux.git
fs: use low-level mapping helpers
In a few places the vfs needs to interact with bare k{g,u}ids directly
instead of struct inode. These are just a few. In previous patches we
introduced low-level mapping helpers that are able to support
filesystems mounted an idmapping. This patch simply converts the places
to use these new helpers.
Link: https://lore.kernel.org/r/20211123114227.3124056-7-brauner@kernel.org (v1)
Link: https://lore.kernel.org/r/20211130121032.3753852-7-brauner@kernel.org (v2)
Link: https://lore.kernel.org/r/20211203111707.3901969-7-brauner@kernel.org
Cc: Seth Forshee <sforshee@digitalocean.com>
Cc: Amir Goldstein <amir73il@gmail.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Al Viro <viro@zeniv.linux.org.uk>
CC: linux-fsdevel@vger.kernel.org
Reviewed-by: Seth Forshee <sforshee@digitalocean.com>
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
This commit is contained in:
parent
8cc5c54de4
commit
4472071331
|
|
@ -275,14 +275,7 @@ static int sid_to_id(struct user_namespace *user_ns,
|
||||||
uid_t id;
|
uid_t id;
|
||||||
|
|
||||||
id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
|
id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
|
||||||
/*
|
uid = mapped_kuid_user(user_ns, &init_user_ns, KUIDT_INIT(id));
|
||||||
* Translate raw sid into kuid in the server's user
|
|
||||||
* namespace.
|
|
||||||
*/
|
|
||||||
uid = make_kuid(&init_user_ns, id);
|
|
||||||
|
|
||||||
/* If this is an idmapped mount, apply the idmapping. */
|
|
||||||
uid = kuid_from_mnt(user_ns, uid);
|
|
||||||
if (uid_valid(uid)) {
|
if (uid_valid(uid)) {
|
||||||
fattr->cf_uid = uid;
|
fattr->cf_uid = uid;
|
||||||
rc = 0;
|
rc = 0;
|
||||||
|
|
@ -292,14 +285,7 @@ static int sid_to_id(struct user_namespace *user_ns,
|
||||||
gid_t id;
|
gid_t id;
|
||||||
|
|
||||||
id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
|
id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
|
||||||
/*
|
gid = mapped_kgid_user(user_ns, &init_user_ns, KGIDT_INIT(id));
|
||||||
* Translate raw sid into kgid in the server's user
|
|
||||||
* namespace.
|
|
||||||
*/
|
|
||||||
gid = make_kgid(&init_user_ns, id);
|
|
||||||
|
|
||||||
/* If this is an idmapped mount, apply the idmapping. */
|
|
||||||
gid = kgid_from_mnt(user_ns, gid);
|
|
||||||
if (gid_valid(gid)) {
|
if (gid_valid(gid)) {
|
||||||
fattr->cf_gid = gid;
|
fattr->cf_gid = gid;
|
||||||
rc = 0;
|
rc = 0;
|
||||||
|
|
|
||||||
|
|
@ -217,7 +217,7 @@ static inline uid_t posix_acl_uid_translate(struct user_namespace *mnt_userns,
|
||||||
kuid_t kuid;
|
kuid_t kuid;
|
||||||
|
|
||||||
/* If this is an idmapped mount, apply the idmapping. */
|
/* If this is an idmapped mount, apply the idmapping. */
|
||||||
kuid = kuid_into_mnt(mnt_userns, pace->e_uid);
|
kuid = mapped_kuid_fs(mnt_userns, &init_user_ns, pace->e_uid);
|
||||||
|
|
||||||
/* Translate the kuid into a userspace id ksmbd would see. */
|
/* Translate the kuid into a userspace id ksmbd would see. */
|
||||||
return from_kuid(&init_user_ns, kuid);
|
return from_kuid(&init_user_ns, kuid);
|
||||||
|
|
@ -229,7 +229,7 @@ static inline gid_t posix_acl_gid_translate(struct user_namespace *mnt_userns,
|
||||||
kgid_t kgid;
|
kgid_t kgid;
|
||||||
|
|
||||||
/* If this is an idmapped mount, apply the idmapping. */
|
/* If this is an idmapped mount, apply the idmapping. */
|
||||||
kgid = kgid_into_mnt(mnt_userns, pace->e_gid);
|
kgid = mapped_kgid_fs(mnt_userns, &init_user_ns, pace->e_gid);
|
||||||
|
|
||||||
/* Translate the kgid into a userspace id ksmbd would see. */
|
/* Translate the kgid into a userspace id ksmbd would see. */
|
||||||
return from_kgid(&init_user_ns, kgid);
|
return from_kgid(&init_user_ns, kgid);
|
||||||
|
|
|
||||||
|
|
@ -653,8 +653,8 @@ int chown_common(const struct path *path, uid_t user, gid_t group)
|
||||||
gid = make_kgid(current_user_ns(), group);
|
gid = make_kgid(current_user_ns(), group);
|
||||||
|
|
||||||
mnt_userns = mnt_user_ns(path->mnt);
|
mnt_userns = mnt_user_ns(path->mnt);
|
||||||
uid = kuid_from_mnt(mnt_userns, uid);
|
uid = mapped_kuid_user(mnt_userns, &init_user_ns, uid);
|
||||||
gid = kgid_from_mnt(mnt_userns, gid);
|
gid = mapped_kgid_user(mnt_userns, &init_user_ns, gid);
|
||||||
|
|
||||||
retry_deleg:
|
retry_deleg:
|
||||||
newattrs.ia_valid = ATTR_CTIME;
|
newattrs.ia_valid = ATTR_CTIME;
|
||||||
|
|
|
||||||
|
|
@ -375,7 +375,9 @@ posix_acl_permission(struct user_namespace *mnt_userns, struct inode *inode,
|
||||||
goto check_perm;
|
goto check_perm;
|
||||||
break;
|
break;
|
||||||
case ACL_USER:
|
case ACL_USER:
|
||||||
uid = kuid_into_mnt(mnt_userns, pa->e_uid);
|
uid = mapped_kuid_fs(mnt_userns,
|
||||||
|
&init_user_ns,
|
||||||
|
pa->e_uid);
|
||||||
if (uid_eq(uid, current_fsuid()))
|
if (uid_eq(uid, current_fsuid()))
|
||||||
goto mask;
|
goto mask;
|
||||||
break;
|
break;
|
||||||
|
|
@ -388,7 +390,9 @@ posix_acl_permission(struct user_namespace *mnt_userns, struct inode *inode,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACL_GROUP:
|
case ACL_GROUP:
|
||||||
gid = kgid_into_mnt(mnt_userns, pa->e_gid);
|
gid = mapped_kgid_fs(mnt_userns,
|
||||||
|
&init_user_ns,
|
||||||
|
pa->e_gid);
|
||||||
if (in_group_p(gid)) {
|
if (in_group_p(gid)) {
|
||||||
found = 1;
|
found = 1;
|
||||||
if ((pa->e_perm & want) == want)
|
if ((pa->e_perm & want) == want)
|
||||||
|
|
@ -735,17 +739,17 @@ static void posix_acl_fix_xattr_userns(
|
||||||
case ACL_USER:
|
case ACL_USER:
|
||||||
uid = make_kuid(from, le32_to_cpu(entry->e_id));
|
uid = make_kuid(from, le32_to_cpu(entry->e_id));
|
||||||
if (from_user)
|
if (from_user)
|
||||||
uid = kuid_from_mnt(mnt_userns, uid);
|
uid = mapped_kuid_user(mnt_userns, &init_user_ns, uid);
|
||||||
else
|
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));
|
entry->e_id = cpu_to_le32(from_kuid(to, uid));
|
||||||
break;
|
break;
|
||||||
case ACL_GROUP:
|
case ACL_GROUP:
|
||||||
gid = make_kgid(from, le32_to_cpu(entry->e_id));
|
gid = make_kgid(from, le32_to_cpu(entry->e_id));
|
||||||
if (from_user)
|
if (from_user)
|
||||||
gid = kgid_from_mnt(mnt_userns, gid);
|
gid = mapped_kgid_user(mnt_userns, &init_user_ns, gid);
|
||||||
else
|
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));
|
entry->e_id = cpu_to_le32(from_kgid(to, gid));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -419,7 +419,7 @@ int cap_inode_getsecurity(struct user_namespace *mnt_userns,
|
||||||
kroot = make_kuid(fs_ns, root);
|
kroot = make_kuid(fs_ns, root);
|
||||||
|
|
||||||
/* If this is an idmapped mount shift the kuid. */
|
/* If this is an idmapped mount shift the kuid. */
|
||||||
kroot = kuid_into_mnt(mnt_userns, kroot);
|
kroot = mapped_kuid_fs(mnt_userns, &init_user_ns, kroot);
|
||||||
|
|
||||||
/* If the root kuid maps to a valid uid in current ns, then return
|
/* If the root kuid maps to a valid uid in current ns, then return
|
||||||
* this as a nscap. */
|
* this as a nscap. */
|
||||||
|
|
@ -489,6 +489,7 @@ int cap_inode_getsecurity(struct user_namespace *mnt_userns,
|
||||||
* @size: size of @ivalue
|
* @size: size of @ivalue
|
||||||
* @task_ns: user namespace of the caller
|
* @task_ns: user namespace of the caller
|
||||||
* @mnt_userns: user namespace of the mount the inode was found from
|
* @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
|
* 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
|
* the vfsmount must be passed through @mnt_userns. This function will then
|
||||||
|
|
@ -498,7 +499,8 @@ int cap_inode_getsecurity(struct user_namespace *mnt_userns,
|
||||||
*/
|
*/
|
||||||
static kuid_t rootid_from_xattr(const void *value, size_t size,
|
static kuid_t rootid_from_xattr(const void *value, size_t size,
|
||||||
struct user_namespace *task_ns,
|
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;
|
const struct vfs_ns_cap_data *nscap = value;
|
||||||
kuid_t rootkid;
|
kuid_t rootkid;
|
||||||
|
|
@ -508,7 +510,7 @@ static kuid_t rootid_from_xattr(const void *value, size_t size,
|
||||||
rootid = le32_to_cpu(nscap->rootid);
|
rootid = le32_to_cpu(nscap->rootid);
|
||||||
|
|
||||||
rootkid = make_kuid(task_ns, 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)
|
static bool validheader(size_t size, const struct vfs_cap_data *cap)
|
||||||
|
|
@ -559,7 +561,8 @@ int cap_convert_nscap(struct user_namespace *mnt_userns, struct dentry *dentry,
|
||||||
/* user is privileged, just write the v2 */
|
/* user is privileged, just write the v2 */
|
||||||
return size;
|
return size;
|
||||||
|
|
||||||
rootid = rootid_from_xattr(*ivalue, size, task_ns, mnt_userns);
|
rootid = rootid_from_xattr(*ivalue, size, task_ns, mnt_userns,
|
||||||
|
&init_user_ns);
|
||||||
if (!uid_valid(rootid))
|
if (!uid_valid(rootid))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
|
@ -700,7 +703,7 @@ int get_vfs_caps_from_disk(struct user_namespace *mnt_userns,
|
||||||
/* Limit the caps to the mounter of the filesystem
|
/* Limit the caps to the mounter of the filesystem
|
||||||
* or the more limited uid specified in the xattr.
|
* or the more limited uid specified in the xattr.
|
||||||
*/
|
*/
|
||||||
rootkuid = kuid_into_mnt(mnt_userns, rootkuid);
|
rootkuid = mapped_kuid_fs(mnt_userns, &init_user_ns, rootkuid);
|
||||||
if (!rootid_owns_currentns(rootkuid))
|
if (!rootid_owns_currentns(rootkuid))
|
||||||
return -ENODATA;
|
return -ENODATA;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue