2021-12-03 11:16:59 +00:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
|
|
|
#ifndef _LINUX_MNT_IDMAPPING_H
|
|
|
|
#define _LINUX_MNT_IDMAPPING_H
|
|
|
|
|
|
|
|
#include <linux/types.h>
|
|
|
|
#include <linux/uidgid.h>
|
|
|
|
|
|
|
|
struct user_namespace;
|
fs: account for filesystem mappings
Currently we only support idmapped mounts for filesystems mounted
without an idmapping. This was a conscious decision mentioned in
multiple places (cf. e.g. [1]).
As explained at length in [3] it is perfectly fine to extend support for
idmapped mounts to filesystem's mounted with an idmapping should the
need arise. The need has been there for some time now. Various container
projects in userspace need this to run unprivileged and nested
unprivileged containers (cf. [2]).
Before we can port any filesystem that is mountable with an idmapping to
support idmapped mounts we need to first extend the mapping helpers to
account for the filesystem's idmapping. This again, is explained at
length in our documentation at [3] but I'll give an overview here again.
Currently, the low-level mapping helpers implement the remapping
algorithms described in [3] in a simplified manner. Because we could
rely on the fact that all filesystems supporting idmapped mounts are
mounted without an idmapping the translation step from or into the
filesystem idmapping could be skipped.
In order to support idmapped mounts of filesystem's mountable with an
idmapping the translation step we were able to skip before cannot be
skipped anymore. A filesystem mounted with an idmapping is very likely
to not use an identity mapping and will instead use a non-identity
mapping. So the translation step from or into the filesystem's idmapping
in the remapping algorithm cannot be skipped for such filesystems. More
details with examples can be found in [3].
This patch adds a few new and prepares some already existing low-level
mapping helpers to perform the full translation algorithm explained in
[3]. The low-level helpers can be written in a way that they only
perform the additional translation step when the filesystem is indeed
mounted with an idmapping.
If the low-level helpers detect that they are not dealing with an
idmapped mount they can simply return the relevant k{g,u}id unchanged;
no remapping needs to be performed at all. The no_idmapping() helper
detects whether the shortcut can be used.
If the low-level helpers detected that they are dealing with an idmapped
mount but the underlying filesystem is mounted without an idmapping we
can rely on the previous shorcut and can continue to skip the
translation step from or into the filesystem's idmapping.
These checks guarantee that only the minimal amount of work is
performed. As before, if idmapped mounts aren't used the low-level
helpers are idempotent and no work is performed at all.
This patch adds the helpers mapped_k{g,u}id_fs() and
mapped_k{g,u}id_user(). Following patches will port all places to
replace the old k{g,u}id_into_mnt() and k{g,u}id_from_mnt() with these
two new helpers. After the conversion is done k{g,u}id_into_mnt() and
k{g,u}id_from_mnt() will be removed. This also concludes the renaming of
the mapping helpers we started in [4]. Now, all mapping helpers will
started with the "mapped_" prefix making everything nice and consistent.
The mapped_k{g,u}id_fs() helpers replace the k{g,u}id_into_mnt()
helpers. They are to be used when k{g,u}ids are to be mapped from the
vfs, e.g. from from struct inode's i_{g,u}id. Conversely, the
mapped_k{g,u}id_user() helpers replace the k{g,u}id_from_mnt() helpers.
They are to be used when k{g,u}ids are to be written to disk, e.g. when
entering from a system call to change ownership of a file.
This patch only introduces the helpers. It doesn't yet convert the
relevant places to account for filesystem mounted with an idmapping.
[1]: commit 2ca4dcc4909d ("fs/mount_setattr: tighten permission checks")
[2]: https://github.com/containers/podman/issues/10374
[3]: Documentations/filesystems/idmappings.rst
[4]: commit a65e58e791a1 ("fs: document and rename fsid helpers")
Link: https://lore.kernel.org/r/20211123114227.3124056-5-brauner@kernel.org (v1)
Link: https://lore.kernel.org/r/20211130121032.3753852-5-brauner@kernel.org (v2)
Link: https://lore.kernel.org/r/20211203111707.3901969-5-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>
2021-12-03 11:17:01 +00:00
|
|
|
/*
|
|
|
|
* Carries the initial idmapping of 0:0:4294967295 which is an identity
|
|
|
|
* mapping. This means that {g,u}id 0 is mapped to {g,u}id 0, {g,u}id 1 is
|
|
|
|
* mapped to {g,u}id 1, [...], {g,u}id 1000 to {g,u}id 1000, [...].
|
|
|
|
*/
|
2021-12-03 11:16:59 +00:00
|
|
|
extern struct user_namespace init_user_ns;
|
|
|
|
|
mnt_idmapping: add vfs{g,u}id_t
Introduces new vfs{g,u}id_t types. Similar to k{g,u}id_t the new types
are just simple wrapper structs around regular {g,u}id_t types.
They allows to establish a type safety boundary between {g,u}ids on
idmapped mounts and {g,u}ids as they are represented in filesystems
themselves.
A vfs{g,u}id_t is always created from a k{g,u}id_t, never directly from
a {g,u}id_t as idmapped mounts remap a given {g,u}id according to the
mount's idmapping. This is expressed in the VFS{G,U}IDT_INIT() macros.
A vfs{g,u}id_t may be used as a k{g,u}id_t via AS_K{G,U}IDT(). This
often happens when we need to check whether a {g,u}id mapped according
to an idmapped mount is identical to a given k{g,u}id_t. For an example,
see vfsgid_in_group_p() which determines whether the value of vfsgid_t
matches the value of any of the caller's groups. Similar logic is
expressed in the k{g,u}id_eq_vfs{g,u}id().
The from_vfs{g,u}id() helpers map a given vfs{g,u}id_t from the mount's
idmapping into the filesystem idmapping. They make it possible to update
a filesystem object such as inode->i_{g,u}id with the correct value.
This makes it harder to accidently write a wrong {g,u}id anwywhere. The
vfs{g,u}id_has_fsmapping() helpers check whether a given vfs{g,u}id_t
can be mapped into the filesystem idmapping.
All new helpers are nops on non-idmapped mounts.
I've done work on this roughly 7 months ago but dropped it to focus on
the testsuite. Linus brought this up independently just last week and
it's time to move this along (see [1]).
[1]: https://lore.kernel.org/lkml/CAHk-=win6+ahs1EwLkcq8apqLi_1wXFWbrPf340zYEhObpz4jA@mail.gmail.com
Link: https://lore.kernel.org/r/20220621141454.2914719-2-brauner@kernel.org
Cc: Seth Forshee <sforshee@digitalocean.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Aleksa Sarai <cyphar@cyphar.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
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 (Microsoft) <brauner@kernel.org>
2022-06-21 14:14:47 +00:00
|
|
|
typedef struct {
|
|
|
|
uid_t val;
|
|
|
|
} vfsuid_t;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
gid_t val;
|
|
|
|
} vfsgid_t;
|
|
|
|
|
|
|
|
#ifdef CONFIG_MULTIUSER
|
|
|
|
static inline uid_t __vfsuid_val(vfsuid_t uid)
|
|
|
|
{
|
|
|
|
return uid.val;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline gid_t __vfsgid_val(vfsgid_t gid)
|
|
|
|
{
|
|
|
|
return gid.val;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
static inline uid_t __vfsuid_val(vfsuid_t uid)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline gid_t __vfsgid_val(vfsgid_t gid)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static inline bool vfsuid_valid(vfsuid_t uid)
|
|
|
|
{
|
|
|
|
return __vfsuid_val(uid) != (uid_t)-1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline bool vfsgid_valid(vfsgid_t gid)
|
|
|
|
{
|
|
|
|
return __vfsgid_val(gid) != (gid_t)-1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline bool vfsuid_eq(vfsuid_t left, vfsuid_t right)
|
|
|
|
{
|
|
|
|
return __vfsuid_val(left) == __vfsuid_val(right);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline bool vfsgid_eq(vfsgid_t left, vfsgid_t right)
|
|
|
|
{
|
|
|
|
return __vfsgid_val(left) == __vfsgid_val(right);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* vfsuid_eq_kuid - check whether kuid and vfsuid have the same value
|
|
|
|
* @kuid: the kuid to compare
|
|
|
|
* @vfsuid: the vfsuid to compare
|
|
|
|
*
|
|
|
|
* Check whether @kuid and @vfsuid have the same values.
|
|
|
|
*
|
|
|
|
* Return: true if @kuid and @vfsuid have the same value, false if not.
|
|
|
|
*/
|
|
|
|
static inline bool vfsuid_eq_kuid(vfsuid_t vfsuid, kuid_t kuid)
|
|
|
|
{
|
|
|
|
return __vfsuid_val(vfsuid) == __kuid_val(kuid);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* vfsgid_eq_kgid - check whether kgid and vfsgid have the same value
|
|
|
|
* @kgid: the kgid to compare
|
|
|
|
* @vfsgid: the vfsgid to compare
|
|
|
|
*
|
|
|
|
* Check whether @kgid and @vfsgid have the same values.
|
|
|
|
*
|
|
|
|
* Return: true if @kgid and @vfsgid have the same value, false if not.
|
|
|
|
*/
|
|
|
|
static inline bool vfsgid_eq_kgid(kgid_t kgid, vfsgid_t vfsgid)
|
|
|
|
{
|
|
|
|
return __vfsgid_val(vfsgid) == __kgid_val(kgid);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* vfs{g,u}ids are created from k{g,u}ids.
|
|
|
|
* We don't allow them to be created from regular {u,g}id.
|
|
|
|
*/
|
|
|
|
#define VFSUIDT_INIT(val) (vfsuid_t){ __kuid_val(val) }
|
|
|
|
#define VFSGIDT_INIT(val) (vfsgid_t){ __kgid_val(val) }
|
|
|
|
|
|
|
|
#define INVALID_VFSUID VFSUIDT_INIT(INVALID_UID)
|
|
|
|
#define INVALID_VFSGID VFSGIDT_INIT(INVALID_GID)
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Allow a vfs{g,u}id to be used as a k{g,u}id where we want to compare
|
|
|
|
* whether the mapped value is identical to value of a k{g,u}id.
|
|
|
|
*/
|
|
|
|
#define AS_KUIDT(val) (kuid_t){ __vfsuid_val(val) }
|
|
|
|
#define AS_KGIDT(val) (kgid_t){ __vfsgid_val(val) }
|
|
|
|
|
|
|
|
#ifdef CONFIG_MULTIUSER
|
|
|
|
/**
|
|
|
|
* vfsgid_in_group_p() - check whether a vfsuid matches the caller's groups
|
|
|
|
* @vfsgid: the mnt gid to match
|
|
|
|
*
|
|
|
|
* This function can be used to determine whether @vfsuid matches any of the
|
|
|
|
* caller's groups.
|
|
|
|
*
|
|
|
|
* Return: 1 if vfsuid matches caller's groups, 0 if not.
|
|
|
|
*/
|
|
|
|
static inline int vfsgid_in_group_p(vfsgid_t vfsgid)
|
|
|
|
{
|
|
|
|
return in_group_p(AS_KGIDT(vfsgid));
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
static inline int vfsgid_in_group_p(vfsgid_t vfsgid)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
fs: account for filesystem mappings
Currently we only support idmapped mounts for filesystems mounted
without an idmapping. This was a conscious decision mentioned in
multiple places (cf. e.g. [1]).
As explained at length in [3] it is perfectly fine to extend support for
idmapped mounts to filesystem's mounted with an idmapping should the
need arise. The need has been there for some time now. Various container
projects in userspace need this to run unprivileged and nested
unprivileged containers (cf. [2]).
Before we can port any filesystem that is mountable with an idmapping to
support idmapped mounts we need to first extend the mapping helpers to
account for the filesystem's idmapping. This again, is explained at
length in our documentation at [3] but I'll give an overview here again.
Currently, the low-level mapping helpers implement the remapping
algorithms described in [3] in a simplified manner. Because we could
rely on the fact that all filesystems supporting idmapped mounts are
mounted without an idmapping the translation step from or into the
filesystem idmapping could be skipped.
In order to support idmapped mounts of filesystem's mountable with an
idmapping the translation step we were able to skip before cannot be
skipped anymore. A filesystem mounted with an idmapping is very likely
to not use an identity mapping and will instead use a non-identity
mapping. So the translation step from or into the filesystem's idmapping
in the remapping algorithm cannot be skipped for such filesystems. More
details with examples can be found in [3].
This patch adds a few new and prepares some already existing low-level
mapping helpers to perform the full translation algorithm explained in
[3]. The low-level helpers can be written in a way that they only
perform the additional translation step when the filesystem is indeed
mounted with an idmapping.
If the low-level helpers detect that they are not dealing with an
idmapped mount they can simply return the relevant k{g,u}id unchanged;
no remapping needs to be performed at all. The no_idmapping() helper
detects whether the shortcut can be used.
If the low-level helpers detected that they are dealing with an idmapped
mount but the underlying filesystem is mounted without an idmapping we
can rely on the previous shorcut and can continue to skip the
translation step from or into the filesystem's idmapping.
These checks guarantee that only the minimal amount of work is
performed. As before, if idmapped mounts aren't used the low-level
helpers are idempotent and no work is performed at all.
This patch adds the helpers mapped_k{g,u}id_fs() and
mapped_k{g,u}id_user(). Following patches will port all places to
replace the old k{g,u}id_into_mnt() and k{g,u}id_from_mnt() with these
two new helpers. After the conversion is done k{g,u}id_into_mnt() and
k{g,u}id_from_mnt() will be removed. This also concludes the renaming of
the mapping helpers we started in [4]. Now, all mapping helpers will
started with the "mapped_" prefix making everything nice and consistent.
The mapped_k{g,u}id_fs() helpers replace the k{g,u}id_into_mnt()
helpers. They are to be used when k{g,u}ids are to be mapped from the
vfs, e.g. from from struct inode's i_{g,u}id. Conversely, the
mapped_k{g,u}id_user() helpers replace the k{g,u}id_from_mnt() helpers.
They are to be used when k{g,u}ids are to be written to disk, e.g. when
entering from a system call to change ownership of a file.
This patch only introduces the helpers. It doesn't yet convert the
relevant places to account for filesystem mounted with an idmapping.
[1]: commit 2ca4dcc4909d ("fs/mount_setattr: tighten permission checks")
[2]: https://github.com/containers/podman/issues/10374
[3]: Documentations/filesystems/idmappings.rst
[4]: commit a65e58e791a1 ("fs: document and rename fsid helpers")
Link: https://lore.kernel.org/r/20211123114227.3124056-5-brauner@kernel.org (v1)
Link: https://lore.kernel.org/r/20211130121032.3753852-5-brauner@kernel.org (v2)
Link: https://lore.kernel.org/r/20211203111707.3901969-5-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>
2021-12-03 11:17:01 +00:00
|
|
|
/**
|
|
|
|
* initial_idmapping - check whether this is the initial mapping
|
|
|
|
* @ns: idmapping to check
|
|
|
|
*
|
|
|
|
* Check whether this is the initial mapping, mapping 0 to 0, 1 to 1,
|
|
|
|
* [...], 1000 to 1000 [...].
|
|
|
|
*
|
|
|
|
* Return: true if this is the initial mapping, false if not.
|
|
|
|
*/
|
|
|
|
static inline bool initial_idmapping(const struct user_namespace *ns)
|
|
|
|
{
|
|
|
|
return ns == &init_user_ns;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* no_idmapping - check whether we can skip remapping a kuid/gid
|
|
|
|
* @mnt_userns: the mount's idmapping
|
|
|
|
* @fs_userns: the filesystem's idmapping
|
|
|
|
*
|
|
|
|
* This function can be used to check whether a remapping between two
|
|
|
|
* idmappings is required.
|
|
|
|
* An idmapped mount is a mount that has an idmapping attached to it that
|
|
|
|
* is different from the filsystem's idmapping and the initial idmapping.
|
|
|
|
* If the initial mapping is used or the idmapping of the mount and the
|
|
|
|
* filesystem are identical no remapping is required.
|
|
|
|
*
|
|
|
|
* Return: true if remapping can be skipped, false if not.
|
|
|
|
*/
|
|
|
|
static inline bool no_idmapping(const struct user_namespace *mnt_userns,
|
|
|
|
const struct user_namespace *fs_userns)
|
|
|
|
{
|
|
|
|
return initial_idmapping(mnt_userns) || mnt_userns == fs_userns;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* mapped_kuid_fs - map a filesystem kuid into a mnt_userns
|
|
|
|
* @mnt_userns: the mount's idmapping
|
|
|
|
* @fs_userns: the filesystem's idmapping
|
|
|
|
* @kuid : kuid to be mapped
|
|
|
|
*
|
|
|
|
* Take a @kuid and remap it from @fs_userns into @mnt_userns. Use this
|
|
|
|
* function when preparing a @kuid to be reported to userspace.
|
|
|
|
*
|
|
|
|
* If no_idmapping() determines that this is not an idmapped mount we can
|
|
|
|
* simply return @kuid unchanged.
|
|
|
|
* If initial_idmapping() tells us that the filesystem is not mounted with an
|
|
|
|
* idmapping we know the value of @kuid won't change when calling
|
|
|
|
* from_kuid() so we can simply retrieve the value via __kuid_val()
|
|
|
|
* directly.
|
|
|
|
*
|
|
|
|
* Return: @kuid mapped according to @mnt_userns.
|
|
|
|
* If @kuid has no mapping in either @mnt_userns or @fs_userns INVALID_UID is
|
|
|
|
* returned.
|
|
|
|
*/
|
mnt_idmapping: add vfs{g,u}id_t
Introduces new vfs{g,u}id_t types. Similar to k{g,u}id_t the new types
are just simple wrapper structs around regular {g,u}id_t types.
They allows to establish a type safety boundary between {g,u}ids on
idmapped mounts and {g,u}ids as they are represented in filesystems
themselves.
A vfs{g,u}id_t is always created from a k{g,u}id_t, never directly from
a {g,u}id_t as idmapped mounts remap a given {g,u}id according to the
mount's idmapping. This is expressed in the VFS{G,U}IDT_INIT() macros.
A vfs{g,u}id_t may be used as a k{g,u}id_t via AS_K{G,U}IDT(). This
often happens when we need to check whether a {g,u}id mapped according
to an idmapped mount is identical to a given k{g,u}id_t. For an example,
see vfsgid_in_group_p() which determines whether the value of vfsgid_t
matches the value of any of the caller's groups. Similar logic is
expressed in the k{g,u}id_eq_vfs{g,u}id().
The from_vfs{g,u}id() helpers map a given vfs{g,u}id_t from the mount's
idmapping into the filesystem idmapping. They make it possible to update
a filesystem object such as inode->i_{g,u}id with the correct value.
This makes it harder to accidently write a wrong {g,u}id anwywhere. The
vfs{g,u}id_has_fsmapping() helpers check whether a given vfs{g,u}id_t
can be mapped into the filesystem idmapping.
All new helpers are nops on non-idmapped mounts.
I've done work on this roughly 7 months ago but dropped it to focus on
the testsuite. Linus brought this up independently just last week and
it's time to move this along (see [1]).
[1]: https://lore.kernel.org/lkml/CAHk-=win6+ahs1EwLkcq8apqLi_1wXFWbrPf340zYEhObpz4jA@mail.gmail.com
Link: https://lore.kernel.org/r/20220621141454.2914719-2-brauner@kernel.org
Cc: Seth Forshee <sforshee@digitalocean.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Aleksa Sarai <cyphar@cyphar.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
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 (Microsoft) <brauner@kernel.org>
2022-06-21 14:14:47 +00:00
|
|
|
|
|
|
|
static inline vfsuid_t make_vfsuid(struct user_namespace *mnt_userns,
|
|
|
|
struct user_namespace *fs_userns,
|
|
|
|
kuid_t kuid)
|
fs: account for filesystem mappings
Currently we only support idmapped mounts for filesystems mounted
without an idmapping. This was a conscious decision mentioned in
multiple places (cf. e.g. [1]).
As explained at length in [3] it is perfectly fine to extend support for
idmapped mounts to filesystem's mounted with an idmapping should the
need arise. The need has been there for some time now. Various container
projects in userspace need this to run unprivileged and nested
unprivileged containers (cf. [2]).
Before we can port any filesystem that is mountable with an idmapping to
support idmapped mounts we need to first extend the mapping helpers to
account for the filesystem's idmapping. This again, is explained at
length in our documentation at [3] but I'll give an overview here again.
Currently, the low-level mapping helpers implement the remapping
algorithms described in [3] in a simplified manner. Because we could
rely on the fact that all filesystems supporting idmapped mounts are
mounted without an idmapping the translation step from or into the
filesystem idmapping could be skipped.
In order to support idmapped mounts of filesystem's mountable with an
idmapping the translation step we were able to skip before cannot be
skipped anymore. A filesystem mounted with an idmapping is very likely
to not use an identity mapping and will instead use a non-identity
mapping. So the translation step from or into the filesystem's idmapping
in the remapping algorithm cannot be skipped for such filesystems. More
details with examples can be found in [3].
This patch adds a few new and prepares some already existing low-level
mapping helpers to perform the full translation algorithm explained in
[3]. The low-level helpers can be written in a way that they only
perform the additional translation step when the filesystem is indeed
mounted with an idmapping.
If the low-level helpers detect that they are not dealing with an
idmapped mount they can simply return the relevant k{g,u}id unchanged;
no remapping needs to be performed at all. The no_idmapping() helper
detects whether the shortcut can be used.
If the low-level helpers detected that they are dealing with an idmapped
mount but the underlying filesystem is mounted without an idmapping we
can rely on the previous shorcut and can continue to skip the
translation step from or into the filesystem's idmapping.
These checks guarantee that only the minimal amount of work is
performed. As before, if idmapped mounts aren't used the low-level
helpers are idempotent and no work is performed at all.
This patch adds the helpers mapped_k{g,u}id_fs() and
mapped_k{g,u}id_user(). Following patches will port all places to
replace the old k{g,u}id_into_mnt() and k{g,u}id_from_mnt() with these
two new helpers. After the conversion is done k{g,u}id_into_mnt() and
k{g,u}id_from_mnt() will be removed. This also concludes the renaming of
the mapping helpers we started in [4]. Now, all mapping helpers will
started with the "mapped_" prefix making everything nice and consistent.
The mapped_k{g,u}id_fs() helpers replace the k{g,u}id_into_mnt()
helpers. They are to be used when k{g,u}ids are to be mapped from the
vfs, e.g. from from struct inode's i_{g,u}id. Conversely, the
mapped_k{g,u}id_user() helpers replace the k{g,u}id_from_mnt() helpers.
They are to be used when k{g,u}ids are to be written to disk, e.g. when
entering from a system call to change ownership of a file.
This patch only introduces the helpers. It doesn't yet convert the
relevant places to account for filesystem mounted with an idmapping.
[1]: commit 2ca4dcc4909d ("fs/mount_setattr: tighten permission checks")
[2]: https://github.com/containers/podman/issues/10374
[3]: Documentations/filesystems/idmappings.rst
[4]: commit a65e58e791a1 ("fs: document and rename fsid helpers")
Link: https://lore.kernel.org/r/20211123114227.3124056-5-brauner@kernel.org (v1)
Link: https://lore.kernel.org/r/20211130121032.3753852-5-brauner@kernel.org (v2)
Link: https://lore.kernel.org/r/20211203111707.3901969-5-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>
2021-12-03 11:17:01 +00:00
|
|
|
{
|
|
|
|
uid_t uid;
|
|
|
|
|
|
|
|
if (no_idmapping(mnt_userns, fs_userns))
|
mnt_idmapping: add vfs{g,u}id_t
Introduces new vfs{g,u}id_t types. Similar to k{g,u}id_t the new types
are just simple wrapper structs around regular {g,u}id_t types.
They allows to establish a type safety boundary between {g,u}ids on
idmapped mounts and {g,u}ids as they are represented in filesystems
themselves.
A vfs{g,u}id_t is always created from a k{g,u}id_t, never directly from
a {g,u}id_t as idmapped mounts remap a given {g,u}id according to the
mount's idmapping. This is expressed in the VFS{G,U}IDT_INIT() macros.
A vfs{g,u}id_t may be used as a k{g,u}id_t via AS_K{G,U}IDT(). This
often happens when we need to check whether a {g,u}id mapped according
to an idmapped mount is identical to a given k{g,u}id_t. For an example,
see vfsgid_in_group_p() which determines whether the value of vfsgid_t
matches the value of any of the caller's groups. Similar logic is
expressed in the k{g,u}id_eq_vfs{g,u}id().
The from_vfs{g,u}id() helpers map a given vfs{g,u}id_t from the mount's
idmapping into the filesystem idmapping. They make it possible to update
a filesystem object such as inode->i_{g,u}id with the correct value.
This makes it harder to accidently write a wrong {g,u}id anwywhere. The
vfs{g,u}id_has_fsmapping() helpers check whether a given vfs{g,u}id_t
can be mapped into the filesystem idmapping.
All new helpers are nops on non-idmapped mounts.
I've done work on this roughly 7 months ago but dropped it to focus on
the testsuite. Linus brought this up independently just last week and
it's time to move this along (see [1]).
[1]: https://lore.kernel.org/lkml/CAHk-=win6+ahs1EwLkcq8apqLi_1wXFWbrPf340zYEhObpz4jA@mail.gmail.com
Link: https://lore.kernel.org/r/20220621141454.2914719-2-brauner@kernel.org
Cc: Seth Forshee <sforshee@digitalocean.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Aleksa Sarai <cyphar@cyphar.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
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 (Microsoft) <brauner@kernel.org>
2022-06-21 14:14:47 +00:00
|
|
|
return VFSUIDT_INIT(kuid);
|
fs: account for filesystem mappings
Currently we only support idmapped mounts for filesystems mounted
without an idmapping. This was a conscious decision mentioned in
multiple places (cf. e.g. [1]).
As explained at length in [3] it is perfectly fine to extend support for
idmapped mounts to filesystem's mounted with an idmapping should the
need arise. The need has been there for some time now. Various container
projects in userspace need this to run unprivileged and nested
unprivileged containers (cf. [2]).
Before we can port any filesystem that is mountable with an idmapping to
support idmapped mounts we need to first extend the mapping helpers to
account for the filesystem's idmapping. This again, is explained at
length in our documentation at [3] but I'll give an overview here again.
Currently, the low-level mapping helpers implement the remapping
algorithms described in [3] in a simplified manner. Because we could
rely on the fact that all filesystems supporting idmapped mounts are
mounted without an idmapping the translation step from or into the
filesystem idmapping could be skipped.
In order to support idmapped mounts of filesystem's mountable with an
idmapping the translation step we were able to skip before cannot be
skipped anymore. A filesystem mounted with an idmapping is very likely
to not use an identity mapping and will instead use a non-identity
mapping. So the translation step from or into the filesystem's idmapping
in the remapping algorithm cannot be skipped for such filesystems. More
details with examples can be found in [3].
This patch adds a few new and prepares some already existing low-level
mapping helpers to perform the full translation algorithm explained in
[3]. The low-level helpers can be written in a way that they only
perform the additional translation step when the filesystem is indeed
mounted with an idmapping.
If the low-level helpers detect that they are not dealing with an
idmapped mount they can simply return the relevant k{g,u}id unchanged;
no remapping needs to be performed at all. The no_idmapping() helper
detects whether the shortcut can be used.
If the low-level helpers detected that they are dealing with an idmapped
mount but the underlying filesystem is mounted without an idmapping we
can rely on the previous shorcut and can continue to skip the
translation step from or into the filesystem's idmapping.
These checks guarantee that only the minimal amount of work is
performed. As before, if idmapped mounts aren't used the low-level
helpers are idempotent and no work is performed at all.
This patch adds the helpers mapped_k{g,u}id_fs() and
mapped_k{g,u}id_user(). Following patches will port all places to
replace the old k{g,u}id_into_mnt() and k{g,u}id_from_mnt() with these
two new helpers. After the conversion is done k{g,u}id_into_mnt() and
k{g,u}id_from_mnt() will be removed. This also concludes the renaming of
the mapping helpers we started in [4]. Now, all mapping helpers will
started with the "mapped_" prefix making everything nice and consistent.
The mapped_k{g,u}id_fs() helpers replace the k{g,u}id_into_mnt()
helpers. They are to be used when k{g,u}ids are to be mapped from the
vfs, e.g. from from struct inode's i_{g,u}id. Conversely, the
mapped_k{g,u}id_user() helpers replace the k{g,u}id_from_mnt() helpers.
They are to be used when k{g,u}ids are to be written to disk, e.g. when
entering from a system call to change ownership of a file.
This patch only introduces the helpers. It doesn't yet convert the
relevant places to account for filesystem mounted with an idmapping.
[1]: commit 2ca4dcc4909d ("fs/mount_setattr: tighten permission checks")
[2]: https://github.com/containers/podman/issues/10374
[3]: Documentations/filesystems/idmappings.rst
[4]: commit a65e58e791a1 ("fs: document and rename fsid helpers")
Link: https://lore.kernel.org/r/20211123114227.3124056-5-brauner@kernel.org (v1)
Link: https://lore.kernel.org/r/20211130121032.3753852-5-brauner@kernel.org (v2)
Link: https://lore.kernel.org/r/20211203111707.3901969-5-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>
2021-12-03 11:17:01 +00:00
|
|
|
if (initial_idmapping(fs_userns))
|
|
|
|
uid = __kuid_val(kuid);
|
|
|
|
else
|
|
|
|
uid = from_kuid(fs_userns, kuid);
|
|
|
|
if (uid == (uid_t)-1)
|
mnt_idmapping: add vfs{g,u}id_t
Introduces new vfs{g,u}id_t types. Similar to k{g,u}id_t the new types
are just simple wrapper structs around regular {g,u}id_t types.
They allows to establish a type safety boundary between {g,u}ids on
idmapped mounts and {g,u}ids as they are represented in filesystems
themselves.
A vfs{g,u}id_t is always created from a k{g,u}id_t, never directly from
a {g,u}id_t as idmapped mounts remap a given {g,u}id according to the
mount's idmapping. This is expressed in the VFS{G,U}IDT_INIT() macros.
A vfs{g,u}id_t may be used as a k{g,u}id_t via AS_K{G,U}IDT(). This
often happens when we need to check whether a {g,u}id mapped according
to an idmapped mount is identical to a given k{g,u}id_t. For an example,
see vfsgid_in_group_p() which determines whether the value of vfsgid_t
matches the value of any of the caller's groups. Similar logic is
expressed in the k{g,u}id_eq_vfs{g,u}id().
The from_vfs{g,u}id() helpers map a given vfs{g,u}id_t from the mount's
idmapping into the filesystem idmapping. They make it possible to update
a filesystem object such as inode->i_{g,u}id with the correct value.
This makes it harder to accidently write a wrong {g,u}id anwywhere. The
vfs{g,u}id_has_fsmapping() helpers check whether a given vfs{g,u}id_t
can be mapped into the filesystem idmapping.
All new helpers are nops on non-idmapped mounts.
I've done work on this roughly 7 months ago but dropped it to focus on
the testsuite. Linus brought this up independently just last week and
it's time to move this along (see [1]).
[1]: https://lore.kernel.org/lkml/CAHk-=win6+ahs1EwLkcq8apqLi_1wXFWbrPf340zYEhObpz4jA@mail.gmail.com
Link: https://lore.kernel.org/r/20220621141454.2914719-2-brauner@kernel.org
Cc: Seth Forshee <sforshee@digitalocean.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Aleksa Sarai <cyphar@cyphar.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
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 (Microsoft) <brauner@kernel.org>
2022-06-21 14:14:47 +00:00
|
|
|
return INVALID_VFSUID;
|
|
|
|
return VFSUIDT_INIT(make_kuid(mnt_userns, uid));
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline kuid_t mapped_kuid_fs(struct user_namespace *mnt_userns,
|
|
|
|
struct user_namespace *fs_userns,
|
|
|
|
kuid_t kuid)
|
|
|
|
{
|
|
|
|
return AS_KUIDT(make_vfsuid(mnt_userns, fs_userns, kuid));
|
fs: account for filesystem mappings
Currently we only support idmapped mounts for filesystems mounted
without an idmapping. This was a conscious decision mentioned in
multiple places (cf. e.g. [1]).
As explained at length in [3] it is perfectly fine to extend support for
idmapped mounts to filesystem's mounted with an idmapping should the
need arise. The need has been there for some time now. Various container
projects in userspace need this to run unprivileged and nested
unprivileged containers (cf. [2]).
Before we can port any filesystem that is mountable with an idmapping to
support idmapped mounts we need to first extend the mapping helpers to
account for the filesystem's idmapping. This again, is explained at
length in our documentation at [3] but I'll give an overview here again.
Currently, the low-level mapping helpers implement the remapping
algorithms described in [3] in a simplified manner. Because we could
rely on the fact that all filesystems supporting idmapped mounts are
mounted without an idmapping the translation step from or into the
filesystem idmapping could be skipped.
In order to support idmapped mounts of filesystem's mountable with an
idmapping the translation step we were able to skip before cannot be
skipped anymore. A filesystem mounted with an idmapping is very likely
to not use an identity mapping and will instead use a non-identity
mapping. So the translation step from or into the filesystem's idmapping
in the remapping algorithm cannot be skipped for such filesystems. More
details with examples can be found in [3].
This patch adds a few new and prepares some already existing low-level
mapping helpers to perform the full translation algorithm explained in
[3]. The low-level helpers can be written in a way that they only
perform the additional translation step when the filesystem is indeed
mounted with an idmapping.
If the low-level helpers detect that they are not dealing with an
idmapped mount they can simply return the relevant k{g,u}id unchanged;
no remapping needs to be performed at all. The no_idmapping() helper
detects whether the shortcut can be used.
If the low-level helpers detected that they are dealing with an idmapped
mount but the underlying filesystem is mounted without an idmapping we
can rely on the previous shorcut and can continue to skip the
translation step from or into the filesystem's idmapping.
These checks guarantee that only the minimal amount of work is
performed. As before, if idmapped mounts aren't used the low-level
helpers are idempotent and no work is performed at all.
This patch adds the helpers mapped_k{g,u}id_fs() and
mapped_k{g,u}id_user(). Following patches will port all places to
replace the old k{g,u}id_into_mnt() and k{g,u}id_from_mnt() with these
two new helpers. After the conversion is done k{g,u}id_into_mnt() and
k{g,u}id_from_mnt() will be removed. This also concludes the renaming of
the mapping helpers we started in [4]. Now, all mapping helpers will
started with the "mapped_" prefix making everything nice and consistent.
The mapped_k{g,u}id_fs() helpers replace the k{g,u}id_into_mnt()
helpers. They are to be used when k{g,u}ids are to be mapped from the
vfs, e.g. from from struct inode's i_{g,u}id. Conversely, the
mapped_k{g,u}id_user() helpers replace the k{g,u}id_from_mnt() helpers.
They are to be used when k{g,u}ids are to be written to disk, e.g. when
entering from a system call to change ownership of a file.
This patch only introduces the helpers. It doesn't yet convert the
relevant places to account for filesystem mounted with an idmapping.
[1]: commit 2ca4dcc4909d ("fs/mount_setattr: tighten permission checks")
[2]: https://github.com/containers/podman/issues/10374
[3]: Documentations/filesystems/idmappings.rst
[4]: commit a65e58e791a1 ("fs: document and rename fsid helpers")
Link: https://lore.kernel.org/r/20211123114227.3124056-5-brauner@kernel.org (v1)
Link: https://lore.kernel.org/r/20211130121032.3753852-5-brauner@kernel.org (v2)
Link: https://lore.kernel.org/r/20211203111707.3901969-5-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>
2021-12-03 11:17:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* mapped_kgid_fs - map a filesystem kgid into a mnt_userns
|
|
|
|
* @mnt_userns: the mount's idmapping
|
|
|
|
* @fs_userns: the filesystem's idmapping
|
|
|
|
* @kgid : kgid to be mapped
|
|
|
|
*
|
|
|
|
* Take a @kgid and remap it from @fs_userns into @mnt_userns. Use this
|
|
|
|
* function when preparing a @kgid to be reported to userspace.
|
|
|
|
*
|
|
|
|
* If no_idmapping() determines that this is not an idmapped mount we can
|
|
|
|
* simply return @kgid unchanged.
|
|
|
|
* If initial_idmapping() tells us that the filesystem is not mounted with an
|
|
|
|
* idmapping we know the value of @kgid won't change when calling
|
|
|
|
* from_kgid() so we can simply retrieve the value via __kgid_val()
|
|
|
|
* directly.
|
|
|
|
*
|
|
|
|
* Return: @kgid mapped according to @mnt_userns.
|
|
|
|
* If @kgid has no mapping in either @mnt_userns or @fs_userns INVALID_GID is
|
|
|
|
* returned.
|
|
|
|
*/
|
mnt_idmapping: add vfs{g,u}id_t
Introduces new vfs{g,u}id_t types. Similar to k{g,u}id_t the new types
are just simple wrapper structs around regular {g,u}id_t types.
They allows to establish a type safety boundary between {g,u}ids on
idmapped mounts and {g,u}ids as they are represented in filesystems
themselves.
A vfs{g,u}id_t is always created from a k{g,u}id_t, never directly from
a {g,u}id_t as idmapped mounts remap a given {g,u}id according to the
mount's idmapping. This is expressed in the VFS{G,U}IDT_INIT() macros.
A vfs{g,u}id_t may be used as a k{g,u}id_t via AS_K{G,U}IDT(). This
often happens when we need to check whether a {g,u}id mapped according
to an idmapped mount is identical to a given k{g,u}id_t. For an example,
see vfsgid_in_group_p() which determines whether the value of vfsgid_t
matches the value of any of the caller's groups. Similar logic is
expressed in the k{g,u}id_eq_vfs{g,u}id().
The from_vfs{g,u}id() helpers map a given vfs{g,u}id_t from the mount's
idmapping into the filesystem idmapping. They make it possible to update
a filesystem object such as inode->i_{g,u}id with the correct value.
This makes it harder to accidently write a wrong {g,u}id anwywhere. The
vfs{g,u}id_has_fsmapping() helpers check whether a given vfs{g,u}id_t
can be mapped into the filesystem idmapping.
All new helpers are nops on non-idmapped mounts.
I've done work on this roughly 7 months ago but dropped it to focus on
the testsuite. Linus brought this up independently just last week and
it's time to move this along (see [1]).
[1]: https://lore.kernel.org/lkml/CAHk-=win6+ahs1EwLkcq8apqLi_1wXFWbrPf340zYEhObpz4jA@mail.gmail.com
Link: https://lore.kernel.org/r/20220621141454.2914719-2-brauner@kernel.org
Cc: Seth Forshee <sforshee@digitalocean.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Aleksa Sarai <cyphar@cyphar.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
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 (Microsoft) <brauner@kernel.org>
2022-06-21 14:14:47 +00:00
|
|
|
|
|
|
|
static inline vfsgid_t make_vfsgid(struct user_namespace *mnt_userns,
|
|
|
|
struct user_namespace *fs_userns,
|
|
|
|
kgid_t kgid)
|
fs: account for filesystem mappings
Currently we only support idmapped mounts for filesystems mounted
without an idmapping. This was a conscious decision mentioned in
multiple places (cf. e.g. [1]).
As explained at length in [3] it is perfectly fine to extend support for
idmapped mounts to filesystem's mounted with an idmapping should the
need arise. The need has been there for some time now. Various container
projects in userspace need this to run unprivileged and nested
unprivileged containers (cf. [2]).
Before we can port any filesystem that is mountable with an idmapping to
support idmapped mounts we need to first extend the mapping helpers to
account for the filesystem's idmapping. This again, is explained at
length in our documentation at [3] but I'll give an overview here again.
Currently, the low-level mapping helpers implement the remapping
algorithms described in [3] in a simplified manner. Because we could
rely on the fact that all filesystems supporting idmapped mounts are
mounted without an idmapping the translation step from or into the
filesystem idmapping could be skipped.
In order to support idmapped mounts of filesystem's mountable with an
idmapping the translation step we were able to skip before cannot be
skipped anymore. A filesystem mounted with an idmapping is very likely
to not use an identity mapping and will instead use a non-identity
mapping. So the translation step from or into the filesystem's idmapping
in the remapping algorithm cannot be skipped for such filesystems. More
details with examples can be found in [3].
This patch adds a few new and prepares some already existing low-level
mapping helpers to perform the full translation algorithm explained in
[3]. The low-level helpers can be written in a way that they only
perform the additional translation step when the filesystem is indeed
mounted with an idmapping.
If the low-level helpers detect that they are not dealing with an
idmapped mount they can simply return the relevant k{g,u}id unchanged;
no remapping needs to be performed at all. The no_idmapping() helper
detects whether the shortcut can be used.
If the low-level helpers detected that they are dealing with an idmapped
mount but the underlying filesystem is mounted without an idmapping we
can rely on the previous shorcut and can continue to skip the
translation step from or into the filesystem's idmapping.
These checks guarantee that only the minimal amount of work is
performed. As before, if idmapped mounts aren't used the low-level
helpers are idempotent and no work is performed at all.
This patch adds the helpers mapped_k{g,u}id_fs() and
mapped_k{g,u}id_user(). Following patches will port all places to
replace the old k{g,u}id_into_mnt() and k{g,u}id_from_mnt() with these
two new helpers. After the conversion is done k{g,u}id_into_mnt() and
k{g,u}id_from_mnt() will be removed. This also concludes the renaming of
the mapping helpers we started in [4]. Now, all mapping helpers will
started with the "mapped_" prefix making everything nice and consistent.
The mapped_k{g,u}id_fs() helpers replace the k{g,u}id_into_mnt()
helpers. They are to be used when k{g,u}ids are to be mapped from the
vfs, e.g. from from struct inode's i_{g,u}id. Conversely, the
mapped_k{g,u}id_user() helpers replace the k{g,u}id_from_mnt() helpers.
They are to be used when k{g,u}ids are to be written to disk, e.g. when
entering from a system call to change ownership of a file.
This patch only introduces the helpers. It doesn't yet convert the
relevant places to account for filesystem mounted with an idmapping.
[1]: commit 2ca4dcc4909d ("fs/mount_setattr: tighten permission checks")
[2]: https://github.com/containers/podman/issues/10374
[3]: Documentations/filesystems/idmappings.rst
[4]: commit a65e58e791a1 ("fs: document and rename fsid helpers")
Link: https://lore.kernel.org/r/20211123114227.3124056-5-brauner@kernel.org (v1)
Link: https://lore.kernel.org/r/20211130121032.3753852-5-brauner@kernel.org (v2)
Link: https://lore.kernel.org/r/20211203111707.3901969-5-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>
2021-12-03 11:17:01 +00:00
|
|
|
{
|
|
|
|
gid_t gid;
|
|
|
|
|
|
|
|
if (no_idmapping(mnt_userns, fs_userns))
|
mnt_idmapping: add vfs{g,u}id_t
Introduces new vfs{g,u}id_t types. Similar to k{g,u}id_t the new types
are just simple wrapper structs around regular {g,u}id_t types.
They allows to establish a type safety boundary between {g,u}ids on
idmapped mounts and {g,u}ids as they are represented in filesystems
themselves.
A vfs{g,u}id_t is always created from a k{g,u}id_t, never directly from
a {g,u}id_t as idmapped mounts remap a given {g,u}id according to the
mount's idmapping. This is expressed in the VFS{G,U}IDT_INIT() macros.
A vfs{g,u}id_t may be used as a k{g,u}id_t via AS_K{G,U}IDT(). This
often happens when we need to check whether a {g,u}id mapped according
to an idmapped mount is identical to a given k{g,u}id_t. For an example,
see vfsgid_in_group_p() which determines whether the value of vfsgid_t
matches the value of any of the caller's groups. Similar logic is
expressed in the k{g,u}id_eq_vfs{g,u}id().
The from_vfs{g,u}id() helpers map a given vfs{g,u}id_t from the mount's
idmapping into the filesystem idmapping. They make it possible to update
a filesystem object such as inode->i_{g,u}id with the correct value.
This makes it harder to accidently write a wrong {g,u}id anwywhere. The
vfs{g,u}id_has_fsmapping() helpers check whether a given vfs{g,u}id_t
can be mapped into the filesystem idmapping.
All new helpers are nops on non-idmapped mounts.
I've done work on this roughly 7 months ago but dropped it to focus on
the testsuite. Linus brought this up independently just last week and
it's time to move this along (see [1]).
[1]: https://lore.kernel.org/lkml/CAHk-=win6+ahs1EwLkcq8apqLi_1wXFWbrPf340zYEhObpz4jA@mail.gmail.com
Link: https://lore.kernel.org/r/20220621141454.2914719-2-brauner@kernel.org
Cc: Seth Forshee <sforshee@digitalocean.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Aleksa Sarai <cyphar@cyphar.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
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 (Microsoft) <brauner@kernel.org>
2022-06-21 14:14:47 +00:00
|
|
|
return VFSGIDT_INIT(kgid);
|
fs: account for filesystem mappings
Currently we only support idmapped mounts for filesystems mounted
without an idmapping. This was a conscious decision mentioned in
multiple places (cf. e.g. [1]).
As explained at length in [3] it is perfectly fine to extend support for
idmapped mounts to filesystem's mounted with an idmapping should the
need arise. The need has been there for some time now. Various container
projects in userspace need this to run unprivileged and nested
unprivileged containers (cf. [2]).
Before we can port any filesystem that is mountable with an idmapping to
support idmapped mounts we need to first extend the mapping helpers to
account for the filesystem's idmapping. This again, is explained at
length in our documentation at [3] but I'll give an overview here again.
Currently, the low-level mapping helpers implement the remapping
algorithms described in [3] in a simplified manner. Because we could
rely on the fact that all filesystems supporting idmapped mounts are
mounted without an idmapping the translation step from or into the
filesystem idmapping could be skipped.
In order to support idmapped mounts of filesystem's mountable with an
idmapping the translation step we were able to skip before cannot be
skipped anymore. A filesystem mounted with an idmapping is very likely
to not use an identity mapping and will instead use a non-identity
mapping. So the translation step from or into the filesystem's idmapping
in the remapping algorithm cannot be skipped for such filesystems. More
details with examples can be found in [3].
This patch adds a few new and prepares some already existing low-level
mapping helpers to perform the full translation algorithm explained in
[3]. The low-level helpers can be written in a way that they only
perform the additional translation step when the filesystem is indeed
mounted with an idmapping.
If the low-level helpers detect that they are not dealing with an
idmapped mount they can simply return the relevant k{g,u}id unchanged;
no remapping needs to be performed at all. The no_idmapping() helper
detects whether the shortcut can be used.
If the low-level helpers detected that they are dealing with an idmapped
mount but the underlying filesystem is mounted without an idmapping we
can rely on the previous shorcut and can continue to skip the
translation step from or into the filesystem's idmapping.
These checks guarantee that only the minimal amount of work is
performed. As before, if idmapped mounts aren't used the low-level
helpers are idempotent and no work is performed at all.
This patch adds the helpers mapped_k{g,u}id_fs() and
mapped_k{g,u}id_user(). Following patches will port all places to
replace the old k{g,u}id_into_mnt() and k{g,u}id_from_mnt() with these
two new helpers. After the conversion is done k{g,u}id_into_mnt() and
k{g,u}id_from_mnt() will be removed. This also concludes the renaming of
the mapping helpers we started in [4]. Now, all mapping helpers will
started with the "mapped_" prefix making everything nice and consistent.
The mapped_k{g,u}id_fs() helpers replace the k{g,u}id_into_mnt()
helpers. They are to be used when k{g,u}ids are to be mapped from the
vfs, e.g. from from struct inode's i_{g,u}id. Conversely, the
mapped_k{g,u}id_user() helpers replace the k{g,u}id_from_mnt() helpers.
They are to be used when k{g,u}ids are to be written to disk, e.g. when
entering from a system call to change ownership of a file.
This patch only introduces the helpers. It doesn't yet convert the
relevant places to account for filesystem mounted with an idmapping.
[1]: commit 2ca4dcc4909d ("fs/mount_setattr: tighten permission checks")
[2]: https://github.com/containers/podman/issues/10374
[3]: Documentations/filesystems/idmappings.rst
[4]: commit a65e58e791a1 ("fs: document and rename fsid helpers")
Link: https://lore.kernel.org/r/20211123114227.3124056-5-brauner@kernel.org (v1)
Link: https://lore.kernel.org/r/20211130121032.3753852-5-brauner@kernel.org (v2)
Link: https://lore.kernel.org/r/20211203111707.3901969-5-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>
2021-12-03 11:17:01 +00:00
|
|
|
if (initial_idmapping(fs_userns))
|
|
|
|
gid = __kgid_val(kgid);
|
|
|
|
else
|
|
|
|
gid = from_kgid(fs_userns, kgid);
|
|
|
|
if (gid == (gid_t)-1)
|
mnt_idmapping: add vfs{g,u}id_t
Introduces new vfs{g,u}id_t types. Similar to k{g,u}id_t the new types
are just simple wrapper structs around regular {g,u}id_t types.
They allows to establish a type safety boundary between {g,u}ids on
idmapped mounts and {g,u}ids as they are represented in filesystems
themselves.
A vfs{g,u}id_t is always created from a k{g,u}id_t, never directly from
a {g,u}id_t as idmapped mounts remap a given {g,u}id according to the
mount's idmapping. This is expressed in the VFS{G,U}IDT_INIT() macros.
A vfs{g,u}id_t may be used as a k{g,u}id_t via AS_K{G,U}IDT(). This
often happens when we need to check whether a {g,u}id mapped according
to an idmapped mount is identical to a given k{g,u}id_t. For an example,
see vfsgid_in_group_p() which determines whether the value of vfsgid_t
matches the value of any of the caller's groups. Similar logic is
expressed in the k{g,u}id_eq_vfs{g,u}id().
The from_vfs{g,u}id() helpers map a given vfs{g,u}id_t from the mount's
idmapping into the filesystem idmapping. They make it possible to update
a filesystem object such as inode->i_{g,u}id with the correct value.
This makes it harder to accidently write a wrong {g,u}id anwywhere. The
vfs{g,u}id_has_fsmapping() helpers check whether a given vfs{g,u}id_t
can be mapped into the filesystem idmapping.
All new helpers are nops on non-idmapped mounts.
I've done work on this roughly 7 months ago but dropped it to focus on
the testsuite. Linus brought this up independently just last week and
it's time to move this along (see [1]).
[1]: https://lore.kernel.org/lkml/CAHk-=win6+ahs1EwLkcq8apqLi_1wXFWbrPf340zYEhObpz4jA@mail.gmail.com
Link: https://lore.kernel.org/r/20220621141454.2914719-2-brauner@kernel.org
Cc: Seth Forshee <sforshee@digitalocean.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Aleksa Sarai <cyphar@cyphar.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
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 (Microsoft) <brauner@kernel.org>
2022-06-21 14:14:47 +00:00
|
|
|
return INVALID_VFSGID;
|
|
|
|
return VFSGIDT_INIT(make_kgid(mnt_userns, gid));
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline kgid_t mapped_kgid_fs(struct user_namespace *mnt_userns,
|
|
|
|
struct user_namespace *fs_userns,
|
|
|
|
kgid_t kgid)
|
|
|
|
{
|
|
|
|
return AS_KGIDT(make_vfsgid(mnt_userns, fs_userns, kgid));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* from_vfsuid - map a vfsuid into the filesystem idmapping
|
|
|
|
* @mnt_userns: the mount's idmapping
|
|
|
|
* @fs_userns: the filesystem's idmapping
|
|
|
|
* @vfsuid : vfsuid to be mapped
|
|
|
|
*
|
|
|
|
* Map @vfsuid into the filesystem idmapping. This function has to be used in
|
|
|
|
* order to e.g. write @vfsuid to inode->i_uid.
|
|
|
|
*
|
|
|
|
* Return: @vfsuid mapped into the filesystem idmapping
|
|
|
|
*/
|
|
|
|
static inline kuid_t from_vfsuid(struct user_namespace *mnt_userns,
|
|
|
|
struct user_namespace *fs_userns,
|
|
|
|
vfsuid_t vfsuid)
|
|
|
|
{
|
|
|
|
uid_t uid;
|
|
|
|
|
|
|
|
if (no_idmapping(mnt_userns, fs_userns))
|
|
|
|
return AS_KUIDT(vfsuid);
|
|
|
|
uid = from_kuid(mnt_userns, AS_KUIDT(vfsuid));
|
|
|
|
if (uid == (uid_t)-1)
|
|
|
|
return INVALID_UID;
|
|
|
|
if (initial_idmapping(fs_userns))
|
|
|
|
return KUIDT_INIT(uid);
|
|
|
|
return make_kuid(fs_userns, uid);
|
fs: account for filesystem mappings
Currently we only support idmapped mounts for filesystems mounted
without an idmapping. This was a conscious decision mentioned in
multiple places (cf. e.g. [1]).
As explained at length in [3] it is perfectly fine to extend support for
idmapped mounts to filesystem's mounted with an idmapping should the
need arise. The need has been there for some time now. Various container
projects in userspace need this to run unprivileged and nested
unprivileged containers (cf. [2]).
Before we can port any filesystem that is mountable with an idmapping to
support idmapped mounts we need to first extend the mapping helpers to
account for the filesystem's idmapping. This again, is explained at
length in our documentation at [3] but I'll give an overview here again.
Currently, the low-level mapping helpers implement the remapping
algorithms described in [3] in a simplified manner. Because we could
rely on the fact that all filesystems supporting idmapped mounts are
mounted without an idmapping the translation step from or into the
filesystem idmapping could be skipped.
In order to support idmapped mounts of filesystem's mountable with an
idmapping the translation step we were able to skip before cannot be
skipped anymore. A filesystem mounted with an idmapping is very likely
to not use an identity mapping and will instead use a non-identity
mapping. So the translation step from or into the filesystem's idmapping
in the remapping algorithm cannot be skipped for such filesystems. More
details with examples can be found in [3].
This patch adds a few new and prepares some already existing low-level
mapping helpers to perform the full translation algorithm explained in
[3]. The low-level helpers can be written in a way that they only
perform the additional translation step when the filesystem is indeed
mounted with an idmapping.
If the low-level helpers detect that they are not dealing with an
idmapped mount they can simply return the relevant k{g,u}id unchanged;
no remapping needs to be performed at all. The no_idmapping() helper
detects whether the shortcut can be used.
If the low-level helpers detected that they are dealing with an idmapped
mount but the underlying filesystem is mounted without an idmapping we
can rely on the previous shorcut and can continue to skip the
translation step from or into the filesystem's idmapping.
These checks guarantee that only the minimal amount of work is
performed. As before, if idmapped mounts aren't used the low-level
helpers are idempotent and no work is performed at all.
This patch adds the helpers mapped_k{g,u}id_fs() and
mapped_k{g,u}id_user(). Following patches will port all places to
replace the old k{g,u}id_into_mnt() and k{g,u}id_from_mnt() with these
two new helpers. After the conversion is done k{g,u}id_into_mnt() and
k{g,u}id_from_mnt() will be removed. This also concludes the renaming of
the mapping helpers we started in [4]. Now, all mapping helpers will
started with the "mapped_" prefix making everything nice and consistent.
The mapped_k{g,u}id_fs() helpers replace the k{g,u}id_into_mnt()
helpers. They are to be used when k{g,u}ids are to be mapped from the
vfs, e.g. from from struct inode's i_{g,u}id. Conversely, the
mapped_k{g,u}id_user() helpers replace the k{g,u}id_from_mnt() helpers.
They are to be used when k{g,u}ids are to be written to disk, e.g. when
entering from a system call to change ownership of a file.
This patch only introduces the helpers. It doesn't yet convert the
relevant places to account for filesystem mounted with an idmapping.
[1]: commit 2ca4dcc4909d ("fs/mount_setattr: tighten permission checks")
[2]: https://github.com/containers/podman/issues/10374
[3]: Documentations/filesystems/idmappings.rst
[4]: commit a65e58e791a1 ("fs: document and rename fsid helpers")
Link: https://lore.kernel.org/r/20211123114227.3124056-5-brauner@kernel.org (v1)
Link: https://lore.kernel.org/r/20211130121032.3753852-5-brauner@kernel.org (v2)
Link: https://lore.kernel.org/r/20211203111707.3901969-5-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>
2021-12-03 11:17:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* mapped_kuid_user - map a user kuid into a mnt_userns
|
|
|
|
* @mnt_userns: the mount's idmapping
|
|
|
|
* @fs_userns: the filesystem's idmapping
|
|
|
|
* @kuid : kuid to be mapped
|
|
|
|
*
|
|
|
|
* Use the idmapping of @mnt_userns to remap a @kuid into @fs_userns. Use this
|
|
|
|
* function when preparing a @kuid to be written to disk or inode.
|
|
|
|
*
|
|
|
|
* If no_idmapping() determines that this is not an idmapped mount we can
|
|
|
|
* simply return @kuid unchanged.
|
|
|
|
* If initial_idmapping() tells us that the filesystem is not mounted with an
|
|
|
|
* idmapping we know the value of @kuid won't change when calling
|
|
|
|
* make_kuid() so we can simply retrieve the value via KUIDT_INIT()
|
|
|
|
* directly.
|
|
|
|
*
|
|
|
|
* Return: @kuid mapped according to @mnt_userns.
|
|
|
|
* If @kuid has no mapping in either @mnt_userns or @fs_userns INVALID_UID is
|
|
|
|
* returned.
|
|
|
|
*/
|
|
|
|
static inline kuid_t mapped_kuid_user(struct user_namespace *mnt_userns,
|
|
|
|
struct user_namespace *fs_userns,
|
|
|
|
kuid_t kuid)
|
|
|
|
{
|
mnt_idmapping: add vfs{g,u}id_t
Introduces new vfs{g,u}id_t types. Similar to k{g,u}id_t the new types
are just simple wrapper structs around regular {g,u}id_t types.
They allows to establish a type safety boundary between {g,u}ids on
idmapped mounts and {g,u}ids as they are represented in filesystems
themselves.
A vfs{g,u}id_t is always created from a k{g,u}id_t, never directly from
a {g,u}id_t as idmapped mounts remap a given {g,u}id according to the
mount's idmapping. This is expressed in the VFS{G,U}IDT_INIT() macros.
A vfs{g,u}id_t may be used as a k{g,u}id_t via AS_K{G,U}IDT(). This
often happens when we need to check whether a {g,u}id mapped according
to an idmapped mount is identical to a given k{g,u}id_t. For an example,
see vfsgid_in_group_p() which determines whether the value of vfsgid_t
matches the value of any of the caller's groups. Similar logic is
expressed in the k{g,u}id_eq_vfs{g,u}id().
The from_vfs{g,u}id() helpers map a given vfs{g,u}id_t from the mount's
idmapping into the filesystem idmapping. They make it possible to update
a filesystem object such as inode->i_{g,u}id with the correct value.
This makes it harder to accidently write a wrong {g,u}id anwywhere. The
vfs{g,u}id_has_fsmapping() helpers check whether a given vfs{g,u}id_t
can be mapped into the filesystem idmapping.
All new helpers are nops on non-idmapped mounts.
I've done work on this roughly 7 months ago but dropped it to focus on
the testsuite. Linus brought this up independently just last week and
it's time to move this along (see [1]).
[1]: https://lore.kernel.org/lkml/CAHk-=win6+ahs1EwLkcq8apqLi_1wXFWbrPf340zYEhObpz4jA@mail.gmail.com
Link: https://lore.kernel.org/r/20220621141454.2914719-2-brauner@kernel.org
Cc: Seth Forshee <sforshee@digitalocean.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Aleksa Sarai <cyphar@cyphar.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
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 (Microsoft) <brauner@kernel.org>
2022-06-21 14:14:47 +00:00
|
|
|
return from_vfsuid(mnt_userns, fs_userns, VFSUIDT_INIT(kuid));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* vfsuid_has_fsmapping - check whether a vfsuid maps into the filesystem
|
|
|
|
* @mnt_userns: the mount's idmapping
|
|
|
|
* @fs_userns: the filesystem's idmapping
|
|
|
|
* @vfsuid: vfsuid to be mapped
|
|
|
|
*
|
|
|
|
* Check whether @vfsuid has a mapping in the filesystem idmapping. Use this
|
|
|
|
* function to check whether the filesystem idmapping has a mapping for
|
|
|
|
* @vfsuid.
|
|
|
|
*
|
|
|
|
* Return: true if @vfsuid has a mapping in the filesystem, false if not.
|
|
|
|
*/
|
|
|
|
static inline bool vfsuid_has_fsmapping(struct user_namespace *mnt_userns,
|
|
|
|
struct user_namespace *fs_userns,
|
|
|
|
vfsuid_t vfsuid)
|
|
|
|
{
|
|
|
|
return uid_valid(from_vfsuid(mnt_userns, fs_userns, vfsuid));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* from_vfsgid - map a vfsgid into the filesystem idmapping
|
|
|
|
* @mnt_userns: the mount's idmapping
|
|
|
|
* @fs_userns: the filesystem's idmapping
|
|
|
|
* @vfsgid : vfsgid to be mapped
|
|
|
|
*
|
|
|
|
* Map @vfsgid into the filesystem idmapping. This function has to be used in
|
|
|
|
* order to e.g. write @vfsgid to inode->i_gid.
|
|
|
|
*
|
|
|
|
* Return: @vfsgid mapped into the filesystem idmapping
|
|
|
|
*/
|
|
|
|
static inline kgid_t from_vfsgid(struct user_namespace *mnt_userns,
|
|
|
|
struct user_namespace *fs_userns,
|
|
|
|
vfsgid_t vfsgid)
|
|
|
|
{
|
|
|
|
gid_t gid;
|
fs: account for filesystem mappings
Currently we only support idmapped mounts for filesystems mounted
without an idmapping. This was a conscious decision mentioned in
multiple places (cf. e.g. [1]).
As explained at length in [3] it is perfectly fine to extend support for
idmapped mounts to filesystem's mounted with an idmapping should the
need arise. The need has been there for some time now. Various container
projects in userspace need this to run unprivileged and nested
unprivileged containers (cf. [2]).
Before we can port any filesystem that is mountable with an idmapping to
support idmapped mounts we need to first extend the mapping helpers to
account for the filesystem's idmapping. This again, is explained at
length in our documentation at [3] but I'll give an overview here again.
Currently, the low-level mapping helpers implement the remapping
algorithms described in [3] in a simplified manner. Because we could
rely on the fact that all filesystems supporting idmapped mounts are
mounted without an idmapping the translation step from or into the
filesystem idmapping could be skipped.
In order to support idmapped mounts of filesystem's mountable with an
idmapping the translation step we were able to skip before cannot be
skipped anymore. A filesystem mounted with an idmapping is very likely
to not use an identity mapping and will instead use a non-identity
mapping. So the translation step from or into the filesystem's idmapping
in the remapping algorithm cannot be skipped for such filesystems. More
details with examples can be found in [3].
This patch adds a few new and prepares some already existing low-level
mapping helpers to perform the full translation algorithm explained in
[3]. The low-level helpers can be written in a way that they only
perform the additional translation step when the filesystem is indeed
mounted with an idmapping.
If the low-level helpers detect that they are not dealing with an
idmapped mount they can simply return the relevant k{g,u}id unchanged;
no remapping needs to be performed at all. The no_idmapping() helper
detects whether the shortcut can be used.
If the low-level helpers detected that they are dealing with an idmapped
mount but the underlying filesystem is mounted without an idmapping we
can rely on the previous shorcut and can continue to skip the
translation step from or into the filesystem's idmapping.
These checks guarantee that only the minimal amount of work is
performed. As before, if idmapped mounts aren't used the low-level
helpers are idempotent and no work is performed at all.
This patch adds the helpers mapped_k{g,u}id_fs() and
mapped_k{g,u}id_user(). Following patches will port all places to
replace the old k{g,u}id_into_mnt() and k{g,u}id_from_mnt() with these
two new helpers. After the conversion is done k{g,u}id_into_mnt() and
k{g,u}id_from_mnt() will be removed. This also concludes the renaming of
the mapping helpers we started in [4]. Now, all mapping helpers will
started with the "mapped_" prefix making everything nice and consistent.
The mapped_k{g,u}id_fs() helpers replace the k{g,u}id_into_mnt()
helpers. They are to be used when k{g,u}ids are to be mapped from the
vfs, e.g. from from struct inode's i_{g,u}id. Conversely, the
mapped_k{g,u}id_user() helpers replace the k{g,u}id_from_mnt() helpers.
They are to be used when k{g,u}ids are to be written to disk, e.g. when
entering from a system call to change ownership of a file.
This patch only introduces the helpers. It doesn't yet convert the
relevant places to account for filesystem mounted with an idmapping.
[1]: commit 2ca4dcc4909d ("fs/mount_setattr: tighten permission checks")
[2]: https://github.com/containers/podman/issues/10374
[3]: Documentations/filesystems/idmappings.rst
[4]: commit a65e58e791a1 ("fs: document and rename fsid helpers")
Link: https://lore.kernel.org/r/20211123114227.3124056-5-brauner@kernel.org (v1)
Link: https://lore.kernel.org/r/20211130121032.3753852-5-brauner@kernel.org (v2)
Link: https://lore.kernel.org/r/20211203111707.3901969-5-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>
2021-12-03 11:17:01 +00:00
|
|
|
|
|
|
|
if (no_idmapping(mnt_userns, fs_userns))
|
mnt_idmapping: add vfs{g,u}id_t
Introduces new vfs{g,u}id_t types. Similar to k{g,u}id_t the new types
are just simple wrapper structs around regular {g,u}id_t types.
They allows to establish a type safety boundary between {g,u}ids on
idmapped mounts and {g,u}ids as they are represented in filesystems
themselves.
A vfs{g,u}id_t is always created from a k{g,u}id_t, never directly from
a {g,u}id_t as idmapped mounts remap a given {g,u}id according to the
mount's idmapping. This is expressed in the VFS{G,U}IDT_INIT() macros.
A vfs{g,u}id_t may be used as a k{g,u}id_t via AS_K{G,U}IDT(). This
often happens when we need to check whether a {g,u}id mapped according
to an idmapped mount is identical to a given k{g,u}id_t. For an example,
see vfsgid_in_group_p() which determines whether the value of vfsgid_t
matches the value of any of the caller's groups. Similar logic is
expressed in the k{g,u}id_eq_vfs{g,u}id().
The from_vfs{g,u}id() helpers map a given vfs{g,u}id_t from the mount's
idmapping into the filesystem idmapping. They make it possible to update
a filesystem object such as inode->i_{g,u}id with the correct value.
This makes it harder to accidently write a wrong {g,u}id anwywhere. The
vfs{g,u}id_has_fsmapping() helpers check whether a given vfs{g,u}id_t
can be mapped into the filesystem idmapping.
All new helpers are nops on non-idmapped mounts.
I've done work on this roughly 7 months ago but dropped it to focus on
the testsuite. Linus brought this up independently just last week and
it's time to move this along (see [1]).
[1]: https://lore.kernel.org/lkml/CAHk-=win6+ahs1EwLkcq8apqLi_1wXFWbrPf340zYEhObpz4jA@mail.gmail.com
Link: https://lore.kernel.org/r/20220621141454.2914719-2-brauner@kernel.org
Cc: Seth Forshee <sforshee@digitalocean.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Aleksa Sarai <cyphar@cyphar.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
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 (Microsoft) <brauner@kernel.org>
2022-06-21 14:14:47 +00:00
|
|
|
return AS_KGIDT(vfsgid);
|
|
|
|
gid = from_kgid(mnt_userns, AS_KGIDT(vfsgid));
|
|
|
|
if (gid == (gid_t)-1)
|
|
|
|
return INVALID_GID;
|
fs: account for filesystem mappings
Currently we only support idmapped mounts for filesystems mounted
without an idmapping. This was a conscious decision mentioned in
multiple places (cf. e.g. [1]).
As explained at length in [3] it is perfectly fine to extend support for
idmapped mounts to filesystem's mounted with an idmapping should the
need arise. The need has been there for some time now. Various container
projects in userspace need this to run unprivileged and nested
unprivileged containers (cf. [2]).
Before we can port any filesystem that is mountable with an idmapping to
support idmapped mounts we need to first extend the mapping helpers to
account for the filesystem's idmapping. This again, is explained at
length in our documentation at [3] but I'll give an overview here again.
Currently, the low-level mapping helpers implement the remapping
algorithms described in [3] in a simplified manner. Because we could
rely on the fact that all filesystems supporting idmapped mounts are
mounted without an idmapping the translation step from or into the
filesystem idmapping could be skipped.
In order to support idmapped mounts of filesystem's mountable with an
idmapping the translation step we were able to skip before cannot be
skipped anymore. A filesystem mounted with an idmapping is very likely
to not use an identity mapping and will instead use a non-identity
mapping. So the translation step from or into the filesystem's idmapping
in the remapping algorithm cannot be skipped for such filesystems. More
details with examples can be found in [3].
This patch adds a few new and prepares some already existing low-level
mapping helpers to perform the full translation algorithm explained in
[3]. The low-level helpers can be written in a way that they only
perform the additional translation step when the filesystem is indeed
mounted with an idmapping.
If the low-level helpers detect that they are not dealing with an
idmapped mount they can simply return the relevant k{g,u}id unchanged;
no remapping needs to be performed at all. The no_idmapping() helper
detects whether the shortcut can be used.
If the low-level helpers detected that they are dealing with an idmapped
mount but the underlying filesystem is mounted without an idmapping we
can rely on the previous shorcut and can continue to skip the
translation step from or into the filesystem's idmapping.
These checks guarantee that only the minimal amount of work is
performed. As before, if idmapped mounts aren't used the low-level
helpers are idempotent and no work is performed at all.
This patch adds the helpers mapped_k{g,u}id_fs() and
mapped_k{g,u}id_user(). Following patches will port all places to
replace the old k{g,u}id_into_mnt() and k{g,u}id_from_mnt() with these
two new helpers. After the conversion is done k{g,u}id_into_mnt() and
k{g,u}id_from_mnt() will be removed. This also concludes the renaming of
the mapping helpers we started in [4]. Now, all mapping helpers will
started with the "mapped_" prefix making everything nice and consistent.
The mapped_k{g,u}id_fs() helpers replace the k{g,u}id_into_mnt()
helpers. They are to be used when k{g,u}ids are to be mapped from the
vfs, e.g. from from struct inode's i_{g,u}id. Conversely, the
mapped_k{g,u}id_user() helpers replace the k{g,u}id_from_mnt() helpers.
They are to be used when k{g,u}ids are to be written to disk, e.g. when
entering from a system call to change ownership of a file.
This patch only introduces the helpers. It doesn't yet convert the
relevant places to account for filesystem mounted with an idmapping.
[1]: commit 2ca4dcc4909d ("fs/mount_setattr: tighten permission checks")
[2]: https://github.com/containers/podman/issues/10374
[3]: Documentations/filesystems/idmappings.rst
[4]: commit a65e58e791a1 ("fs: document and rename fsid helpers")
Link: https://lore.kernel.org/r/20211123114227.3124056-5-brauner@kernel.org (v1)
Link: https://lore.kernel.org/r/20211130121032.3753852-5-brauner@kernel.org (v2)
Link: https://lore.kernel.org/r/20211203111707.3901969-5-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>
2021-12-03 11:17:01 +00:00
|
|
|
if (initial_idmapping(fs_userns))
|
mnt_idmapping: add vfs{g,u}id_t
Introduces new vfs{g,u}id_t types. Similar to k{g,u}id_t the new types
are just simple wrapper structs around regular {g,u}id_t types.
They allows to establish a type safety boundary between {g,u}ids on
idmapped mounts and {g,u}ids as they are represented in filesystems
themselves.
A vfs{g,u}id_t is always created from a k{g,u}id_t, never directly from
a {g,u}id_t as idmapped mounts remap a given {g,u}id according to the
mount's idmapping. This is expressed in the VFS{G,U}IDT_INIT() macros.
A vfs{g,u}id_t may be used as a k{g,u}id_t via AS_K{G,U}IDT(). This
often happens when we need to check whether a {g,u}id mapped according
to an idmapped mount is identical to a given k{g,u}id_t. For an example,
see vfsgid_in_group_p() which determines whether the value of vfsgid_t
matches the value of any of the caller's groups. Similar logic is
expressed in the k{g,u}id_eq_vfs{g,u}id().
The from_vfs{g,u}id() helpers map a given vfs{g,u}id_t from the mount's
idmapping into the filesystem idmapping. They make it possible to update
a filesystem object such as inode->i_{g,u}id with the correct value.
This makes it harder to accidently write a wrong {g,u}id anwywhere. The
vfs{g,u}id_has_fsmapping() helpers check whether a given vfs{g,u}id_t
can be mapped into the filesystem idmapping.
All new helpers are nops on non-idmapped mounts.
I've done work on this roughly 7 months ago but dropped it to focus on
the testsuite. Linus brought this up independently just last week and
it's time to move this along (see [1]).
[1]: https://lore.kernel.org/lkml/CAHk-=win6+ahs1EwLkcq8apqLi_1wXFWbrPf340zYEhObpz4jA@mail.gmail.com
Link: https://lore.kernel.org/r/20220621141454.2914719-2-brauner@kernel.org
Cc: Seth Forshee <sforshee@digitalocean.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Aleksa Sarai <cyphar@cyphar.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
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 (Microsoft) <brauner@kernel.org>
2022-06-21 14:14:47 +00:00
|
|
|
return KGIDT_INIT(gid);
|
|
|
|
return make_kgid(fs_userns, gid);
|
fs: account for filesystem mappings
Currently we only support idmapped mounts for filesystems mounted
without an idmapping. This was a conscious decision mentioned in
multiple places (cf. e.g. [1]).
As explained at length in [3] it is perfectly fine to extend support for
idmapped mounts to filesystem's mounted with an idmapping should the
need arise. The need has been there for some time now. Various container
projects in userspace need this to run unprivileged and nested
unprivileged containers (cf. [2]).
Before we can port any filesystem that is mountable with an idmapping to
support idmapped mounts we need to first extend the mapping helpers to
account for the filesystem's idmapping. This again, is explained at
length in our documentation at [3] but I'll give an overview here again.
Currently, the low-level mapping helpers implement the remapping
algorithms described in [3] in a simplified manner. Because we could
rely on the fact that all filesystems supporting idmapped mounts are
mounted without an idmapping the translation step from or into the
filesystem idmapping could be skipped.
In order to support idmapped mounts of filesystem's mountable with an
idmapping the translation step we were able to skip before cannot be
skipped anymore. A filesystem mounted with an idmapping is very likely
to not use an identity mapping and will instead use a non-identity
mapping. So the translation step from or into the filesystem's idmapping
in the remapping algorithm cannot be skipped for such filesystems. More
details with examples can be found in [3].
This patch adds a few new and prepares some already existing low-level
mapping helpers to perform the full translation algorithm explained in
[3]. The low-level helpers can be written in a way that they only
perform the additional translation step when the filesystem is indeed
mounted with an idmapping.
If the low-level helpers detect that they are not dealing with an
idmapped mount they can simply return the relevant k{g,u}id unchanged;
no remapping needs to be performed at all. The no_idmapping() helper
detects whether the shortcut can be used.
If the low-level helpers detected that they are dealing with an idmapped
mount but the underlying filesystem is mounted without an idmapping we
can rely on the previous shorcut and can continue to skip the
translation step from or into the filesystem's idmapping.
These checks guarantee that only the minimal amount of work is
performed. As before, if idmapped mounts aren't used the low-level
helpers are idempotent and no work is performed at all.
This patch adds the helpers mapped_k{g,u}id_fs() and
mapped_k{g,u}id_user(). Following patches will port all places to
replace the old k{g,u}id_into_mnt() and k{g,u}id_from_mnt() with these
two new helpers. After the conversion is done k{g,u}id_into_mnt() and
k{g,u}id_from_mnt() will be removed. This also concludes the renaming of
the mapping helpers we started in [4]. Now, all mapping helpers will
started with the "mapped_" prefix making everything nice and consistent.
The mapped_k{g,u}id_fs() helpers replace the k{g,u}id_into_mnt()
helpers. They are to be used when k{g,u}ids are to be mapped from the
vfs, e.g. from from struct inode's i_{g,u}id. Conversely, the
mapped_k{g,u}id_user() helpers replace the k{g,u}id_from_mnt() helpers.
They are to be used when k{g,u}ids are to be written to disk, e.g. when
entering from a system call to change ownership of a file.
This patch only introduces the helpers. It doesn't yet convert the
relevant places to account for filesystem mounted with an idmapping.
[1]: commit 2ca4dcc4909d ("fs/mount_setattr: tighten permission checks")
[2]: https://github.com/containers/podman/issues/10374
[3]: Documentations/filesystems/idmappings.rst
[4]: commit a65e58e791a1 ("fs: document and rename fsid helpers")
Link: https://lore.kernel.org/r/20211123114227.3124056-5-brauner@kernel.org (v1)
Link: https://lore.kernel.org/r/20211130121032.3753852-5-brauner@kernel.org (v2)
Link: https://lore.kernel.org/r/20211203111707.3901969-5-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>
2021-12-03 11:17:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* mapped_kgid_user - map a user kgid into a mnt_userns
|
|
|
|
* @mnt_userns: the mount's idmapping
|
|
|
|
* @fs_userns: the filesystem's idmapping
|
|
|
|
* @kgid : kgid to be mapped
|
|
|
|
*
|
|
|
|
* Use the idmapping of @mnt_userns to remap a @kgid into @fs_userns. Use this
|
|
|
|
* function when preparing a @kgid to be written to disk or inode.
|
|
|
|
*
|
|
|
|
* If no_idmapping() determines that this is not an idmapped mount we can
|
|
|
|
* simply return @kgid unchanged.
|
|
|
|
* If initial_idmapping() tells us that the filesystem is not mounted with an
|
|
|
|
* idmapping we know the value of @kgid won't change when calling
|
|
|
|
* make_kgid() so we can simply retrieve the value via KGIDT_INIT()
|
|
|
|
* directly.
|
|
|
|
*
|
|
|
|
* Return: @kgid mapped according to @mnt_userns.
|
|
|
|
* If @kgid has no mapping in either @mnt_userns or @fs_userns INVALID_GID is
|
|
|
|
* returned.
|
|
|
|
*/
|
|
|
|
static inline kgid_t mapped_kgid_user(struct user_namespace *mnt_userns,
|
|
|
|
struct user_namespace *fs_userns,
|
|
|
|
kgid_t kgid)
|
|
|
|
{
|
mnt_idmapping: add vfs{g,u}id_t
Introduces new vfs{g,u}id_t types. Similar to k{g,u}id_t the new types
are just simple wrapper structs around regular {g,u}id_t types.
They allows to establish a type safety boundary between {g,u}ids on
idmapped mounts and {g,u}ids as they are represented in filesystems
themselves.
A vfs{g,u}id_t is always created from a k{g,u}id_t, never directly from
a {g,u}id_t as idmapped mounts remap a given {g,u}id according to the
mount's idmapping. This is expressed in the VFS{G,U}IDT_INIT() macros.
A vfs{g,u}id_t may be used as a k{g,u}id_t via AS_K{G,U}IDT(). This
often happens when we need to check whether a {g,u}id mapped according
to an idmapped mount is identical to a given k{g,u}id_t. For an example,
see vfsgid_in_group_p() which determines whether the value of vfsgid_t
matches the value of any of the caller's groups. Similar logic is
expressed in the k{g,u}id_eq_vfs{g,u}id().
The from_vfs{g,u}id() helpers map a given vfs{g,u}id_t from the mount's
idmapping into the filesystem idmapping. They make it possible to update
a filesystem object such as inode->i_{g,u}id with the correct value.
This makes it harder to accidently write a wrong {g,u}id anwywhere. The
vfs{g,u}id_has_fsmapping() helpers check whether a given vfs{g,u}id_t
can be mapped into the filesystem idmapping.
All new helpers are nops on non-idmapped mounts.
I've done work on this roughly 7 months ago but dropped it to focus on
the testsuite. Linus brought this up independently just last week and
it's time to move this along (see [1]).
[1]: https://lore.kernel.org/lkml/CAHk-=win6+ahs1EwLkcq8apqLi_1wXFWbrPf340zYEhObpz4jA@mail.gmail.com
Link: https://lore.kernel.org/r/20220621141454.2914719-2-brauner@kernel.org
Cc: Seth Forshee <sforshee@digitalocean.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Aleksa Sarai <cyphar@cyphar.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
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 (Microsoft) <brauner@kernel.org>
2022-06-21 14:14:47 +00:00
|
|
|
return from_vfsgid(mnt_userns, fs_userns, VFSGIDT_INIT(kgid));
|
|
|
|
}
|
fs: account for filesystem mappings
Currently we only support idmapped mounts for filesystems mounted
without an idmapping. This was a conscious decision mentioned in
multiple places (cf. e.g. [1]).
As explained at length in [3] it is perfectly fine to extend support for
idmapped mounts to filesystem's mounted with an idmapping should the
need arise. The need has been there for some time now. Various container
projects in userspace need this to run unprivileged and nested
unprivileged containers (cf. [2]).
Before we can port any filesystem that is mountable with an idmapping to
support idmapped mounts we need to first extend the mapping helpers to
account for the filesystem's idmapping. This again, is explained at
length in our documentation at [3] but I'll give an overview here again.
Currently, the low-level mapping helpers implement the remapping
algorithms described in [3] in a simplified manner. Because we could
rely on the fact that all filesystems supporting idmapped mounts are
mounted without an idmapping the translation step from or into the
filesystem idmapping could be skipped.
In order to support idmapped mounts of filesystem's mountable with an
idmapping the translation step we were able to skip before cannot be
skipped anymore. A filesystem mounted with an idmapping is very likely
to not use an identity mapping and will instead use a non-identity
mapping. So the translation step from or into the filesystem's idmapping
in the remapping algorithm cannot be skipped for such filesystems. More
details with examples can be found in [3].
This patch adds a few new and prepares some already existing low-level
mapping helpers to perform the full translation algorithm explained in
[3]. The low-level helpers can be written in a way that they only
perform the additional translation step when the filesystem is indeed
mounted with an idmapping.
If the low-level helpers detect that they are not dealing with an
idmapped mount they can simply return the relevant k{g,u}id unchanged;
no remapping needs to be performed at all. The no_idmapping() helper
detects whether the shortcut can be used.
If the low-level helpers detected that they are dealing with an idmapped
mount but the underlying filesystem is mounted without an idmapping we
can rely on the previous shorcut and can continue to skip the
translation step from or into the filesystem's idmapping.
These checks guarantee that only the minimal amount of work is
performed. As before, if idmapped mounts aren't used the low-level
helpers are idempotent and no work is performed at all.
This patch adds the helpers mapped_k{g,u}id_fs() and
mapped_k{g,u}id_user(). Following patches will port all places to
replace the old k{g,u}id_into_mnt() and k{g,u}id_from_mnt() with these
two new helpers. After the conversion is done k{g,u}id_into_mnt() and
k{g,u}id_from_mnt() will be removed. This also concludes the renaming of
the mapping helpers we started in [4]. Now, all mapping helpers will
started with the "mapped_" prefix making everything nice and consistent.
The mapped_k{g,u}id_fs() helpers replace the k{g,u}id_into_mnt()
helpers. They are to be used when k{g,u}ids are to be mapped from the
vfs, e.g. from from struct inode's i_{g,u}id. Conversely, the
mapped_k{g,u}id_user() helpers replace the k{g,u}id_from_mnt() helpers.
They are to be used when k{g,u}ids are to be written to disk, e.g. when
entering from a system call to change ownership of a file.
This patch only introduces the helpers. It doesn't yet convert the
relevant places to account for filesystem mounted with an idmapping.
[1]: commit 2ca4dcc4909d ("fs/mount_setattr: tighten permission checks")
[2]: https://github.com/containers/podman/issues/10374
[3]: Documentations/filesystems/idmappings.rst
[4]: commit a65e58e791a1 ("fs: document and rename fsid helpers")
Link: https://lore.kernel.org/r/20211123114227.3124056-5-brauner@kernel.org (v1)
Link: https://lore.kernel.org/r/20211130121032.3753852-5-brauner@kernel.org (v2)
Link: https://lore.kernel.org/r/20211203111707.3901969-5-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>
2021-12-03 11:17:01 +00:00
|
|
|
|
mnt_idmapping: add vfs{g,u}id_t
Introduces new vfs{g,u}id_t types. Similar to k{g,u}id_t the new types
are just simple wrapper structs around regular {g,u}id_t types.
They allows to establish a type safety boundary between {g,u}ids on
idmapped mounts and {g,u}ids as they are represented in filesystems
themselves.
A vfs{g,u}id_t is always created from a k{g,u}id_t, never directly from
a {g,u}id_t as idmapped mounts remap a given {g,u}id according to the
mount's idmapping. This is expressed in the VFS{G,U}IDT_INIT() macros.
A vfs{g,u}id_t may be used as a k{g,u}id_t via AS_K{G,U}IDT(). This
often happens when we need to check whether a {g,u}id mapped according
to an idmapped mount is identical to a given k{g,u}id_t. For an example,
see vfsgid_in_group_p() which determines whether the value of vfsgid_t
matches the value of any of the caller's groups. Similar logic is
expressed in the k{g,u}id_eq_vfs{g,u}id().
The from_vfs{g,u}id() helpers map a given vfs{g,u}id_t from the mount's
idmapping into the filesystem idmapping. They make it possible to update
a filesystem object such as inode->i_{g,u}id with the correct value.
This makes it harder to accidently write a wrong {g,u}id anwywhere. The
vfs{g,u}id_has_fsmapping() helpers check whether a given vfs{g,u}id_t
can be mapped into the filesystem idmapping.
All new helpers are nops on non-idmapped mounts.
I've done work on this roughly 7 months ago but dropped it to focus on
the testsuite. Linus brought this up independently just last week and
it's time to move this along (see [1]).
[1]: https://lore.kernel.org/lkml/CAHk-=win6+ahs1EwLkcq8apqLi_1wXFWbrPf340zYEhObpz4jA@mail.gmail.com
Link: https://lore.kernel.org/r/20220621141454.2914719-2-brauner@kernel.org
Cc: Seth Forshee <sforshee@digitalocean.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Aleksa Sarai <cyphar@cyphar.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
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 (Microsoft) <brauner@kernel.org>
2022-06-21 14:14:47 +00:00
|
|
|
/**
|
|
|
|
* vfsgid_has_fsmapping - check whether a vfsgid maps into the filesystem
|
|
|
|
* @mnt_userns: the mount's idmapping
|
|
|
|
* @fs_userns: the filesystem's idmapping
|
|
|
|
* @vfsgid: vfsgid to be mapped
|
|
|
|
*
|
|
|
|
* Check whether @vfsgid has a mapping in the filesystem idmapping. Use this
|
|
|
|
* function to check whether the filesystem idmapping has a mapping for
|
|
|
|
* @vfsgid.
|
|
|
|
*
|
|
|
|
* Return: true if @vfsgid has a mapping in the filesystem, false if not.
|
|
|
|
*/
|
|
|
|
static inline bool vfsgid_has_fsmapping(struct user_namespace *mnt_userns,
|
|
|
|
struct user_namespace *fs_userns,
|
|
|
|
vfsgid_t vfsgid)
|
|
|
|
{
|
|
|
|
return gid_valid(from_vfsgid(mnt_userns, fs_userns, vfsgid));
|
fs: account for filesystem mappings
Currently we only support idmapped mounts for filesystems mounted
without an idmapping. This was a conscious decision mentioned in
multiple places (cf. e.g. [1]).
As explained at length in [3] it is perfectly fine to extend support for
idmapped mounts to filesystem's mounted with an idmapping should the
need arise. The need has been there for some time now. Various container
projects in userspace need this to run unprivileged and nested
unprivileged containers (cf. [2]).
Before we can port any filesystem that is mountable with an idmapping to
support idmapped mounts we need to first extend the mapping helpers to
account for the filesystem's idmapping. This again, is explained at
length in our documentation at [3] but I'll give an overview here again.
Currently, the low-level mapping helpers implement the remapping
algorithms described in [3] in a simplified manner. Because we could
rely on the fact that all filesystems supporting idmapped mounts are
mounted without an idmapping the translation step from or into the
filesystem idmapping could be skipped.
In order to support idmapped mounts of filesystem's mountable with an
idmapping the translation step we were able to skip before cannot be
skipped anymore. A filesystem mounted with an idmapping is very likely
to not use an identity mapping and will instead use a non-identity
mapping. So the translation step from or into the filesystem's idmapping
in the remapping algorithm cannot be skipped for such filesystems. More
details with examples can be found in [3].
This patch adds a few new and prepares some already existing low-level
mapping helpers to perform the full translation algorithm explained in
[3]. The low-level helpers can be written in a way that they only
perform the additional translation step when the filesystem is indeed
mounted with an idmapping.
If the low-level helpers detect that they are not dealing with an
idmapped mount they can simply return the relevant k{g,u}id unchanged;
no remapping needs to be performed at all. The no_idmapping() helper
detects whether the shortcut can be used.
If the low-level helpers detected that they are dealing with an idmapped
mount but the underlying filesystem is mounted without an idmapping we
can rely on the previous shorcut and can continue to skip the
translation step from or into the filesystem's idmapping.
These checks guarantee that only the minimal amount of work is
performed. As before, if idmapped mounts aren't used the low-level
helpers are idempotent and no work is performed at all.
This patch adds the helpers mapped_k{g,u}id_fs() and
mapped_k{g,u}id_user(). Following patches will port all places to
replace the old k{g,u}id_into_mnt() and k{g,u}id_from_mnt() with these
two new helpers. After the conversion is done k{g,u}id_into_mnt() and
k{g,u}id_from_mnt() will be removed. This also concludes the renaming of
the mapping helpers we started in [4]. Now, all mapping helpers will
started with the "mapped_" prefix making everything nice and consistent.
The mapped_k{g,u}id_fs() helpers replace the k{g,u}id_into_mnt()
helpers. They are to be used when k{g,u}ids are to be mapped from the
vfs, e.g. from from struct inode's i_{g,u}id. Conversely, the
mapped_k{g,u}id_user() helpers replace the k{g,u}id_from_mnt() helpers.
They are to be used when k{g,u}ids are to be written to disk, e.g. when
entering from a system call to change ownership of a file.
This patch only introduces the helpers. It doesn't yet convert the
relevant places to account for filesystem mounted with an idmapping.
[1]: commit 2ca4dcc4909d ("fs/mount_setattr: tighten permission checks")
[2]: https://github.com/containers/podman/issues/10374
[3]: Documentations/filesystems/idmappings.rst
[4]: commit a65e58e791a1 ("fs: document and rename fsid helpers")
Link: https://lore.kernel.org/r/20211123114227.3124056-5-brauner@kernel.org (v1)
Link: https://lore.kernel.org/r/20211130121032.3753852-5-brauner@kernel.org (v2)
Link: https://lore.kernel.org/r/20211203111707.3901969-5-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>
2021-12-03 11:17:01 +00:00
|
|
|
}
|
|
|
|
|
2021-12-03 11:16:59 +00:00
|
|
|
/**
|
|
|
|
* mapped_fsuid - return caller's fsuid mapped up into a mnt_userns
|
fs: account for filesystem mappings
Currently we only support idmapped mounts for filesystems mounted
without an idmapping. This was a conscious decision mentioned in
multiple places (cf. e.g. [1]).
As explained at length in [3] it is perfectly fine to extend support for
idmapped mounts to filesystem's mounted with an idmapping should the
need arise. The need has been there for some time now. Various container
projects in userspace need this to run unprivileged and nested
unprivileged containers (cf. [2]).
Before we can port any filesystem that is mountable with an idmapping to
support idmapped mounts we need to first extend the mapping helpers to
account for the filesystem's idmapping. This again, is explained at
length in our documentation at [3] but I'll give an overview here again.
Currently, the low-level mapping helpers implement the remapping
algorithms described in [3] in a simplified manner. Because we could
rely on the fact that all filesystems supporting idmapped mounts are
mounted without an idmapping the translation step from or into the
filesystem idmapping could be skipped.
In order to support idmapped mounts of filesystem's mountable with an
idmapping the translation step we were able to skip before cannot be
skipped anymore. A filesystem mounted with an idmapping is very likely
to not use an identity mapping and will instead use a non-identity
mapping. So the translation step from or into the filesystem's idmapping
in the remapping algorithm cannot be skipped for such filesystems. More
details with examples can be found in [3].
This patch adds a few new and prepares some already existing low-level
mapping helpers to perform the full translation algorithm explained in
[3]. The low-level helpers can be written in a way that they only
perform the additional translation step when the filesystem is indeed
mounted with an idmapping.
If the low-level helpers detect that they are not dealing with an
idmapped mount they can simply return the relevant k{g,u}id unchanged;
no remapping needs to be performed at all. The no_idmapping() helper
detects whether the shortcut can be used.
If the low-level helpers detected that they are dealing with an idmapped
mount but the underlying filesystem is mounted without an idmapping we
can rely on the previous shorcut and can continue to skip the
translation step from or into the filesystem's idmapping.
These checks guarantee that only the minimal amount of work is
performed. As before, if idmapped mounts aren't used the low-level
helpers are idempotent and no work is performed at all.
This patch adds the helpers mapped_k{g,u}id_fs() and
mapped_k{g,u}id_user(). Following patches will port all places to
replace the old k{g,u}id_into_mnt() and k{g,u}id_from_mnt() with these
two new helpers. After the conversion is done k{g,u}id_into_mnt() and
k{g,u}id_from_mnt() will be removed. This also concludes the renaming of
the mapping helpers we started in [4]. Now, all mapping helpers will
started with the "mapped_" prefix making everything nice and consistent.
The mapped_k{g,u}id_fs() helpers replace the k{g,u}id_into_mnt()
helpers. They are to be used when k{g,u}ids are to be mapped from the
vfs, e.g. from from struct inode's i_{g,u}id. Conversely, the
mapped_k{g,u}id_user() helpers replace the k{g,u}id_from_mnt() helpers.
They are to be used when k{g,u}ids are to be written to disk, e.g. when
entering from a system call to change ownership of a file.
This patch only introduces the helpers. It doesn't yet convert the
relevant places to account for filesystem mounted with an idmapping.
[1]: commit 2ca4dcc4909d ("fs/mount_setattr: tighten permission checks")
[2]: https://github.com/containers/podman/issues/10374
[3]: Documentations/filesystems/idmappings.rst
[4]: commit a65e58e791a1 ("fs: document and rename fsid helpers")
Link: https://lore.kernel.org/r/20211123114227.3124056-5-brauner@kernel.org (v1)
Link: https://lore.kernel.org/r/20211130121032.3753852-5-brauner@kernel.org (v2)
Link: https://lore.kernel.org/r/20211203111707.3901969-5-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>
2021-12-03 11:17:01 +00:00
|
|
|
* @mnt_userns: the mount's idmapping
|
2021-12-03 11:17:05 +00:00
|
|
|
* @fs_userns: the filesystem's idmapping
|
2021-12-03 11:16:59 +00:00
|
|
|
*
|
|
|
|
* Use this helper to initialize a new vfs or filesystem object based on
|
|
|
|
* the caller's fsuid. A common example is initializing the i_uid field of
|
|
|
|
* a newly allocated inode triggered by a creation event such as mkdir or
|
|
|
|
* O_CREAT. Other examples include the allocation of quotas for a specific
|
|
|
|
* user.
|
|
|
|
*
|
|
|
|
* Return: the caller's current fsuid mapped up according to @mnt_userns.
|
|
|
|
*/
|
2021-12-03 11:17:05 +00:00
|
|
|
static inline kuid_t mapped_fsuid(struct user_namespace *mnt_userns,
|
|
|
|
struct user_namespace *fs_userns)
|
2021-12-03 11:16:59 +00:00
|
|
|
{
|
2021-12-03 11:17:05 +00:00
|
|
|
return mapped_kuid_user(mnt_userns, fs_userns, current_fsuid());
|
2021-12-03 11:16:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* mapped_fsgid - return caller's fsgid mapped up into a mnt_userns
|
fs: account for filesystem mappings
Currently we only support idmapped mounts for filesystems mounted
without an idmapping. This was a conscious decision mentioned in
multiple places (cf. e.g. [1]).
As explained at length in [3] it is perfectly fine to extend support for
idmapped mounts to filesystem's mounted with an idmapping should the
need arise. The need has been there for some time now. Various container
projects in userspace need this to run unprivileged and nested
unprivileged containers (cf. [2]).
Before we can port any filesystem that is mountable with an idmapping to
support idmapped mounts we need to first extend the mapping helpers to
account for the filesystem's idmapping. This again, is explained at
length in our documentation at [3] but I'll give an overview here again.
Currently, the low-level mapping helpers implement the remapping
algorithms described in [3] in a simplified manner. Because we could
rely on the fact that all filesystems supporting idmapped mounts are
mounted without an idmapping the translation step from or into the
filesystem idmapping could be skipped.
In order to support idmapped mounts of filesystem's mountable with an
idmapping the translation step we were able to skip before cannot be
skipped anymore. A filesystem mounted with an idmapping is very likely
to not use an identity mapping and will instead use a non-identity
mapping. So the translation step from or into the filesystem's idmapping
in the remapping algorithm cannot be skipped for such filesystems. More
details with examples can be found in [3].
This patch adds a few new and prepares some already existing low-level
mapping helpers to perform the full translation algorithm explained in
[3]. The low-level helpers can be written in a way that they only
perform the additional translation step when the filesystem is indeed
mounted with an idmapping.
If the low-level helpers detect that they are not dealing with an
idmapped mount they can simply return the relevant k{g,u}id unchanged;
no remapping needs to be performed at all. The no_idmapping() helper
detects whether the shortcut can be used.
If the low-level helpers detected that they are dealing with an idmapped
mount but the underlying filesystem is mounted without an idmapping we
can rely on the previous shorcut and can continue to skip the
translation step from or into the filesystem's idmapping.
These checks guarantee that only the minimal amount of work is
performed. As before, if idmapped mounts aren't used the low-level
helpers are idempotent and no work is performed at all.
This patch adds the helpers mapped_k{g,u}id_fs() and
mapped_k{g,u}id_user(). Following patches will port all places to
replace the old k{g,u}id_into_mnt() and k{g,u}id_from_mnt() with these
two new helpers. After the conversion is done k{g,u}id_into_mnt() and
k{g,u}id_from_mnt() will be removed. This also concludes the renaming of
the mapping helpers we started in [4]. Now, all mapping helpers will
started with the "mapped_" prefix making everything nice and consistent.
The mapped_k{g,u}id_fs() helpers replace the k{g,u}id_into_mnt()
helpers. They are to be used when k{g,u}ids are to be mapped from the
vfs, e.g. from from struct inode's i_{g,u}id. Conversely, the
mapped_k{g,u}id_user() helpers replace the k{g,u}id_from_mnt() helpers.
They are to be used when k{g,u}ids are to be written to disk, e.g. when
entering from a system call to change ownership of a file.
This patch only introduces the helpers. It doesn't yet convert the
relevant places to account for filesystem mounted with an idmapping.
[1]: commit 2ca4dcc4909d ("fs/mount_setattr: tighten permission checks")
[2]: https://github.com/containers/podman/issues/10374
[3]: Documentations/filesystems/idmappings.rst
[4]: commit a65e58e791a1 ("fs: document and rename fsid helpers")
Link: https://lore.kernel.org/r/20211123114227.3124056-5-brauner@kernel.org (v1)
Link: https://lore.kernel.org/r/20211130121032.3753852-5-brauner@kernel.org (v2)
Link: https://lore.kernel.org/r/20211203111707.3901969-5-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>
2021-12-03 11:17:01 +00:00
|
|
|
* @mnt_userns: the mount's idmapping
|
2021-12-03 11:17:05 +00:00
|
|
|
* @fs_userns: the filesystem's idmapping
|
2021-12-03 11:16:59 +00:00
|
|
|
*
|
|
|
|
* Use this helper to initialize a new vfs or filesystem object based on
|
|
|
|
* the caller's fsgid. A common example is initializing the i_gid field of
|
|
|
|
* a newly allocated inode triggered by a creation event such as mkdir or
|
|
|
|
* O_CREAT. Other examples include the allocation of quotas for a specific
|
|
|
|
* user.
|
|
|
|
*
|
|
|
|
* Return: the caller's current fsgid mapped up according to @mnt_userns.
|
|
|
|
*/
|
2021-12-03 11:17:05 +00:00
|
|
|
static inline kgid_t mapped_fsgid(struct user_namespace *mnt_userns,
|
|
|
|
struct user_namespace *fs_userns)
|
2021-12-03 11:16:59 +00:00
|
|
|
{
|
2021-12-03 11:17:05 +00:00
|
|
|
return mapped_kgid_user(mnt_userns, fs_userns, current_fsgid());
|
2021-12-03 11:16:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* _LINUX_MNT_IDMAPPING_H */
|