diff mbox series

blk-lib: fix blkdev_issue_secure_erase

Message ID alpine.LRH.2.02.2209141549480.28100@file01.intranet.prod.int.rdu2.redhat.com (mailing list archive)
State New, archived
Headers show
Series blk-lib: fix blkdev_issue_secure_erase | expand

Commit Message

Mikulas Patocka Sept. 14, 2022, 8:55 p.m. UTC
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")

---
 block/blk-lib.c |   11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

Comments

Christoph Hellwig Sept. 20, 2022, 7:41 a.m. UTC | #1
On Wed, Sep 14, 2022 at 04:55:51PM -0400, Mikulas Patocka wrote:
> +	/* make sure that "len << SECTOR_SHIFT" doesn't overflow */
> +	if (max_sectors > UINT_MAX >> SECTOR_SHIFT)
> +		max_sectors = UINT_MAX >> SECTOR_SHIFT;

This should use max / max_t:

	max_sectors = max(max_sectors, UINT_MAX >> SECTOR_SHIFT) & ~bs_mask;
diff mbox series

Patch

Index: linux-2.6/block/blk-lib.c
===================================================================
--- linux-2.6.orig/block/blk-lib.c
+++ linux-2.6/block/blk-lib.c
@@ -309,6 +309,11 @@  int blkdev_issue_secure_erase(struct blo
 	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)
@@ -322,10 +327,10 @@  int blkdev_issue_secure_erase(struct blo
 
 		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);