From: Greg Kroah-Hartman Date: Mon, 22 Jun 2026 09:01:31 +0000 (+0200) Subject: 7.0-stable patches X-Git-Tag: v6.18.37~51 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=747cdb8270086f3f30aa71c6d643edacad0caafc;p=thirdparty%2Fkernel%2Fstable-queue.git 7.0-stable patches added patches: fuse-re-lock-request-before-replacing-page-cache-folio.patch --- diff --git a/queue-7.0/fuse-re-lock-request-before-replacing-page-cache-folio.patch b/queue-7.0/fuse-re-lock-request-before-replacing-page-cache-folio.patch new file mode 100644 index 0000000000..47737cfaf9 --- /dev/null +++ b/queue-7.0/fuse-re-lock-request-before-replacing-page-cache-folio.patch @@ -0,0 +1,67 @@ +From a078484921052d0badd827fcc2770b5cfc1d4120 Mon Sep 17 00:00:00 2001 +From: Joanne Koong +Date: Mon, 18 May 2026 22:28:06 -0700 +Subject: fuse: re-lock request before replacing page cache folio + +From: Joanne Koong + +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 +Signed-off-by: Joanne Koong +Signed-off-by: Miklos Szeredi +Signed-off-by: Greg Kroah-Hartman +--- + 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); diff --git a/queue-7.0/series b/queue-7.0/series index 1940111452..bb6f1e3399 100644 --- a/queue-7.0/series +++ b/queue-7.0/series @@ -6,3 +6,4 @@ firmware-exynos-acpm-count-acpm_xfer-buffers-with-__counted_by_ptr.patch firmware-samsung-acpm-fix-cross-thread-rx-length-corruption.patch firmware-samsung-acpm-fix-false-timeouts-and-use-after-free-in-polling.patch firmware-samsung-acpm-fix-missing-lkmm-barriers-in-sequence-allocator.patch +fuse-re-lock-request-before-replacing-page-cache-folio.patch