提交 80b8678a 编写于 作者: M Ming Lei 提交者: Wang ShaoBo

scsi: core: Fix failure handling of scsi_add_host_with_dma()

stable inclusion
from stable-v5.10.44
commit 146446a43b3dbaa3a58364ef99fd606b3f324832
bugzilla: https://bugzilla.openeuler.org/show_bug.cgi?id=361
CVE: NA

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

commit 3719f4ff 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: NJohn Garry <john.garry@huawei.com>
Reviewed-by: NBart Van Assche <bvanassche@acm.org>
Reviewed-by: NJohn Garry <john.garry@huawei.com>
Reviewed-by: NHannes Reinecke <hare@suse.de>
Signed-off-by: NMing Lei <ming.lei@redhat.com>
Signed-off-by: NMartin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Ndongenyang <sdlpdey@163.com>
Reviewed-by: NJian Cheng <cj.chengjian@huawei.com>
Signed-off-by: NWang ShaoBo <bobo.shaobowang@huawei.com>
上级 00d3f87c
...@@ -278,23 +278,22 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, ...@@ -278,23 +278,22 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
if (!shost->work_q) { if (!shost->work_q) {
error = -EINVAL; error = -EINVAL;
goto out_free_shost_data; goto out_del_dev;
} }
} }
error = scsi_sysfs_add_host(shost); error = scsi_sysfs_add_host(shost);
if (error) if (error)
goto out_destroy_host; goto out_del_dev;
scsi_proc_host_add(shost); scsi_proc_host_add(shost);
scsi_autopm_put_host(shost); scsi_autopm_put_host(shost);
return error; return error;
out_destroy_host: /*
if (shost->work_q) * Any host allocation in this function will be freed in
destroy_workqueue(shost->work_q); * scsi_host_dev_release().
out_free_shost_data: */
kfree(shost->shost_data);
out_del_dev: out_del_dev:
device_del(&shost->shost_dev); device_del(&shost->shost_dev);
out_del_gendev: out_del_gendev:
...@@ -304,7 +303,6 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, ...@@ -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_disable(&shost->shost_gendev);
pm_runtime_set_suspended(&shost->shost_gendev); pm_runtime_set_suspended(&shost->shost_gendev);
pm_runtime_put_noidle(&shost->shost_gendev); pm_runtime_put_noidle(&shost->shost_gendev);
scsi_mq_destroy_tags(shost);
fail: fail:
return error; return error;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册