]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
fuse-uring: check connection abort during ring creation
authorJoanne Koong <joannelkoong@gmail.com>
Mon, 8 Jun 2026 19:21:48 +0000 (12:21 -0700)
committerMiklos Szeredi <mszeredi@redhat.com>
Mon, 15 Jun 2026 12:06:14 +0000 (14:06 +0200)
Check fch->connected under fch->lock in fuse_uring_create() before
attaching a new ring. Without this, a race between fuse_uring_create()
and fuse_chan_abort() can result in the ring, queue, and fpq.processing
table being created after fuse_uring_abort() has already run, leading
to unnecessary allocation and teardown. These are eventually cleaned up
by fuse_uring_destruct() but will linger until the process exits, even
with the connection aborted.

Reviewed-by: Bernd Schubert <bernd@bsbernd.com>
Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/fuse/dev_uring.c

index 16b9229c2dbdf8a95686a3248a45e26259606b74..fb24a2cb53dcce909132719dd7314c06f931580c 100644 (file)
@@ -244,6 +244,10 @@ static struct fuse_ring *fuse_uring_create(struct fuse_conn *fc)
        max_payload_size = max(max_payload_size, fc->max_pages * PAGE_SIZE);
 
        spin_lock(&fc->lock);
+       if (!fc->connected) {
+               spin_unlock(&fc->lock);
+               goto out_err;
+       }
        if (fc->ring) {
                /* race, another thread created the ring in the meantime */
                spin_unlock(&fc->lock);
@@ -981,16 +985,16 @@ static int fuse_uring_do_register(struct fuse_ring_ent *ent,
        struct fuse_conn *fc = ring->fc;
        struct fuse_iqueue *fiq = &fc->iq;
 
-       spin_lock(&fch->lock);
+       spin_lock(&fc->lock);
        /* abort teardown path is running or has run */
-       if (!fch->connected) {
-               spin_unlock(&fch->lock);
+       if (!fc->connected) {
+               spin_unlock(&fc->lock);
                if (atomic_dec_and_test(&ring->queue_refs))
                        wake_up_all(&ring->stop_waitq);
                kfree(ent);
                return -ECONNABORTED;
        }
-       spin_unlock(&fch->lock);
+       spin_unlock(&fc->lock);
 
        fuse_uring_prepare_cancel(cmd, issue_flags, ent);