diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-05-25 04:19:06 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-05-25 04:19:06 +0300 |
commit | f30fabe78acb31cd309f2fdfdb0be54df4cad68f (patch) | |
tree | 24e43ea294fd023120f6ae28d5ff4b45ced0e292 | |
parent | 827060261cf3c7b79ee7185d5aa61c851beb9403 (diff) | |
parent | e1bbcd277a53e08d619ffeec56c5c9287f2bf42f (diff) | |
download | linux-f30fabe78acb31cd309f2fdfdb0be54df4cad68f.tar.xz |
Merge tag 'fs.idmapped.v5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux
Pull fs idmapping updates from Christian Brauner:
"This contains two minor updates:
- An update to the idmapping documentation by Rodrigo making it
easier to understand that we first introduce several use-cases that
fail without idmapped mounts simply to explain how they can be
handled with idmapped mounts.
- When changing a mount's idmapping we now hold writers to make it
more robust.
This is similar to turning a mount ro with the difference that in
contrast to turning a mount ro changing the idmapping can only ever
be done once while a mount can transition between ro and rw as much
as it wants.
The vfs layer itself takes care to retrieve the idmapping of a
mount once ensuring that the idmapping used for vfs permission
checking is identical to the idmapping passed down to the
filesystem. All filesystems with FS_ALLOW_IDMAP raised take the
same precautions as the vfs in code-paths that are outside of
direct control of the vfs such as ioctl()s.
However, holding writers makes this more robust and predictable for
both the kernel and userspace.
This is a minor user-visible change. But it is extremely unlikely
to matter. The caller must've created a detached mount via
OPEN_TREE_CLONE and then handed that O_PATH fd to another process
or thread which then must've gotten a writable fd for that mount
and started creating files in there while the caller is still
changing mount properties. While not impossible it will be an
extremely rare corner-case and should in general be considered a
bug in the application. Consider making a mount MOUNT_ATTR_NOEXEC
or MOUNT_ATTR_NODEV while allowing someone else to perform lookups
or exec'ing in parallel by handing them a copy of the
OPEN_TREE_CLONE fd or another fd beneath that mount.
I've pinged all major users of idmapped mounts pointing out this
change and none of them have active writers on a mount while still
changing mount properties. It would've been strange if they did.
The rest and majority of the work will be coming through the overlayfs
tree this cycle. In addition to overlayfs this cycle should also see
support for idmapped mounts on erofs as I've acked a patch to this
effect a little while ago"
* tag 'fs.idmapped.v5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux:
fs: hold writers when changing mount's idmapping
docs: Add small intro to idmap examples
-rw-r--r-- | Documentation/filesystems/idmappings.rst | 5 | ||||
-rw-r--r-- | fs/namespace.c | 5 |
2 files changed, 8 insertions, 2 deletions
diff --git a/Documentation/filesystems/idmappings.rst b/Documentation/filesystems/idmappings.rst index 7a879ec3b6bf..c1db8748389c 100644 --- a/Documentation/filesystems/idmappings.rst +++ b/Documentation/filesystems/idmappings.rst @@ -369,6 +369,11 @@ kernel maps the caller's userspace id down into a kernel id according to the caller's idmapping and then maps that kernel id up according to the filesystem's idmapping. +Let's see some examples with caller/filesystem idmapping but without mount +idmappings. This will exhibit some problems we can hit. After that we will +revisit/reconsider these examples, this time using mount idmappings, to see how +they can solve the problems we observed before. + Example 1 ~~~~~~~~~ diff --git a/fs/namespace.c b/fs/namespace.c index afe2b64b14f1..41461f55c039 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -4026,8 +4026,9 @@ static int can_idmap_mount(const struct mount_kattr *kattr, struct mount *mnt) static inline bool mnt_allow_writers(const struct mount_kattr *kattr, const struct mount *mnt) { - return !(kattr->attr_set & MNT_READONLY) || - (mnt->mnt.mnt_flags & MNT_READONLY); + return (!(kattr->attr_set & MNT_READONLY) || + (mnt->mnt.mnt_flags & MNT_READONLY)) && + !kattr->mnt_userns; } static int mount_setattr_prepare(struct mount_kattr *kattr, struct mount *mnt) |