This is a test repository.
Révision | c4fa368466cc1b60bb92f867741488930ddd6034 (tree) |
---|---|
l'heure | 2022-09-15 15:25:17 |
Auteur | Mikulas Patocka <mpatocka@redh...> |
Commiter | Jens Axboe |
blk-lib: fix blkdev_issue_secure_erase
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>
@@ -309,6 +309,11 @@ int blkdev_issue_secure_erase(struct block_device *bdev, sector_t sector, | ||
309 | 309 | struct blk_plug plug; |
310 | 310 | int ret = 0; |
311 | 311 | |
312 | + /* make sure that "len << SECTOR_SHIFT" doesn't overflow */ | |
313 | + if (max_sectors > UINT_MAX >> SECTOR_SHIFT) | |
314 | + max_sectors = UINT_MAX >> SECTOR_SHIFT; | |
315 | + max_sectors &= ~bs_mask; | |
316 | + | |
312 | 317 | if (max_sectors == 0) |
313 | 318 | return -EOPNOTSUPP; |
314 | 319 | if ((sector | nr_sects) & bs_mask) |
@@ -322,10 +327,10 @@ int blkdev_issue_secure_erase(struct block_device *bdev, sector_t sector, | ||
322 | 327 | |
323 | 328 | bio = blk_next_bio(bio, bdev, 0, REQ_OP_SECURE_ERASE, gfp); |
324 | 329 | bio->bi_iter.bi_sector = sector; |
325 | - bio->bi_iter.bi_size = len; | |
330 | + bio->bi_iter.bi_size = len << SECTOR_SHIFT; | |
326 | 331 | |
327 | - sector += len << SECTOR_SHIFT; | |
328 | - nr_sects -= len << SECTOR_SHIFT; | |
332 | + sector += len; | |
333 | + nr_sects -= len; | |
329 | 334 | if (!nr_sects) { |
330 | 335 | ret = submit_bio_wait(bio); |
331 | 336 | bio_put(bio); |