On Mon, Jul 13, 2026 at 10:24 AM Joanne Koong <[email protected]> wrote: > > On Thu, Jul 9, 2026 at 2:11 PM Xiang Mei <[email protected]> wrote: > > > > The fuse-io-uring transport imports each ring entry's payload buffer at > > ring->max_payload_sz and bounds both copy directions against that value, > > ignoring the buffer length the server actually registered. Both the > > server-supplied reply payload_sz (fuse_uring_copy_from_ring) and an > > oversized request payload such as a large FUSE_SETXATTR value > > (fuse_uring_args_to_ring) can then overrun the imported iterator and hit > > fuse_copy_fill()'s BUG_ON(!err): > > > > kernel BUG at fs/fuse/dev.c:1053! > > Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI > > RIP: 0010:fuse_copy_fill (fs/fuse/dev.c:1022) > > Call Trace: > > fuse_copy_args (fs/fuse/dev.c:1329 fs/fuse/dev.c:1351) > > fuse_uring_copy_from_ring (fs/fuse/dev_uring.c:686) > > fuse_uring_cmd (fs/fuse/dev_uring.c:1226) > > io_uring_cmd (io_uring/uring_cmd.c:271) > > __io_issue_sqe (io_uring/io_uring.c:1395) > > io_issue_sqe (io_uring/io_uring.c:1418) > > io_submit_sqes (io_uring/io_uring.c:1649 io_uring/io_uring.c:1934 > > io_uring/io_uring.c:2057) > > __do_sys_io_uring_enter (io_uring/io_uring.c:2646) > > do_syscall_64 (arch/x86/entry/syscall_64.c:63 > > arch/x86/entry/syscall_64.c:94) > > entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121) > > > > The request path overruns the same way, via fuse_copy_args() -> > > fuse_uring_args_to_ring(). > > > > Store the registered payload length (payload->iov_len) in the ring entry > > and use it for the import and both bounds checks, so the buffer the > > server provided is honoured and an oversized reply/request is rejected > > (-EINVAL for a reply, and -E2BIG/-EIO for a request, matching > > fuse_dev_do_read()) instead of panicking. > > > > Fixes: c090c8abae4b ("fuse: Add io-uring sqe commit and fetch support") > > Cc: [email protected] > > Reported-by: Weiming Shi <[email protected]> > > Assisted-by: Claude:claude-opus-4-8 > > Signed-off-by: Xiang Mei <[email protected]> > > --- > > v3: propose the patch fixing another issue found by Bernd by Joanne > > suggested way > > > > fs/fuse/dev_uring.c | 9 ++++++++- > > fs/fuse/dev_uring_i.h | 1 + > > 2 files changed, 9 insertions(+), 1 deletion(-) > > > > diff --git a/fs/fuse/dev_uring.c b/fs/fuse/dev_uring.c > > index 0814681eb04b..248e5a3e340e 100644 > > --- a/fs/fuse/dev_uring.c > > +++ b/fs/fuse/dev_uring.c > > @@ -650,7 +650,7 @@ static int setup_fuse_copy_state(struct fuse_copy_state > > *cs, > > { > > int err; > > > > - err = import_ubuf(dir, ent->payload, ring->max_payload_sz, iter); > > + err = import_ubuf(dir, ent->payload, ent->payload_sz, iter); > > if (err) { > > pr_info_ratelimited("fuse: Import of user buffer failed\n"); > > return err; > > @@ -679,6 +679,9 @@ static int fuse_uring_copy_from_ring(struct fuse_ring > > *ring, > > if (err) > > return err; > > > > + if (ring_in_out.payload_sz > ent->payload_sz) > > + return -EINVAL; > > + > > err = setup_fuse_copy_state(&cs, ring, req, ent, ITER_SOURCE, > > &iter); > > if (err) > > return err; > > @@ -725,6 +728,9 @@ static int fuse_uring_args_to_ring(struct fuse_ring > > *ring, struct fuse_req *req, > > num_args--; > > } > > > > + if (fuse_len_args(num_args, (struct fuse_arg *)in_args) > > > ent->payload_sz) > > + return args->opcode == FUSE_SETXATTR ? -E2BIG : -EIO; > > Reviewed-by: Joanne Koong <[email protected]> > > Not saying you have to do this, but if you wanted to, I think it'd be > nice to have a separate cleanup patch that deduplicates this setxattr > special casing logic between the /dev/fuse path and here. > > Thanks, > Joanne
Thanks for your review. I updated my 1/2 to make it an elegant patch and added your suggested cleanup as 3/3. 1/3: drop previous tags; reserve the fields for user copy https://lore.kernel.org/fuse-devel/[email protected]/T/#t 2/3: no change https://lore.kernel.org/fuse-devel/[email protected]/T/#t 3/3: add a helper to return the correct error code https://lore.kernel.org/fuse-devel/[email protected]/T/#t Xiang

