aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGabriel Krisman Bertazi <krisman@suse.de>2024-05-01 14:56:36 -0600
committerJens Axboe <axboe@kernel.dk>2024-05-01 14:56:36 -0600
commit79996b45f7b28c0e3e08a95bab80119e95317e28 (patch)
tree16216c963f5329a5effb9a9d32676716bc81d390
parent19352a1d395424b5f8c03289a85fbd6622d6601a (diff)
downloadlinux-79996b45f7b28c0e3e08a95bab80119e95317e28.tar.gz
io_uring: Require zeroed sqe->len on provided-buffers send
When sending from a provided buffer, we set sr->len to be the smallest between the actual buffer size and sqe->len. But, now that we disconnect the buffer from the submission request, we can get in a situation where the buffers and requests mismatch, and only part of a buffer gets sent. Assume: * buf[1]->len = 128; buf[2]->len = 256 * sqe[1]->len = 128; sqe[2]->len = 256 If sqe1 runs first, it picks buff[1] and it's all good. But, if sqe[2] runs first, sqe[1] picks buff[2], and the last half of buff[2] is never sent. While arguably the use-case of different-length sends is questionable, it has already raised confusion with potential users of this feature. Let's make the interface less tricky by forcing the length to only come from the buffer ring entry itself. Fixes: ac5f71a3d9d7 ("io_uring/net: add provided buffer support for IORING_OP_SEND") Signed-off-by: Gabriel Krisman Bertazi <krisman@suse.de> Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--io_uring/net.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/io_uring/net.c b/io_uring/net.c
index 503debecad3210..b0bf8471ecb77f 100644
--- a/io_uring/net.c
+++ b/io_uring/net.c
@@ -423,6 +423,8 @@ int io_sendmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
sr->buf_group = req->buf_index;
req->buf_list = NULL;
}
+ if (req->flags & REQ_F_BUFFER_SELECT && sr->len)
+ return -EINVAL;
#ifdef CONFIG_COMPAT
if (req->ctx->compat)
@@ -586,7 +588,7 @@ retry_bundle:
if (io_do_buffer_select(req)) {
struct buf_sel_arg arg = {
.iovs = &kmsg->fast_iov,
- .max_len = min_not_zero(sr->len, INT_MAX),
+ .max_len = INT_MAX,
.nr_iovs = 1,
.mode = KBUF_MODE_EXPAND,
};