mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] fuse: serialize processing table installation with I/O
@ 2026-10-08  6:29 Cen Zhang
  0 siblings, 0 replies; only message in thread
From: Cen Zhang @ 2026-10-08  6:29 UTC (permalink / raw)
  To: miklos; +Cc: fuse-devel, linux-kernel, baijiaju1990, jjzuming, zzzccc427

The processing table of a /dev/fuse endpoint must be initialized before
I/O can use it. fuse_dev_open() leaves pq.processing NULL, and
fuse_dev_install_with_pq() publishes fud->chan before assigning the
table. fuse_get_dev() accepts the published channel without taking
fch->lock, so the installer's channel lock does not protect the reader.

On SMP, a daemon can issue FUSE_DEV_IOC_CLONE and read concurrently on
the same fresh endpoint. If the source channel has a reply-requiring
request pending and the read copies it successfully, the following
order is possible:

  Clone ioctl                         Daemon read
  -----------                         -----------
  fuse_dev_install_with_pq()
    lock fch->lock
    publish fud->chan
                                      fuse_get_dev() sees fud->chan
                                      fuse_dev_do_read()
                                        dequeue request under fiq->lock
                                        lock fpq->lock
                                        add request to fpq->io
                                        unlock fpq->lock
                                        copy request to userspace
                                        lock fpq->lock
                                        list_move_tail() to
                                          fpq->processing[hash]
    set fud->pq.processing

The list operation accesses a NULL-derived list head and can fault
before the installer stores the table.

Take fud->pq.lock before publishing the channel and hold it until
installation finishes. The reader then waits at its existing queue
lock until the table is initialized. This follows the fch->lock then
fpq->lock order already used by abort, resend and device release, and
preserves the handling of unsuccessful installation.

KASAN report as below:

    Oops: general protection fault, probably for non-canonical address 0xdffffc0000000039: 0000 [#1] SMP KASAN NOPTI
    KASAN: null-ptr-deref in range [0x00000000000001c8-0x00000000000001cf]
    CPU: 1 UID: 0 PID: 500 Comm: fuse-clone-race Not tainted 7.2.0-rc5-pmb-bt-functional-v1+ #1 PREEMPT(lazy)
    Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
    RIP: 0010:fuse_dev_do_read+0x1693/0x2480
    Code: c1 ea 03 80 3c 02 00 0f 85 b9 0b 00 00 4d 89 27 e8 42 07 2c ff 4c 8d 7b 08 48 b8 00 00 00 00 00 fc ff df 4c 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 7f 0a 00 00 4c 8b 63 08 48 89 da 4c 89 ef 4c 89
    RSP: 0018:ffff888118ecfab0 EFLAGS: 00010216
    RAX: dffffc0000000000 RBX: 00000000000001c0 RCX: ffffffff8258e60e
    RDX: 0000000000000039 RSI: 0000000000000000 RDI: ffff8881066f9768
    RBP: ffff888112b6d7a8 R08: 0000000000000001 R09: 0000000000000001
    R10: ffffffff893dbc57 R11: ffff888108fbd700 R12: ffff8881066f9760
    R13: ffff888112b6d7a0 R14: 0000000000000050 R15: 00000000000001c8
    FS:  00007feb22c636c0(0000) GS:ffff8881fd82c000(0000) knlGS:0000000000000000
    CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    CR2: 00007feb22c62f38 CR3: 0000000107252004 CR4: 0000000000770ef0
    PKRU: 55555554
    Call Trace:
     <TASK>
     ? srso_alias_return_thunk+0x5/0xfbef5
     ? __pfx_fuse_dev_do_read+0x10/0x10
     ? srso_alias_return_thunk+0x5/0xfbef5
     ? srso_alias_return_thunk+0x5/0xfbef5
     ? pmbd_probe_hit_cookie+0xee/0x1c0
     ? __pfx_pmbd_probe_hit_cookie+0x10/0x10
     fuse_dev_read+0x19d/0x250
     ? __pfx_fuse_dev_read+0x10/0x10
     ? srso_alias_return_thunk+0x5/0xfbef5
     ? security_file_permission+0x26/0x80
     vfs_read+0x7d2/0xc20
     ? __pfx_vfs_read+0x10/0x10
     ksys_read+0x111/0x200
     ? __pfx_ksys_read+0x10/0x10
     ? srso_alias_return_thunk+0x5/0xfbef5
     ? restore_fpregs_from_fpstate+0x55/0x100
     do_syscall_64+0x115/0x6a0
     entry_SYSCALL_64_after_hwframe+0x77/0x7f
    RIP: 0033:0x7feb23d039ee
    Code: 08 0f 85 f5 4b ff ff 49 89 fb 48 89 f0 48 89 d7 48 89 ce 4c 89 c2 4d 89 ca 4c 8b 44 24 08 4c 8b 4c 24 10 4c 89 5c 24 08 0f 05 <c3> 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 80 00 00 00 00 48 83 ec 08
    RSP: 002b:00007feb22c62df8 EFLAGS: 00000246 ORIG_RAX: 0000000000000000
    RAX: ffffffffffffffda RBX: 00007feb22c636c0 RCX: 00007feb23d039ee
    RDX: 0000000000010000 RSI: 000055615dac9114 RDI: 0000000000000005
    RBP: 0000000000000004 R08: 0000000000000000 R09: 0000000000000000
    R10: 0000000000000000 R11: 0000000000000246 R12: 000055615dac9114
    R13: 000055615dac9070 R14: ffffffff00000000 R15: 0000000000000001
     </TASK>
    Modules linked in:
    ---[ end trace 0000000000000000 ]---
    RIP: 0010:fuse_dev_do_read+0x1693/0x2480
    Code: c1 ea 03 80 3c 02 00 0f 85 b9 0b 00 00 4d 89 27 e8 42 07 2c ff 4c 8d 7b 08 48 b8 00 00 00 00 00 fc ff df 4c 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 7f 0a 00 00 4c 8b 63 08 48 89 da 4c 89 ef 4c 89
    RSP: 0018:ffff888118ecfab0 EFLAGS: 00010216
    RAX: dffffc0000000000 RBX: 00000000000001c0 RCX: ffffffff8258e60e
    RDX: 0000000000000039 RSI: 0000000000000000 RDI: ffff8881066f9768
    RBP: ffff888112b6d7a8 R08: 0000000000000001 R09: 0000000000000001
    R10: ffffffff893dbc57 R11: ffff888108fbd700 R12: ffff8881066f9760
    R13: ffff888112b6d7a0 R14: 0000000000000050 R15: 00000000000001c8
    FS:  00007feb22c636c0(0000) GS:ffff8881fd82c000(0000) knlGS:0000000000000000
    CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    CR2: 00007feb22c62f38 CR3: 0000000107252004 CR4: 0000000000770ef0
    PKRU: 55555554
    Kernel panic - not syncing: Fatal exception
    Kernel Offset: disabled
    Rebooting in 1 seconds..

Fixes: 48649c0603bd ("fuse: alloc pqueue before installing fch in fuse_dev")
Assisted-by: LLM
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
---

diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 4fec31fc0b845008ae037472065284e8f8dea87e..106daf2d10b34886fa5cda3c641121a08181adb4 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -466,6 +466,8 @@ static bool fuse_dev_install_with_pq(struct fuse_dev *fud, struct fuse_chan *fch
 	struct fuse_chan *old_fch;
 
 	guard(spinlock)(&fch->lock);
+	/* Serialize processing table setup with I/O. */
+	guard(spinlock)(&fud->pq.lock);
 	/*
 	 * Pairs with:
 	 *  - xchg() in fuse_dev_release()

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2026-10-08  6:29 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-08  6:29 [PATCH] fuse: serialize processing table installation with I/O Cen Zhang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®