diff --git a/block/blk-lib.c b/block/blk-lib.c index e59c3069e8351f7edf0d82c6a3b376a3029a994c..564904eeaed53d90654ccb5b9cd8cc811b5d1402 100644 --- a/block/blk-lib.c +++ b/block/blk-lib.c @@ -64,6 +64,14 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector, sector_t req_sects = min(nr_sects, bio_discard_limit(bdev, sector)); + if (!req_sects) { + if (bio) { + bio_io_error(bio); + bio_put(bio); + } + return -EOPNOTSUPP; + } + bio = blk_next_bio(bio, bdev, 0, REQ_OP_DISCARD, gfp_mask); bio->bi_iter.bi_sector = sector; bio->bi_iter.bi_size = req_sects << 9; diff --git a/block/ioctl.c b/block/ioctl.c index 572bef75d601ca61e28e21432a850b3bebbd3dfa..b7104fd80a46e53e91608fe9efc3bb59dcb3bba5 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -89,7 +89,7 @@ static int blk_ioctl_discard(struct block_device *bdev, blk_mode_t mode, unsigned long arg) { uint64_t range[2]; - uint64_t start, len; + uint64_t start, len, end; struct inode *inode = bdev->bd_inode; int err; @@ -110,7 +110,8 @@ static int blk_ioctl_discard(struct block_device *bdev, blk_mode_t mode, if (len & 511) return -EINVAL; - if (start + len > bdev_nr_bytes(bdev)) + if (check_add_overflow(start, len, &end) || + end > bdev_nr_bytes(bdev)) return -EINVAL; filemap_invalidate_lock(inode->i_mapping);