scsi: iscsi: Fix possible memory leak when device_register() failed
[ Upstream commit f014165faa
]
If device_register() returns error, the name allocated by the
dev_set_name() need be freed. As described in the comment of
device_register(), we should use put_device() to give up the reference in
the error path.
Fix this by calling put_device(), the name will be freed in the
kobject_cleanup(), and this patch modified resources will be released by
calling the corresponding callback function in the device_release().
Signed-off-by: Zhou Guanghui <zhouguanghui1@huawei.com>
Link: https://lore.kernel.org/r/20221110033729.1555-1-zhouguanghui1@huawei.com
Reviewed-by: Mike Christie <michael.christie@oracle.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Родитель
56ab7f237e
Коммит
97f47617e8
|
@ -232,7 +232,7 @@ iscsi_create_endpoint(int dd_size)
|
||||||
dev_set_name(&ep->dev, "ep-%d", id);
|
dev_set_name(&ep->dev, "ep-%d", id);
|
||||||
err = device_register(&ep->dev);
|
err = device_register(&ep->dev);
|
||||||
if (err)
|
if (err)
|
||||||
goto free_id;
|
goto put_dev;
|
||||||
|
|
||||||
err = sysfs_create_group(&ep->dev.kobj, &iscsi_endpoint_group);
|
err = sysfs_create_group(&ep->dev.kobj, &iscsi_endpoint_group);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -246,10 +246,12 @@ unregister_dev:
|
||||||
device_unregister(&ep->dev);
|
device_unregister(&ep->dev);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
free_id:
|
put_dev:
|
||||||
mutex_lock(&iscsi_ep_idr_mutex);
|
mutex_lock(&iscsi_ep_idr_mutex);
|
||||||
idr_remove(&iscsi_ep_idr, id);
|
idr_remove(&iscsi_ep_idr, id);
|
||||||
mutex_unlock(&iscsi_ep_idr_mutex);
|
mutex_unlock(&iscsi_ep_idr_mutex);
|
||||||
|
put_device(&ep->dev);
|
||||||
|
return NULL;
|
||||||
free_ep:
|
free_ep:
|
||||||
kfree(ep);
|
kfree(ep);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -767,7 +769,7 @@ iscsi_create_iface(struct Scsi_Host *shost, struct iscsi_transport *transport,
|
||||||
|
|
||||||
err = device_register(&iface->dev);
|
err = device_register(&iface->dev);
|
||||||
if (err)
|
if (err)
|
||||||
goto free_iface;
|
goto put_dev;
|
||||||
|
|
||||||
err = sysfs_create_group(&iface->dev.kobj, &iscsi_iface_group);
|
err = sysfs_create_group(&iface->dev.kobj, &iscsi_iface_group);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -781,9 +783,8 @@ unreg_iface:
|
||||||
device_unregister(&iface->dev);
|
device_unregister(&iface->dev);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
free_iface:
|
put_dev:
|
||||||
put_device(iface->dev.parent);
|
put_device(&iface->dev);
|
||||||
kfree(iface);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(iscsi_create_iface);
|
EXPORT_SYMBOL_GPL(iscsi_create_iface);
|
||||||
|
@ -1252,15 +1253,15 @@ iscsi_create_flashnode_sess(struct Scsi_Host *shost, int index,
|
||||||
|
|
||||||
err = device_register(&fnode_sess->dev);
|
err = device_register(&fnode_sess->dev);
|
||||||
if (err)
|
if (err)
|
||||||
goto free_fnode_sess;
|
goto put_dev;
|
||||||
|
|
||||||
if (dd_size)
|
if (dd_size)
|
||||||
fnode_sess->dd_data = &fnode_sess[1];
|
fnode_sess->dd_data = &fnode_sess[1];
|
||||||
|
|
||||||
return fnode_sess;
|
return fnode_sess;
|
||||||
|
|
||||||
free_fnode_sess:
|
put_dev:
|
||||||
kfree(fnode_sess);
|
put_device(&fnode_sess->dev);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(iscsi_create_flashnode_sess);
|
EXPORT_SYMBOL_GPL(iscsi_create_flashnode_sess);
|
||||||
|
@ -1300,15 +1301,15 @@ iscsi_create_flashnode_conn(struct Scsi_Host *shost,
|
||||||
|
|
||||||
err = device_register(&fnode_conn->dev);
|
err = device_register(&fnode_conn->dev);
|
||||||
if (err)
|
if (err)
|
||||||
goto free_fnode_conn;
|
goto put_dev;
|
||||||
|
|
||||||
if (dd_size)
|
if (dd_size)
|
||||||
fnode_conn->dd_data = &fnode_conn[1];
|
fnode_conn->dd_data = &fnode_conn[1];
|
||||||
|
|
||||||
return fnode_conn;
|
return fnode_conn;
|
||||||
|
|
||||||
free_fnode_conn:
|
put_dev:
|
||||||
kfree(fnode_conn);
|
put_device(&fnode_conn->dev);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(iscsi_create_flashnode_conn);
|
EXPORT_SYMBOL_GPL(iscsi_create_flashnode_conn);
|
||||||
|
@ -4838,7 +4839,7 @@ iscsi_register_transport(struct iscsi_transport *tt)
|
||||||
dev_set_name(&priv->dev, "%s", tt->name);
|
dev_set_name(&priv->dev, "%s", tt->name);
|
||||||
err = device_register(&priv->dev);
|
err = device_register(&priv->dev);
|
||||||
if (err)
|
if (err)
|
||||||
goto free_priv;
|
goto put_dev;
|
||||||
|
|
||||||
err = sysfs_create_group(&priv->dev.kobj, &iscsi_transport_group);
|
err = sysfs_create_group(&priv->dev.kobj, &iscsi_transport_group);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -4873,8 +4874,8 @@ iscsi_register_transport(struct iscsi_transport *tt)
|
||||||
unregister_dev:
|
unregister_dev:
|
||||||
device_unregister(&priv->dev);
|
device_unregister(&priv->dev);
|
||||||
return NULL;
|
return NULL;
|
||||||
free_priv:
|
put_dev:
|
||||||
kfree(priv);
|
put_device(&priv->dev);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(iscsi_register_transport);
|
EXPORT_SYMBOL_GPL(iscsi_register_transport);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче