[PATCH RFC 3/5] block: validate bio bounds in the queue entered context
Damien Le Moal
dlemoal at kernel.org
Wed May 20 00:25:13 PDT 2026
On 2026/05/20 9:22, Damien Le Moal wrote:
> On 2026/05/19 19:23, Keith Busch wrote:
>> From: Keith Busch <kbusch at kernel.org>
>>
>> bio_check_eod() in submit_bio_noacct() validates that a bio does not
>> extend beyond the partition's available sectors. This check runs before
>> bio_queue_enter(), so it is not serialized against queue limit updates.
>> A driver that freezes the queue, updates limits, changes the capacity,
>> and unfreezes can race with a bio that passed the early check under the
>> old capacity.
>>
>> Remove bio_check_eod() and replace it with a bounds check in
>> __bio_split_to_limits(), which runs after the queue usage reference has
>> been acquired. The check uses partition-aware arithmetic to validate
>> both partition bounds and disk capacity in a single comparison that
>> works correctly on the post-remap sector values.
>>
>> Signed-off-by: Keith Busch <kbusch at kernel.org>
>
> [...]
>
>> @@ -423,6 +423,17 @@ static inline bool bio_may_need_split(struct bio *bio,
>> static inline struct bio *__bio_split_to_limits(struct bio *bio,
>> const struct queue_limits *lim, unsigned int *nr_segs)
>> {
>> + if (unlikely(bio_end_sector(bio) > bdev_nr_sectors(bio->bi_bdev) +
>> + bio->bi_bdev->bd_start_sect)) {
>> + pr_info_ratelimited("%s: attempt to access beyond end of device\n"
>> + "%pg: rw=%d, sector=%llu, nr_sectors = %u limit=%llu\n",
>> + current->comm, bio->bi_bdev, bio->bi_opf,
>> + bio->bi_iter.bi_sector, bio_sectors(bio),
>> + bdev_nr_sectors(bio->bi_bdev) +
>> + bio->bi_bdev->bd_start_sect);
>
> Should this be a pr_err_ratelimited() ?
>
> Also, putting this check here means that we are going to redo the check for all
> the fragment of the large BIO being split, no ? It would be nice to be able to
> do this check only once when the large BIO is submitted.
>
> Moving this check to a helper and calling this new helper higher in the
> submission path could avoid that. But I am not 100% sure if a higher placed call
> can be a problem.
Replying to myself: We do not yet have called queue enter higher up. So moving
this check defeats your goal. Please ignore this comment :)
>> + goto ioerr;
>> + }
>> +
>> switch (bio_op(bio)) {
>> case REQ_OP_READ:
>> case REQ_OP_WRITE:
>> @@ -442,6 +453,9 @@ static inline struct bio *__bio_split_to_limits(struct bio *bio,
>> *nr_segs = 0;
>> return bio;
>> }
>> +ioerr:
>> + bio_io_error(bio);
>> + return NULL;
>> }
>>
>> /**
>
>
--
Damien Le Moal
Western Digital Research
More information about the Linux-nvme
mailing list