public inbox for io-uring@vger.kernel.org
 help / color / mirror / Atom feed
From: veygax <veyga@veygax.dev>
To: Ming Lei <ming.lei@redhat.com>
Cc: Jens Axboe <axboe@kernel.dk>,
	"io-uring@vger.kernel.org" <io-uring@vger.kernel.org>,
	Caleb Sander Mateos <csander@purestorage.com>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] io_uring/rsrc: fix slab-out-of-bounds in io_buffer_register_bvec
Date: Thu, 18 Dec 2025 00:37:47 +0000	[thread overview]
Message-ID: <f1522c5d-febf-4e51-b534-c0ffa719d555@veygax.dev> (raw)
In-Reply-To: <aUNLs5g3Qed4tuYs@fedora>

On 18/12/2025 00:32, Ming Lei wrote:
> Can you share the test case so that we can understand why page isn't merged
> to last bvec? Maybe there is chance to improve block layer(bio add page
> related code)

Sure, this is how i triggered it:

#include <kunit/test.h>
#include <linux/io_uring.h>
#include <linux/io_uring_types.h>
#include <linux/io_uring/cmd.h>
#include <linux/blk-mq.h>
#include <linux/bio.h>
#include <linux/bvec.h>
#include <linux/mm.h>
#include <linux/slab.h>

#include "io_uring.h"
#include "rsrc.h"

static void dummy_release(void *priv)
{
}

static void io_buffer_register_bvec_overflow_test(struct kunit *test)
{
	struct io_ring_ctx *ctx;
	struct io_uring_cmd *cmd;
	struct io_kiocb *req;
	struct request *rq;
	struct bio *bio;
	struct page *page;
	int i, ret;

	/*
	 * IO_CACHED_BVECS_SEGS is 32.
	 * We want more than 32 bvecs to trigger overflow if allocation uses 32.
	 */
	int num_bvecs = 40;
	
	ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
	KUNIT_ASSERT_NOT_NULL(test, ctx);
	
	/* Initialize caches so io_alloc_imu works and knows the size */
	if (io_rsrc_cache_init(ctx))
		kunit_skip(test, "failed to init rsrc cache");

	/* Initialize buf_table so index check passes */
	ret = io_rsrc_data_alloc(&ctx->buf_table, 1);
	KUNIT_ASSERT_EQ(test, ret, 0);

	req = kunit_kzalloc(test, sizeof(*req), GFP_KERNEL);
	KUNIT_ASSERT_NOT_NULL(test, req);
	req->ctx = ctx;
	cmd = io_kiocb_to_cmd(req, struct io_uring_cmd);

	rq = kunit_kzalloc(test, sizeof(*rq), GFP_KERNEL);
	KUNIT_ASSERT_NOT_NULL(test, rq);
	
	/* Allocate bio with enough slots */
	bio = bio_kmalloc(num_bvecs, GFP_KERNEL);
	KUNIT_ASSERT_NOT_NULL(test, bio);
	bio_init(bio, NULL, bio_inline_vecs(bio), num_bvecs, REQ_OP_WRITE);
	rq->bio = bio;
	
	page = alloc_pages(GFP_KERNEL | __GFP_COMP | __GFP_ZERO, 6);
	KUNIT_ASSERT_NOT_NULL(test, page);
	
	/*
	 * Add pages to bio manually.
	 * We use physically contiguous pages to trick blk_rq_nr_phys_segments
	 * into returning 1 segment.
	 * We use multiple bvec entries to trick the loop in
io_buffer_register_bvec
	 * into writing out of bounds.
	 */
	for (i = 0; i < num_bvecs; i++) {
		struct bio_vec *bv = &bio->bi_io_vec[i];
		bv->bv_page = page + i;
		bv->bv_len = PAGE_SIZE;
		bv->bv_offset = 0;
		bio->bi_vcnt++;
		bio->bi_iter.bi_size += PAGE_SIZE;
	}
	
	/* Trigger */
	ret = io_buffer_register_bvec(cmd, rq, dummy_release, 0, 0);
	
	/* this should not be reachable */
	__free_pages(page, 6);
	kfree(bio);
	io_rsrc_data_free(ctx, &ctx->buf_table);
	io_rsrc_cache_free(ctx);
}

static struct kunit_case io_uring_rsrc_test_cases[] = {
	KUNIT_CASE(io_buffer_register_bvec_overflow_test),
	{}
};

static struct kunit_suite io_uring_rsrc_test_suite = {
	.name = "io_uring_rsrc_test",
	.test_cases = io_uring_rsrc_test_cases,
};

kunit_test_suite(io_uring_rsrc_test_suite);
MODULE_LICENSE("GPL");


-- 
- Evan Lambert / veygax



  reply	other threads:[~2025-12-18  0:38 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-12-17 21:04 [PATCH] io_uring/rsrc: fix slab-out-of-bounds in io_buffer_register_bvec veygax
2025-12-17 21:22 ` Caleb Sander Mateos
2025-12-18  0:32 ` Ming Lei
2025-12-18  0:37   ` veygax [this message]
2025-12-18  0:56     ` Keith Busch
2025-12-18  1:13       ` veygax
2025-12-18  2:58         ` Ming Lei
2025-12-18 23:00         ` Keith Busch
2025-12-19  3:28           ` Jens Axboe
2025-12-19  5:33       ` Christoph Hellwig
2025-12-21 23:29         ` Keith Busch
2025-12-22 22:08           ` Christoph Hellwig
2025-12-22  1:02         ` veygax

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=f1522c5d-febf-4e51-b534-c0ffa719d555@veygax.dev \
    --to=veyga@veygax.dev \
    --cc=axboe@kernel.dk \
    --cc=csander@purestorage.com \
    --cc=io-uring@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ming.lei@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox