]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.12-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 16 Jul 2026 13:11:02 +0000 (15:11 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 16 Jul 2026 13:11:02 +0000 (15:11 +0200)
added patches:
fuse-clear-intr_entry-in-fuse_resend-and-fuse_remove_pending_req.patch
fuse-fix-device-node-leak-in-cuse_process_init_reply.patch
fuse-re-lock-request-before-returning-from-fuse_ref_folio.patch

queue-6.12/fuse-clear-intr_entry-in-fuse_resend-and-fuse_remove_pending_req.patch [new file with mode: 0644]
queue-6.12/fuse-fix-device-node-leak-in-cuse_process_init_reply.patch [new file with mode: 0644]
queue-6.12/fuse-re-lock-request-before-returning-from-fuse_ref_folio.patch [new file with mode: 0644]
queue-6.12/series

diff --git a/queue-6.12/fuse-clear-intr_entry-in-fuse_resend-and-fuse_remove_pending_req.patch b/queue-6.12/fuse-clear-intr_entry-in-fuse_resend-and-fuse_remove_pending_req.patch
new file mode 100644 (file)
index 0000000..8ba107c
--- /dev/null
@@ -0,0 +1,61 @@
+From f8fce75fedf73ac72aa09163deb8f4291fdcaad2 Mon Sep 17 00:00:00 2001
+From: Ji'an Zhou <eilaimemedsnaimel@gmail.com>
+Date: Tue, 9 Jun 2026 09:58:51 +0000
+Subject: fuse: clear intr_entry in fuse_resend and fuse_remove_pending_req
+
+From: Ji'an Zhou <eilaimemedsnaimel@gmail.com>
+
+commit f8fce75fedf73ac72aa09163deb8f4291fdcaad2 upstream.
+
+When fuse_resend() moves a request from fpq->processing back to
+fiq->pending, it sets FR_PENDING and clears FR_SENT but does not
+remove the requests intr_entry from fiq->interrupts.  If the
+request had FR_INTERRUPTED set from a prior signal, intr_entry
+remains dangling on fiq->interrupts.  When the requesting task
+then receives a fatal signal, fuse_remove_pending_req() sees
+FR_PENDING=1, removes the request from fiq->pending and frees it
+via the refcount path, also without cleaning intr_entry.  The
+stale intr_entry causes use-after-free when fuse_read_interrupt()
+iterates fiq->interrupts:
+  - list_del_init(&req->intr_entry) -> UAF write on freed slab
+  - req->in.h.unique -> UAF read, data leaked to userspace
+
+Remove intr_entry from fiq->interrupts in fuse_resend() for
+interrupted requests before they are placed back on fiq->pending.
+
+Add a WARN_ON if the intr_entry is not empty on request destruction.
+
+Fixes: 760eac73f9f6 ("fuse: Introduce a new notification type for resend pending requests")
+Cc: stable@vger.kernel.org # 6.9
+Signed-off-by: Ji'an Zhou <eilaimemedsnaimel@gmail.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/fuse/dev.c |    9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/fs/fuse/dev.c
++++ b/fs/fuse/dev.c
+@@ -66,6 +66,7 @@ static struct fuse_req *fuse_request_all
+ static void fuse_request_free(struct fuse_req *req)
+ {
++      WARN_ON(!list_empty(&req->intr_entry));
+       kmem_cache_free(fuse_req_cachep, req);
+ }
+@@ -1881,6 +1882,14 @@ static void fuse_resend(struct fuse_conn
+               end_requests(&to_queue);
+               return;
+       }
++      /*
++       * Remove interrupt entries for resent requests to prevent stale
++       * intr_entry on fiq->interrupts after the request is re-queued.
++       */
++      list_for_each_entry(req, &to_queue, list) {
++              if (test_bit(FR_INTERRUPTED, &req->flags))
++                      list_del_init(&req->intr_entry);
++      }
+       /* iq and pq requests are both oldest to newest */
+       list_splice(&to_queue, &fiq->pending);
+       fuse_dev_wake_and_unlock(fiq);
diff --git a/queue-6.12/fuse-fix-device-node-leak-in-cuse_process_init_reply.patch b/queue-6.12/fuse-fix-device-node-leak-in-cuse_process_init_reply.patch
new file mode 100644 (file)
index 0000000..a11fb49
--- /dev/null
@@ -0,0 +1,68 @@
+From 9fa4f7a53406430ee9982f2f636a15b338185122 Mon Sep 17 00:00:00 2001
+From: Alberto Ruiz <aruiz@redhat.com>
+Date: Wed, 8 Apr 2026 17:23:40 +0200
+Subject: fuse: fix device node leak in cuse_process_init_reply()
+
+From: Alberto Ruiz <aruiz@redhat.com>
+
+commit 9fa4f7a53406430ee9982f2f636a15b338185122 upstream.
+
+If device_add() succeeds during CUSE initialization but a subsequent
+step (cdev_alloc() or cdev_add()) fails, the error path calls
+put_device() without first calling device_del().  This leaks the
+devtmpfs entry created by device_add(), leaving a stale /dev/<name>
+node that persists until reboot.
+
+Since the cuse_conn is never linked into cuse_conntbl on the failure
+path, cuse_channel_release() sees cc->dev == NULL and skips
+device_unregister(), so no other code path cleans up the node.
+
+This has several consequences:
+
+ - The device name is permanently poisoned: any subsequent attempt to
+   create a CUSE device with the same name hits the stale sysfs entry,
+   device_add() fails, and the new device is aborted.
+
+ - The collision manifests as ENODEV returned to userspace with no
+   dmesg diagnostic, making it very difficult to debug.
+
+ - The failure is self-perpetuating: once a name is leaked, all future
+   attempts with that name fail identically.
+
+Fix this by introducing an err_dev label that calls device_del() to
+undo device_add() before falling through to err_unlock.  The existing
+err_unlock path from a device_add() failure correctly skips device_del()
+since the device was never added.
+
+Testing instructions can be found at the lore link below.
+
+Link: https://lore.kernel.org/all/20260408-wip-cuse-leak-fix-v1-0-1c028d575e97@redhat.com/
+Signed-off-by: Alberto Ruiz <aruiz@redhat.com>
+Fixes: 151060ac1314 ("CUSE: implement CUSE - Character device in Userspace")
+Cc: stable@vger.kernel.org
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/fuse/cuse.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/fs/fuse/cuse.c
++++ b/fs/fuse/cuse.c
+@@ -390,7 +390,7 @@ static void cuse_process_init_reply(stru
+       rc = -ENOMEM;
+       cdev = cdev_alloc();
+       if (!cdev)
+-              goto err_unlock;
++              goto err_dev;
+       cdev->owner = THIS_MODULE;
+       cdev->ops = &cuse_frontend_fops;
+@@ -416,6 +416,8 @@ out:
+ err_cdev:
+       cdev_del(cdev);
++err_dev:
++      device_del(dev);
+ err_unlock:
+       mutex_unlock(&cuse_lock);
+       put_device(dev);
diff --git a/queue-6.12/fuse-re-lock-request-before-returning-from-fuse_ref_folio.patch b/queue-6.12/fuse-re-lock-request-before-returning-from-fuse_ref_folio.patch
new file mode 100644 (file)
index 0000000..53eed05
--- /dev/null
@@ -0,0 +1,37 @@
+From b5befa80fdbe287a98480effed9564712924add5 Mon Sep 17 00:00:00 2001
+From: Joanne Koong <joannelkoong@gmail.com>
+Date: Mon, 18 May 2026 22:28:07 -0700
+Subject: fuse: re-lock request before returning from fuse_ref_folio()
+
+From: Joanne Koong <joannelkoong@gmail.com>
+
+commit b5befa80fdbe287a98480effed9564712924add5 upstream.
+
+fuse_ref_folio() unlocks the request but does not re-lock it before
+returning. fuse_chan_abort() can end the request and the async end
+callback (eg fuse_writepage_free()) can free the args while the
+subsequent copy chain logic after fuse_ref_folio() accesses them,
+leading to use-after-free issues.
+
+Fix this by locking the request in fuse_ref_folio() before returning.
+
+Fixes: c3021629a0d8 ("fuse: support splice() reading from fuse device")
+Cc: stable@vger.kernel.org
+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 |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/fuse/dev.c
++++ b/fs/fuse/dev.c
+@@ -960,7 +960,7 @@ static int fuse_ref_page(struct fuse_cop
+       cs->nr_segs++;
+       cs->len = 0;
+-      return 0;
++      return lock_request(cs->req);
+ }
+ /*
index 9bbad6df9e4d438e4a1dd10614fbced9d0400b77..6eebf884746b8a1b8eea416ad62e0eda1a77caad 100644 (file)
@@ -343,3 +343,6 @@ input-maplemouse-set-driver-data-before-registering-input-device.patch
 input-maplecontrol-set-driver-data-before-registering-input-device.patch
 rdma-rtrs-srv-bound-rdma-write-length-to-chunk-size-in-rdma_write_sg.patch
 rdma-siw-bound-read-response-placement-to-the-rread-length.patch
+fuse-fix-device-node-leak-in-cuse_process_init_reply.patch
+fuse-re-lock-request-before-returning-from-fuse_ref_folio.patch
+fuse-clear-intr_entry-in-fuse_resend-and-fuse_remove_pending_req.patch