]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
7.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 22 Jun 2026 09:01:40 +0000 (11:01 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 22 Jun 2026 09:01:40 +0000 (11:01 +0200)
added patches:
fuse-re-lock-request-before-replacing-page-cache-folio.patch

queue-7.1/fuse-re-lock-request-before-replacing-page-cache-folio.patch [new file with mode: 0644]
queue-7.1/series

diff --git a/queue-7.1/fuse-re-lock-request-before-replacing-page-cache-folio.patch b/queue-7.1/fuse-re-lock-request-before-replacing-page-cache-folio.patch
new file mode 100644 (file)
index 0000000..47737cf
--- /dev/null
@@ -0,0 +1,67 @@
+From a078484921052d0badd827fcc2770b5cfc1d4120 Mon Sep 17 00:00:00 2001
+From: Joanne Koong <joannelkoong@gmail.com>
+Date: Mon, 18 May 2026 22:28:06 -0700
+Subject: fuse: re-lock request before replacing page cache folio
+
+From: Joanne Koong <joannelkoong@gmail.com>
+
+commit a078484921052d0badd827fcc2770b5cfc1d4120 upstream.
+
+fuse_try_move_folio() unlocks the request on entry but does not
+re-lock it on the success path. This means fuse_chan_abort() can end the
+request and free the fuse_io_args (eg fuse_readpages_end()) while the
+subsequent copy chain logic after fuse_try_move_folio() accesses the
+fuse_io_args, leading to use-after-free issues.
+
+Fix this by calling lock_request() before replace_page_cache_folio().
+This ensures the request is locked on the success path which will
+prevent the fuse_io_args from being freed while the later copying logic
+runs, and also ensures that the ap->folios[i]->mapping is never null
+since ap->folios[i] will always point to the newfolio after
+replace_page_cache_folio().
+
+Fixes: ce534fb05292 ("fuse: allow splice to move pages")
+Cc: stable@vger.kernel.org
+Reported-by: Lei Lu <llfamsec@gmail.com>
+Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/fuse/dev.c |   19 +++++--------------
+ 1 file changed, 5 insertions(+), 14 deletions(-)
+
+--- a/fs/fuse/dev.c
++++ b/fs/fuse/dev.c
+@@ -1037,6 +1037,10 @@ static int fuse_try_move_folio(struct fu
+       if (WARN_ON(folio_test_mlocked(oldfolio)))
+               goto out_fallback_unlock;
++      err = lock_request(cs->req);
++      if (err)
++              goto out_fallback_unlock;
++
+       replace_page_cache_folio(oldfolio, newfolio);
+       folio_get(newfolio);
+@@ -1050,20 +1054,7 @@ static int fuse_try_move_folio(struct fu
+        */
+       pipe_buf_release(cs->pipe, buf);
+-      err = 0;
+-      spin_lock(&cs->req->waitq.lock);
+-      if (test_bit(FR_ABORTED, &cs->req->flags))
+-              err = -ENOENT;
+-      else
+-              *foliop = newfolio;
+-      spin_unlock(&cs->req->waitq.lock);
+-
+-      if (err) {
+-              folio_unlock(newfolio);
+-              folio_put(newfolio);
+-              goto out_put_old;
+-      }
+-
++      *foliop = newfolio;
+       folio_unlock(oldfolio);
+       /* Drop ref for ap->pages[] array */
+       folio_put(oldfolio);
index 7dd13f0fed9373223dd14cf81f9015d527689547..cc7e8535e22c997f00c77a9a83d6c64563237786 100644 (file)
@@ -1 +1,2 @@
 io_uring-net-avoid-msghdr-on-op_connect-op_bind-asyn.patch
+fuse-re-lock-request-before-replacing-page-cache-folio.patch