Skip to content

Commit

Permalink
scsi: core: Fix failure handling of scsi_add_host_with_dma()
Browse files Browse the repository at this point in the history
commit 3719f4f upstream.

When scsi_add_host_with_dma() returns failure, the caller will call
scsi_host_put(shost) to release everything allocated for this host
instance. Consequently we can't also free allocated stuff in
scsi_add_host_with_dma(), otherwise we will end up with a double free.

Strictly speaking, host resource allocations should have been done in
scsi_host_alloc(). However, the allocations may need information which is
not yet provided by the driver when that function is called. So leave the
allocations where they are but rely on host device's release handler to
free resources.

Link: https://lore.kernel.org/r/20210602133029.2864069-3-ming.lei@redhat.com
Cc: Bart Van Assche <bvanassche@acm.org>
Cc: John Garry <john.garry@huawei.com>
Cc: Hannes Reinecke <hare@suse.de>
Tested-by: John Garry <john.garry@huawei.com>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Reviewed-by: John Garry <john.garry@huawei.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Ming Lei authored and gregkh committed Jun 16, 2021
1 parent 45d83db commit 4aaa0d8
Showing 1 changed file with 6 additions and 8 deletions.
14 changes: 6 additions & 8 deletions drivers/scsi/hosts.c
Expand Up @@ -278,23 +278,22 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,

if (!shost->work_q) {
error = -EINVAL;
goto out_free_shost_data;
goto out_del_dev;
}
}

error = scsi_sysfs_add_host(shost);
if (error)
goto out_destroy_host;
goto out_del_dev;

scsi_proc_host_add(shost);
scsi_autopm_put_host(shost);
return error;

out_destroy_host:
if (shost->work_q)
destroy_workqueue(shost->work_q);
out_free_shost_data:
kfree(shost->shost_data);
/*
* Any host allocation in this function will be freed in
* scsi_host_dev_release().
*/
out_del_dev:
device_del(&shost->shost_dev);
out_del_gendev:
Expand All @@ -304,7 +303,6 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
pm_runtime_disable(&shost->shost_gendev);
pm_runtime_set_suspended(&shost->shost_gendev);
pm_runtime_put_noidle(&shost->shost_gendev);
scsi_mq_destroy_tags(shost);
fail:
return error;
}
Expand Down

0 comments on commit 4aaa0d8

Please sign in to comment.