Skip to content

Commit 4b43392

Browse files
damien-lemoalmartinkpetersen
authored andcommitted
scsi: sd_zbc: Fix potential memory leak
Rework sd_zbc_check_zone_size() to avoid a memory leak due to an early return if sd_zbc_report_zones() fails. Reported-by: David.butterfield <[email protected]> Signed-off-by: Damien Le Moal <[email protected]> Cc: [email protected] Reviewed-by: Bart Van Assche <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 864449e commit 4b43392

File tree

1 file changed

+15
-20
lines changed

1 file changed

+15
-20
lines changed

drivers/scsi/sd_zbc.c

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ static int sd_zbc_check_capacity(struct scsi_disk *sdkp, unsigned char *buf)
486486
*/
487487
static int sd_zbc_check_zone_size(struct scsi_disk *sdkp)
488488
{
489-
u64 zone_blocks;
489+
u64 zone_blocks = 0;
490490
sector_t block = 0;
491491
unsigned char *buf;
492492
unsigned char *rec;
@@ -504,10 +504,8 @@ static int sd_zbc_check_zone_size(struct scsi_disk *sdkp)
504504

505505
/* Do a report zone to get the same field */
506506
ret = sd_zbc_report_zones(sdkp, buf, SD_ZBC_BUF_SIZE, 0);
507-
if (ret) {
508-
zone_blocks = 0;
509-
goto out;
510-
}
507+
if (ret)
508+
goto out_free;
511509

512510
same = buf[4] & 0x0f;
513511
if (same > 0) {
@@ -547,43 +545,40 @@ static int sd_zbc_check_zone_size(struct scsi_disk *sdkp)
547545
ret = sd_zbc_report_zones(sdkp, buf,
548546
SD_ZBC_BUF_SIZE, block);
549547
if (ret)
550-
return ret;
548+
goto out_free;
551549
}
552550

553551
} while (block < sdkp->capacity);
554552

555553
zone_blocks = sdkp->zone_blocks;
556554

557555
out:
558-
kfree(buf);
559-
560556
if (!zone_blocks) {
561557
if (sdkp->first_scan)
562558
sd_printk(KERN_NOTICE, sdkp,
563559
"Devices with non constant zone "
564560
"size are not supported\n");
565-
return -ENODEV;
566-
}
567-
568-
if (!is_power_of_2(zone_blocks)) {
561+
ret = -ENODEV;
562+
} else if (!is_power_of_2(zone_blocks)) {
569563
if (sdkp->first_scan)
570564
sd_printk(KERN_NOTICE, sdkp,
571565
"Devices with non power of 2 zone "
572566
"size are not supported\n");
573-
return -ENODEV;
574-
}
575-
576-
if (logical_to_sectors(sdkp->device, zone_blocks) > UINT_MAX) {
567+
ret = -ENODEV;
568+
} else if (logical_to_sectors(sdkp->device, zone_blocks) > UINT_MAX) {
577569
if (sdkp->first_scan)
578570
sd_printk(KERN_NOTICE, sdkp,
579571
"Zone size too large\n");
580-
return -ENODEV;
572+
ret = -ENODEV;
573+
} else {
574+
sdkp->zone_blocks = zone_blocks;
575+
sdkp->zone_shift = ilog2(zone_blocks);
581576
}
582577

583-
sdkp->zone_blocks = zone_blocks;
584-
sdkp->zone_shift = ilog2(zone_blocks);
578+
out_free:
579+
kfree(buf);
585580

586-
return 0;
581+
return ret;
587582
}
588583

589584
static int sd_zbc_setup(struct scsi_disk *sdkp)

0 commit comments

Comments
 (0)