diff options
author | Mikulas Patocka <mpatocka@redhat.com> | 2022-09-14 16:55:51 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2022-09-23 14:14:05 +0200 |
commit | 46c716a31fcdfd94524bb4b99814428603e4d7bb (patch) | |
tree | 5e7ed7e5905b046bac69aec114c4278a99a0898e /block/blk-lib.c | |
parent | c2c7f67fd12d82bb89a210f3442e392b5d781fda (diff) | |
download | linux-stable-46c716a31fcdfd94524bb4b99814428603e4d7bb.tar.gz linux-stable-46c716a31fcdfd94524bb4b99814428603e4d7bb.tar.bz2 linux-stable-46c716a31fcdfd94524bb4b99814428603e4d7bb.zip |
blk-lib: fix blkdev_issue_secure_erase
commit c4fa368466cc1b60bb92f867741488930ddd6034 upstream.
There's a bug in blkdev_issue_secure_erase. The statement
"unsigned int len = min_t(sector_t, nr_sects, max_sectors);"
sets the variable "len" to the length in sectors, but the statement
"bio->bi_iter.bi_size = len" treats it as if it were in bytes.
The statements "sector += len << SECTOR_SHIFT" and "nr_sects -= len <<
SECTOR_SHIFT" are thinko.
This patch fixes it.
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Cc: stable@vger.kernel.org # v5.19
Fixes: 44abff2c0b97 ("block: decouple REQ_OP_SECURE_ERASE from REQ_OP_DISCARD")
Link: https://lore.kernel.org/r/alpine.LRH.2.02.2209141549480.28100@file01.intranet.prod.int.rdu2.redhat.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'block/blk-lib.c')
-rw-r--r-- | block/blk-lib.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/block/blk-lib.c b/block/blk-lib.c index 09b7e1200c0f..20e42144065b 100644 --- a/block/blk-lib.c +++ b/block/blk-lib.c @@ -311,6 +311,11 @@ int blkdev_issue_secure_erase(struct block_device *bdev, sector_t sector, struct blk_plug plug; int ret = 0; + /* make sure that "len << SECTOR_SHIFT" doesn't overflow */ + if (max_sectors > UINT_MAX >> SECTOR_SHIFT) + max_sectors = UINT_MAX >> SECTOR_SHIFT; + max_sectors &= ~bs_mask; + if (max_sectors == 0) return -EOPNOTSUPP; if ((sector | nr_sects) & bs_mask) @@ -324,10 +329,10 @@ int blkdev_issue_secure_erase(struct block_device *bdev, sector_t sector, bio = blk_next_bio(bio, bdev, 0, REQ_OP_SECURE_ERASE, gfp); bio->bi_iter.bi_sector = sector; - bio->bi_iter.bi_size = len; + bio->bi_iter.bi_size = len << SECTOR_SHIFT; - sector += len << SECTOR_SHIFT; - nr_sects -= len << SECTOR_SHIFT; + sector += len; + nr_sects -= len; if (!nr_sects) { ret = submit_bio_wait(bio); bio_put(bio); |