lkml.org 
[lkml]   [2018]   [Jun]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.14 01/41] scsi: sd_zbc: Fix potential memory leak
    Date
    4.14-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Damien Le Moal <damien.lemoal@wdc.com>

    commit 4b433924b2755a94f99258c178684a0e05c344de upstream.

    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 <david.butterfield@wdc.com>
    Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
    Cc: stable@vger.kernel.org
    Reviewed-by: Bart Van Assche <bart.vanassche@wdc.com>
    Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/scsi/sd_zbc.c | 34 +++++++++++++++-------------------
    1 file changed, 15 insertions(+), 19 deletions(-)

    --- a/drivers/scsi/sd_zbc.c
    +++ b/drivers/scsi/sd_zbc.c
    @@ -425,7 +425,7 @@ static int sd_zbc_check_capacity(struct

    static int sd_zbc_check_zone_size(struct scsi_disk *sdkp)
    {
    - u64 zone_blocks;
    + u64 zone_blocks = 0;
    sector_t block = 0;
    unsigned char *buf;
    unsigned char *rec;
    @@ -443,10 +443,8 @@ static int sd_zbc_check_zone_size(struct

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

    same = buf[4] & 0x0f;
    if (same > 0) {
    @@ -489,7 +487,7 @@ static int sd_zbc_check_zone_size(struct
    ret = sd_zbc_report_zones(sdkp, buf,
    SD_ZBC_BUF_SIZE, block);
    if (ret)
    - return ret;
    + goto out_free;
    }

    } while (block < sdkp->capacity);
    @@ -497,34 +495,32 @@ static int sd_zbc_check_zone_size(struct
    zone_blocks = sdkp->zone_blocks;

    out:
    - kfree(buf);
    -
    if (!zone_blocks) {
    if (sdkp->first_scan)
    sd_printk(KERN_NOTICE, sdkp,
    "Devices with non constant zone "
    "size are not supported\n");
    - return -ENODEV;
    - }
    -
    - if (!is_power_of_2(zone_blocks)) {
    + ret = -ENODEV;
    + } else if (!is_power_of_2(zone_blocks)) {
    if (sdkp->first_scan)
    sd_printk(KERN_NOTICE, sdkp,
    "Devices with non power of 2 zone "
    "size are not supported\n");
    - return -ENODEV;
    - }
    -
    - if (logical_to_sectors(sdkp->device, zone_blocks) > UINT_MAX) {
    + ret = -ENODEV;
    + } else if (logical_to_sectors(sdkp->device, zone_blocks) > UINT_MAX) {
    if (sdkp->first_scan)
    sd_printk(KERN_NOTICE, sdkp,
    "Zone size too large\n");
    - return -ENODEV;
    + ret = -ENODEV;
    + } else {
    + sdkp->zone_blocks = zone_blocks;
    + sdkp->zone_shift = ilog2(zone_blocks);
    }

    - sdkp->zone_blocks = zone_blocks;
    +out_free:
    + kfree(buf);

    - return 0;
    + return ret;
    }

    static int sd_zbc_setup(struct scsi_disk *sdkp)

    \
     
     \ /
      Last update: 2018-06-09 17:35    [W:4.327 / U:0.432 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site