[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