diff options
author | Yang Yingliang <yangyingliang@huawei.com> | 2022-11-12 12:43:10 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2023-01-14 12:15:51 +0300 |
commit | 9d0ad1e2bae72ae7f97d5374bb2d7b46c5ca7bd6 (patch) | |
tree | 9b128873eada4bcd1ea82e64731a38affc4f75ac /drivers/scsi | |
parent | 2b142f6046ceb19e35ea77b9ad4578f19d751eb9 (diff) | |
download | linux-9d0ad1e2bae72ae7f97d5374bb2d7b46c5ca7bd6.tar.xz |
scsi: fcoe: Fix possible name leak when device_register() fails
[ Upstream commit 47b6a122c7b69a876c7ee2fc064a26b09627de9d ]
If device_register() returns an error, the name allocated by dev_set_name()
needs to be freed. As the comment of device_register() says, one should use
put_device() to give up the reference in the error path. Fix this by
calling put_device(), then the name can be freed in kobject_cleanup().
The 'fcf' is freed in fcoe_fcf_device_release(), so the kfree() in the
error path can be removed.
The 'ctlr' is freed in fcoe_ctlr_device_release(), so don't use the error
label, just return NULL after calling put_device().
Fixes: 9a74e884ee71 ("[SCSI] libfcoe: Add fcoe_sysfs")
Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
Link: https://lore.kernel.org/r/20221112094310.3633291-1-yangyingliang@huawei.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/fcoe/fcoe_sysfs.c | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/drivers/scsi/fcoe/fcoe_sysfs.c b/drivers/scsi/fcoe/fcoe_sysfs.c index ffef2c8eddc6..68d8027d5108 100644 --- a/drivers/scsi/fcoe/fcoe_sysfs.c +++ b/drivers/scsi/fcoe/fcoe_sysfs.c @@ -830,14 +830,15 @@ struct fcoe_ctlr_device *fcoe_ctlr_device_add(struct device *parent, dev_set_name(&ctlr->dev, "ctlr_%d", ctlr->id); error = device_register(&ctlr->dev); - if (error) - goto out_del_q2; + if (error) { + destroy_workqueue(ctlr->devloss_work_q); + destroy_workqueue(ctlr->work_q); + put_device(&ctlr->dev); + return NULL; + } return ctlr; -out_del_q2: - destroy_workqueue(ctlr->devloss_work_q); - ctlr->devloss_work_q = NULL; out_del_q: destroy_workqueue(ctlr->work_q); ctlr->work_q = NULL; @@ -1036,16 +1037,16 @@ struct fcoe_fcf_device *fcoe_fcf_device_add(struct fcoe_ctlr_device *ctlr, fcf->selected = new_fcf->selected; error = device_register(&fcf->dev); - if (error) - goto out_del; + if (error) { + put_device(&fcf->dev); + goto out; + } fcf->state = FCOE_FCF_STATE_CONNECTED; list_add_tail(&fcf->peers, &ctlr->fcfs); return fcf; -out_del: - kfree(fcf); out: return NULL; } |