mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
fuse: don't BUG when the copy buffer is exhausted
fuse_copy_fill() hits BUG_ON(!err) once the iterator backing the copy
runs out of pages. Over io-uring the amount copied is not bounded by the
payload buffer the server registered, so an unprivileged user can drain
the iterator and panic the host - mount a FUSE filesystem with small
payload buffers, then setxattr() a larger value:
kernel BUG at fs/fuse/dev.c:1064!
Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI
CPU: 1 UID: 0 PID: 148 Comm: exploit Not tainted 7.3.0-rc1 #2
RIP: 0010:fuse_copy_fill (fs/fuse/dev.c:1033)
Call Trace:
<TASK>
fuse_copy_args (fs/fuse/dev.c:1354 fs/fuse/dev.c:1380)
fuse_uring_args_to_ring (fs/fuse/dev_uring.c:891)
fuse_uring_prepare_send (fs/fuse/dev_uring.c:940 fs/fuse/dev_uring.c:1057)
fuse_uring_send_in_task (fs/fuse/dev_uring.c:1745)
tctx_task_work_run (io_uring/tw.c:96)
tctx_task_work (io_uring/tw.c:133)
task_work_run (kernel/task_work.c:233)
io_run_task_work (io_uring/tw.h:84)
io_cqring_wait (io_uring/wait.c:278)
__do_sys_io_uring_enter (io_uring/io_uring.c:2676)
do_syscall_64 (arch/x86/entry/syscall_64.c:61)
entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
The reply path can drain it the same way, via the server-supplied
payload_sz in fuse_uring_copy_from_ring().
Return -EIO instead. All three fuse_copy_fill() callers already
propagate the error.
Fixes: c090c8abae ("fuse: Add io-uring sqe commit and fetch support")
Cc: stable@vger.kernel.org
Reported-by: Weiming Shi <bestswngs@gmail.com>
Suggested-by: Joanne Koong <joannelkoong@gmail.com>
Assisted-by: Claude:claude-opus-4-8
Reviewed-by: Joanne Koong <joannelkoong@gmail.com>
Signed-off-by: Xiang Mei <xmei5@asu.edu>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
parent
b46e096674
commit
c1338aae7b
|
|
@ -1061,7 +1061,8 @@ static int fuse_copy_fill(struct fuse_copy_state *cs)
|
|||
err = iov_iter_get_pages2(cs->iter, &page, PAGE_SIZE, 1, &off);
|
||||
if (err < 0)
|
||||
return err;
|
||||
BUG_ON(!err);
|
||||
if (!err)
|
||||
return -EIO;
|
||||
cs->len = err;
|
||||
cs->offset = off;
|
||||
cs->pg = page;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user