diff options
author | Damien Le Moal <damien.lemoal@wdc.com> | 2018-10-12 06:08:42 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2018-10-25 13:17:40 -0400 |
commit | 5f832a395859de7191e638e3777ae57f37d46d08 (patch) | |
tree | 54acd5b024436bdffffeee21e11e0783d254d624 | |
parent | d2e428e49eec9b7ff175d7d5941d50e5a7d15324 (diff) |
scsi: sd_zbc: Fix sd_zbc_check_zones() error checks
The unsigned 32 bits overflow check for the zone size value is already
done within sd_zbc_check_zones() with the test:
} else if (logical_to_sectors(sdkp->device, zone_blocks) > UINT_MAX) {
so there is no need to check again for an out of range value in
sd_zbc_read_zones(). Simplify the code and fix sd_zbc_check_zones()
error return to -EFBIG instead of -ENODEV if the zone size is too large.
Change the return type of sd_zbc_check_zones() to an int for the error
code and return the zone size (zone_blocks) through a u32 pointer to
avoid overflowing the signed 32 return value.
Reviewed-by: Hannes Reinecke <hare@suse.com>
Acked-by: Martin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r-- | drivers/scsi/sd_zbc.c | 19 |
1 files changed, 8 insertions, 11 deletions
diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c index ca73c46931c0..0678e1e108b0 100644 --- a/drivers/scsi/sd_zbc.c +++ b/drivers/scsi/sd_zbc.c | |||
@@ -373,7 +373,7 @@ static int sd_zbc_check_zoned_characteristics(struct scsi_disk *sdkp, | |||
373 | * Returns the zone size in number of blocks upon success or an error code | 373 | * Returns the zone size in number of blocks upon success or an error code |
374 | * upon failure. | 374 | * upon failure. |
375 | */ | 375 | */ |
376 | static s64 sd_zbc_check_zones(struct scsi_disk *sdkp) | 376 | static int sd_zbc_check_zones(struct scsi_disk *sdkp, u32 *zblocks) |
377 | { | 377 | { |
378 | u64 zone_blocks = 0; | 378 | u64 zone_blocks = 0; |
379 | sector_t max_lba, block = 0; | 379 | sector_t max_lba, block = 0; |
@@ -381,7 +381,7 @@ static s64 sd_zbc_check_zones(struct scsi_disk *sdkp) | |||
381 | unsigned char *rec; | 381 | unsigned char *rec; |
382 | unsigned int buf_len; | 382 | unsigned int buf_len; |
383 | unsigned int list_length; | 383 | unsigned int list_length; |
384 | s64 ret; | 384 | int ret; |
385 | u8 same; | 385 | u8 same; |
386 | 386 | ||
387 | /* Get a buffer */ | 387 | /* Get a buffer */ |
@@ -472,9 +472,10 @@ out: | |||
472 | if (sdkp->first_scan) | 472 | if (sdkp->first_scan) |
473 | sd_printk(KERN_NOTICE, sdkp, | 473 | sd_printk(KERN_NOTICE, sdkp, |
474 | "Zone size too large\n"); | 474 | "Zone size too large\n"); |
475 | ret = -ENODEV; | 475 | ret = -EFBIG; |
476 | } else { | 476 | } else { |
477 | ret = zone_blocks; | 477 | *zblocks = zone_blocks; |
478 | ret = 0; | ||
478 | } | 479 | } |
479 | 480 | ||
480 | out_free: | 481 | out_free: |
@@ -668,7 +669,7 @@ err: | |||
668 | 669 | ||
669 | int sd_zbc_read_zones(struct scsi_disk *sdkp, unsigned char *buf) | 670 | int sd_zbc_read_zones(struct scsi_disk *sdkp, unsigned char *buf) |
670 | { | 671 | { |
671 | int64_t zone_blocks; | 672 | u32 zone_blocks; |
672 | int ret; | 673 | int ret; |
673 | 674 | ||
674 | if (!sd_is_zoned(sdkp)) | 675 | if (!sd_is_zoned(sdkp)) |
@@ -687,12 +688,8 @@ int sd_zbc_read_zones(struct scsi_disk *sdkp, unsigned char *buf) | |||
687 | * Check zone size: only devices with a constant zone size (except | 688 | * Check zone size: only devices with a constant zone size (except |
688 | * an eventual last runt zone) that is a power of 2 are supported. | 689 | * an eventual last runt zone) that is a power of 2 are supported. |
689 | */ | 690 | */ |
690 | zone_blocks = sd_zbc_check_zones(sdkp); | 691 | ret = sd_zbc_check_zones(sdkp, &zone_blocks); |
691 | ret = -EFBIG; | 692 | if (ret != 0) |
692 | if (zone_blocks != (u32)zone_blocks) | ||
693 | goto err; | ||
694 | ret = zone_blocks; | ||
695 | if (ret < 0) | ||
696 | goto err; | 693 | goto err; |
697 | 694 | ||
698 | /* The drive satisfies the kernel restrictions: set it up */ | 695 | /* The drive satisfies the kernel restrictions: set it up */ |