io_uring/rsrc: ensure compat iovecs are copied correctly
authorJens Axboe <axboe@kernel.dk>
Wed, 28 Aug 2024 15:42:33 +0000 (09:42 -0600)
committerJens Axboe <axboe@kernel.dk>
Fri, 30 Aug 2024 13:52:43 +0000 (07:52 -0600)
commit1c47c0d6014c832ad8e2ba04fc2c5b7070d999f7
treeebfa4020b2e63d10c22826209aaed83cb7b121f2
parente0ee967630c8ee67bb47a5b38d235cd5a8789c48
io_uring/rsrc: ensure compat iovecs are copied correctly

For buffer registration (or updates), a userspace iovec is copied in
and updated. If the application is within a compat syscall, then the
iovec type is compat_iovec rather than iovec. However, the type used
in __io_sqe_buffers_update() and io_sqe_buffers_register() is always
struct iovec, and hence the source is incremented by the size of a
non-compat iovec in the loop. This misses every other iovec in the
source, and will run into garbage half way through the copies and
return -EFAULT to the application.

Maintain the source address separately and assign to our user vec
pointer, so that copies always happen from the right source address.

While in there, correct a bad placement of __user which triggered
the following sparse warning prior to this fix:

io_uring/rsrc.c:981:33: warning: cast removes address space '__user' of expression
io_uring/rsrc.c:981:30: warning: incorrect type in assignment (different address spaces)
io_uring/rsrc.c:981:30:    expected struct iovec const [noderef] __user *uvec
io_uring/rsrc.c:981:30:    got struct iovec *[noderef] __user

Fixes: f4eaf8eda89e ("io_uring/rsrc: Drop io_copy_iov in favor of iovec API")
Reviewed-by: Gabriel Krisman Bertazi <krisman@suse.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
io_uring/rsrc.c