]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 10 Oct 2023 16:14:49 +0000 (18:14 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 10 Oct 2023 16:14:49 +0000 (18:14 +0200)
added patches:
btrfs-file_remove_privs-needs-an-exclusive-lock-in-direct-io-write.patch

queue-6.1/btrfs-file_remove_privs-needs-an-exclusive-lock-in-direct-io-write.patch [new file with mode: 0644]
queue-6.1/series

diff --git a/queue-6.1/btrfs-file_remove_privs-needs-an-exclusive-lock-in-direct-io-write.patch b/queue-6.1/btrfs-file_remove_privs-needs-an-exclusive-lock-in-direct-io-write.patch
new file mode 100644 (file)
index 0000000..aa354a7
--- /dev/null
@@ -0,0 +1,59 @@
+From 9af86694fd5d387992699ec99007ed374966ce9a Mon Sep 17 00:00:00 2001
+From: Bernd Schubert <bschubert@ddn.com>
+Date: Wed, 6 Sep 2023 17:59:03 +0200
+Subject: btrfs: file_remove_privs needs an exclusive lock in direct io write
+
+From: Bernd Schubert <bschubert@ddn.com>
+
+commit 9af86694fd5d387992699ec99007ed374966ce9a upstream.
+
+This was noticed by Miklos that file_remove_privs might call into
+notify_change(), which requires to hold an exclusive lock. The problem
+exists in FUSE and btrfs. We can fix it without any additional helpers
+from VFS, in case the privileges would need to be dropped, change the
+lock type to be exclusive and redo the loop.
+
+Fixes: e9adabb9712e ("btrfs: use shared lock for direct writes within EOF")
+CC: Miklos Szeredi <miklos@szeredi.hu>
+CC: stable@vger.kernel.org # 5.15+
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Bernd Schubert <bschubert@ddn.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/file.c |   16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+--- a/fs/btrfs/file.c
++++ b/fs/btrfs/file.c
+@@ -1458,8 +1458,13 @@ static ssize_t btrfs_direct_write(struct
+       if (iocb->ki_flags & IOCB_NOWAIT)
+               ilock_flags |= BTRFS_ILOCK_TRY;
+-      /* If the write DIO is within EOF, use a shared lock */
+-      if (iocb->ki_pos + iov_iter_count(from) <= i_size_read(inode))
++      /*
++       * If the write DIO is within EOF, use a shared lock and also only if
++       * security bits will likely not be dropped by file_remove_privs() called
++       * from btrfs_write_check(). Either will need to be rechecked after the
++       * lock was acquired.
++       */
++      if (iocb->ki_pos + iov_iter_count(from) <= i_size_read(inode) && IS_NOSEC(inode))
+               ilock_flags |= BTRFS_ILOCK_SHARED;
+ relock:
+@@ -1467,6 +1472,13 @@ relock:
+       if (err < 0)
+               return err;
++      /* Shared lock cannot be used with security bits set. */
++      if ((ilock_flags & BTRFS_ILOCK_SHARED) && !IS_NOSEC(inode)) {
++              btrfs_inode_unlock(inode, ilock_flags);
++              ilock_flags &= ~BTRFS_ILOCK_SHARED;
++              goto relock;
++      }
++
+       err = generic_write_checks(iocb, from);
+       if (err <= 0) {
+               btrfs_inode_unlock(inode, ilock_flags);
index 61ea34a623b67eaf3230d95c93cee57192830e5e..bd999669daec0351febf6e33786e54f4b518e7a7 100644 (file)
@@ -151,3 +151,4 @@ vrf-fix-lockdep-splat-in-output-path.patch
 btrfs-fix-an-error-handling-path-in-btrfs_rename.patch
 btrfs-fix-fscrypt-name-leak-after-failure-to-join-log-transaction.patch
 netlink-remove-the-flex-array-from-struct-nlmsghdr.patch
+btrfs-file_remove_privs-needs-an-exclusive-lock-in-direct-io-write.patch