From: Chaitanya Kulkarni <chaitanya.kulkarni@xxxxxxx> The function bio_trim has offset and size arguments that are declared as int. The callers of this function uses sector_t type when passing the offset and size e,g. drivers/md/raid1.c:narrow_write_error() and drivers/md/raid1.c:narrow_write_error(). Change offset and size arguments to sector_t type for bio_trim(). Also, add WARN_ON() to catch their overflow. Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@xxxxxxx> Signed-off-by: Naohiro Aota <naohiro.aota@xxxxxxx> --- block/bio.c | 14 +++++++++++--- include/linux/bio.h | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/block/bio.c b/block/bio.c index 44205dfb6b60..69a9751b18e7 100644 --- a/block/bio.c +++ b/block/bio.c @@ -1465,12 +1465,20 @@ EXPORT_SYMBOL(bio_split); * @offset: number of sectors to trim from the front of @bio * @size: size we want to trim @bio to, in sectors */ -void bio_trim(struct bio *bio, int offset, int size) +void bio_trim(struct bio *bio, sector_t offset, sector_t size) { - /* 'bio' is a cloned bio which we need to trim to match - * the given offset and size. + const sector_t uint_max_sectors = UINT_MAX >> SECTOR_SHIFT; + + /* + * 'bio' is a cloned bio which we need to trim to match the given + * offset and size. */ + /* sanity check */ + if (WARN_ON(offset > uint_max_sectors || size > uint_max_sectors || + offset + size > bio->bi_iter.bi_size)) + return; + size <<= 9; if (offset == 0 && size == bio->bi_iter.bi_size) return; diff --git a/include/linux/bio.h b/include/linux/bio.h index a0b4cfdf62a4..c91bc70add06 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -379,7 +379,7 @@ static inline void bip_set_seed(struct bio_integrity_payload *bip, #endif /* CONFIG_BLK_DEV_INTEGRITY */ -extern void bio_trim(struct bio *bio, int offset, int size); +extern void bio_trim(struct bio *bio, sector_t offset, sector_t size); extern struct bio *bio_split(struct bio *bio, int sectors, gfp_t gfp, struct bio_set *bs); -- 2.32.0