]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 15 Mar 2023 11:36:52 +0000 (12:36 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 15 Mar 2023 11:36:52 +0000 (12:36 +0100)
added patches:
fs-hold-writers-when-changing-mount-s-idmapping.patch

queue-5.15/fs-hold-writers-when-changing-mount-s-idmapping.patch [new file with mode: 0644]
queue-5.15/series

diff --git a/queue-5.15/fs-hold-writers-when-changing-mount-s-idmapping.patch b/queue-5.15/fs-hold-writers-when-changing-mount-s-idmapping.patch
new file mode 100644 (file)
index 0000000..aebe7f5
--- /dev/null
@@ -0,0 +1,100 @@
+From e1bbcd277a53e08d619ffeec56c5c9287f2bf42f Mon Sep 17 00:00:00 2001
+From: Christian Brauner <christian.brauner@ubuntu.com>
+Date: Tue, 10 May 2022 11:58:40 +0200
+Subject: fs: hold writers when changing mount's idmapping
+
+From: Christian Brauner <christian.brauner@ubuntu.com>
+
+commit e1bbcd277a53e08d619ffeec56c5c9287f2bf42f upstream.
+
+Hold writers when changing a mount's idmapping to make it more robust.
+
+The vfs layer 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.
+
+For ioctl codepaths the filesystem itself is responsible for taking the
+idmapping into account if they need to. While all filesystems with
+FS_ALLOW_IDMAP raised take the same precautions as the vfs we should
+enforce it explicitly by making sure there are no active writers on the
+relevant mount while changing the idmapping.
+
+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.
+
+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.
+
+Link: https://lore.kernel.org/r/20220510095840.152264-1-brauner@kernel.org
+Cc: Seth Forshee <seth.forshee@digitalocean.com>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Cc: linux-fsdevel@vger.kernel.org
+Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/namespace.c |   29 ++++++++++++++++++++---------
+ 1 file changed, 20 insertions(+), 9 deletions(-)
+
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -3968,6 +3968,23 @@ static int can_idmap_mount(const struct
+       return 0;
+ }
++/**
++ * mnt_allow_writers() - check whether the attribute change allows writers
++ * @kattr: the new mount attributes
++ * @mnt: the mount to which @kattr will be applied
++ *
++ * Check whether thew new mount attributes in @kattr allow concurrent writers.
++ *
++ * Return: true if writers need to be held, false if not
++ */
++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)) &&
++             !kattr->mnt_userns;
++}
++
+ static struct mount *mount_setattr_prepare(struct mount_kattr *kattr,
+                                          struct mount *mnt, int *err)
+ {
+@@ -3998,8 +4015,7 @@ static struct mount *mount_setattr_prepa
+               last = m;
+-              if ((kattr->attr_set & MNT_READONLY) &&
+-                  !(m->mnt.mnt_flags & MNT_READONLY)) {
++              if (!mnt_allow_writers(kattr, m)) {
+                       *err = mnt_hold_writers(m);
+                       if (*err)
+                               goto out;
+@@ -4050,13 +4066,8 @@ static void mount_setattr_commit(struct
+                       WRITE_ONCE(m->mnt.mnt_flags, flags);
+               }
+-              /*
+-               * We either set MNT_READONLY above so make it visible
+-               * before ~MNT_WRITE_HOLD or we failed to recursively
+-               * apply mount options.
+-               */
+-              if ((kattr->attr_set & MNT_READONLY) &&
+-                  (m->mnt.mnt_flags & MNT_WRITE_HOLD))
++              /* If we had to hold writers unblock them. */
++              if (m->mnt.mnt_flags & MNT_WRITE_HOLD)
+                       mnt_unhold_writers(m);
+               if (!err && kattr->propagation)
index 28136261ccaa381f01f440fc3110e3438f38b23e..cc23ab7f6ab9682e361878e53eda90c4be2ec727 100644 (file)
@@ -139,3 +139,4 @@ tools-bpftool-fix-compilation-error-with-new-binutils.patch
 kvm-fix-memoryleak-in-kvm_init.patch
 xfs-remove-xfs_setattr_time-declaration.patch
 uml-define-runtime_discard_exit.patch
+fs-hold-writers-when-changing-mount-s-idmapping.patch