Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'io_uring-6.11-20240830' of git://git.kernel.dk/linux

Pull io_uring fixes from Jens Axboe:

- A fix for a regression that happened in 6.11 merge window, where the
copying of iovecs for compat mode applications got broken for certain
cases.

- Fix for a bug introduced in 6.10, where if using recv/send bundles
with classic provided buffers, the recv/send would fail to set the
right iovec count. This caused 0 byte send/recv results. Found via
code coverage testing and writing a test case to exercise it.

* tag 'io_uring-6.11-20240830' of git://git.kernel.dk/linux:
io_uring/kbuf: return correct iovec count from classic buffer peek
io_uring/rsrc: ensure compat iovecs are copied correctly

+16 -5
+1 -1
io_uring/kbuf.c
··· 129 129 130 130 iov[0].iov_base = buf; 131 131 iov[0].iov_len = *len; 132 - return 0; 132 + return 1; 133 133 } 134 134 135 135 static struct io_uring_buf *io_ring_head_to_buf(struct io_uring_buf_ring *br,
+15 -4
io_uring/rsrc.c
··· 394 394 struct io_uring_rsrc_update2 *up, 395 395 unsigned int nr_args) 396 396 { 397 - struct iovec __user *uvec = u64_to_user_ptr(up->data); 398 397 u64 __user *tags = u64_to_user_ptr(up->tags); 399 398 struct iovec fast_iov, *iov; 400 399 struct page *last_hpage = NULL; 400 + struct iovec __user *uvec; 401 + u64 user_data = up->data; 401 402 __u32 done; 402 403 int i, err; 403 404 ··· 411 410 struct io_mapped_ubuf *imu; 412 411 u64 tag = 0; 413 412 414 - iov = iovec_from_user(&uvec[done], 1, 1, &fast_iov, ctx->compat); 413 + uvec = u64_to_user_ptr(user_data); 414 + iov = iovec_from_user(uvec, 1, 1, &fast_iov, ctx->compat); 415 415 if (IS_ERR(iov)) { 416 416 err = PTR_ERR(iov); 417 417 break; ··· 445 443 446 444 ctx->user_bufs[i] = imu; 447 445 *io_get_tag_slot(ctx->buf_data, i) = tag; 446 + if (ctx->compat) 447 + user_data += sizeof(struct compat_iovec); 448 + else 449 + user_data += sizeof(struct iovec); 448 450 } 449 451 return done ? done : err; 450 452 } ··· 955 949 struct page *last_hpage = NULL; 956 950 struct io_rsrc_data *data; 957 951 struct iovec fast_iov, *iov = &fast_iov; 958 - const struct iovec __user *uvec = (struct iovec * __user) arg; 952 + const struct iovec __user *uvec; 959 953 int i, ret; 960 954 961 955 BUILD_BUG_ON(IORING_MAX_REG_BUFFERS >= (1u << 16)); ··· 978 972 979 973 for (i = 0; i < nr_args; i++, ctx->nr_user_bufs++) { 980 974 if (arg) { 981 - iov = iovec_from_user(&uvec[i], 1, 1, &fast_iov, ctx->compat); 975 + uvec = (struct iovec __user *) arg; 976 + iov = iovec_from_user(uvec, 1, 1, &fast_iov, ctx->compat); 982 977 if (IS_ERR(iov)) { 983 978 ret = PTR_ERR(iov); 984 979 break; ··· 987 980 ret = io_buffer_validate(iov); 988 981 if (ret) 989 982 break; 983 + if (ctx->compat) 984 + arg += sizeof(struct compat_iovec); 985 + else 986 + arg += sizeof(struct iovec); 990 987 } 991 988 992 989 if (!iov->iov_base && *io_get_tag_slot(data, i)) {