Skip to content

Commit 54c27d6

Browse files
committed
Merge branch 'io_uring-6.16' into for-next
* io_uring-6.16: io_uring/kbuf: limit legacy provided buffer lists to USHRT_MAX
2 parents b801ed0 + 607d09d commit 54c27d6

2 files changed

Lines changed: 18 additions & 2 deletions

File tree

io_uring/kbuf.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ bool io_kbuf_recycle_legacy(struct io_kiocb *req, unsigned issue_flags)
108108
buf = req->kbuf;
109109
bl = io_buffer_get_list(ctx, buf->bgid);
110110
list_add(&buf->list, &bl->buf_list);
111+
bl->nbufs++;
111112
req->flags &= ~REQ_F_BUFFER_SELECTED;
112113

113114
io_ring_submit_unlock(ctx, issue_flags);
@@ -122,6 +123,7 @@ static void __user *io_provided_buffer_select(struct io_kiocb *req, size_t *len,
122123

123124
kbuf = list_first_entry(&bl->buf_list, struct io_buffer, list);
124125
list_del(&kbuf->list);
126+
bl->nbufs--;
125127
if (*len == 0 || *len > kbuf->len)
126128
*len = kbuf->len;
127129
if (list_empty(&bl->buf_list))
@@ -390,6 +392,7 @@ static int io_remove_buffers_legacy(struct io_ring_ctx *ctx,
390392
for (i = 0; i < nbufs && !list_empty(&bl->buf_list); i++) {
391393
nxt = list_first_entry(&bl->buf_list, struct io_buffer, list);
392394
list_del(&nxt->list);
395+
bl->nbufs--;
393396
kfree(nxt);
394397
cond_resched();
395398
}
@@ -491,14 +494,24 @@ static int io_add_buffers(struct io_ring_ctx *ctx, struct io_provide_buf *pbuf,
491494
{
492495
struct io_buffer *buf;
493496
u64 addr = pbuf->addr;
494-
int i, bid = pbuf->bid;
497+
int ret = -ENOMEM, i, bid = pbuf->bid;
495498

496499
for (i = 0; i < pbuf->nbufs; i++) {
500+
/*
501+
* Nonsensical to have more than sizeof(bid) buffers in a
502+
* buffer list, as the application then has no way of knowing
503+
* which duplicate bid refers to what buffer.
504+
*/
505+
if (bl->nbufs == USHRT_MAX) {
506+
ret = -EOVERFLOW;
507+
break;
508+
}
497509
buf = kmalloc(sizeof(*buf), GFP_KERNEL_ACCOUNT);
498510
if (!buf)
499511
break;
500512

501513
list_add_tail(&buf->list, &bl->buf_list);
514+
bl->nbufs++;
502515
buf->addr = addr;
503516
buf->len = min_t(__u32, pbuf->len, MAX_RW_COUNT);
504517
buf->bid = bid;
@@ -508,7 +521,7 @@ static int io_add_buffers(struct io_ring_ctx *ctx, struct io_provide_buf *pbuf,
508521
cond_resched();
509522
}
510523

511-
return i ? 0 : -ENOMEM;
524+
return i ? 0 : ret;
512525
}
513526

514527
static int __io_manage_buffers_legacy(struct io_kiocb *req,

io_uring/kbuf.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ struct io_buffer_list {
2121
struct list_head buf_list;
2222
struct io_uring_buf_ring *buf_ring;
2323
};
24+
/* count of classic/legacy buffers in buffer list */
25+
int nbufs;
26+
2427
__u16 bgid;
2528

2629
/* below is for ring provided buffers */

0 commit comments

Comments
 (0)