Commit 220374ab authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'io_uring-6.17-20250828' of git://git.kernel.dk/linux

Pull io_uring fixes from Jens Axboe:

 - Use the proper type for min_t() in getting the min of the leftover
   bytes and the buffer length.

 - As good practice, use READ_ONCE() consistently for reading ring
   provided buffer lengths. Additionally, stop looping for incremental
   commits if a zero sized buffer is hit, as no further progress can be
   made at that point.

* tag 'io_uring-6.17-20250828' of git://git.kernel.dk/linux:
  io_uring/kbuf: always use READ_ONCE() to read ring provided buffer lengths
  io_uring/kbuf: fix signedness in this_len calculation
parents 9c736ace 98b6fa62
Loading
Loading
Loading
Loading
+13 −7
Original line number Diff line number Diff line
@@ -36,15 +36,19 @@ static bool io_kbuf_inc_commit(struct io_buffer_list *bl, int len)
{
	while (len) {
		struct io_uring_buf *buf;
		u32 this_len;
		u32 buf_len, this_len;

		buf = io_ring_head_to_buf(bl->buf_ring, bl->head, bl->mask);
		this_len = min_t(int, len, buf->len);
		buf->len -= this_len;
		if (buf->len) {
		buf_len = READ_ONCE(buf->len);
		this_len = min_t(u32, len, buf_len);
		buf_len -= this_len;
		/* Stop looping for invalid buffer length of 0 */
		if (buf_len || !this_len) {
			buf->addr += this_len;
			buf->len = buf_len;
			return false;
		}
		buf->len = 0;
		bl->head++;
		len -= this_len;
	}
@@ -159,6 +163,7 @@ static void __user *io_ring_buffer_select(struct io_kiocb *req, size_t *len,
	__u16 tail, head = bl->head;
	struct io_uring_buf *buf;
	void __user *ret;
	u32 buf_len;

	tail = smp_load_acquire(&br->tail);
	if (unlikely(tail == head))
@@ -168,8 +173,9 @@ static void __user *io_ring_buffer_select(struct io_kiocb *req, size_t *len,
		req->flags |= REQ_F_BL_EMPTY;

	buf = io_ring_head_to_buf(br, head, bl->mask);
	if (*len == 0 || *len > buf->len)
		*len = buf->len;
	buf_len = READ_ONCE(buf->len);
	if (*len == 0 || *len > buf_len)
		*len = buf_len;
	req->flags |= REQ_F_BUFFER_RING | REQ_F_BUFFERS_COMMIT;
	req->buf_list = bl;
	req->buf_index = buf->bid;
@@ -265,7 +271,7 @@ static int io_ring_buffers_peek(struct io_kiocb *req, struct buf_sel_arg *arg,

	req->buf_index = buf->bid;
	do {
		u32 len = buf->len;
		u32 len = READ_ONCE(buf->len);

		/* truncate end piece, if needed, for non partial buffers */
		if (len > arg->max_len) {