Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 16b20773 authored by Yang Yingliang's avatar Yang Yingliang Committed by Greg Kroah-Hartman
Browse files

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: 9a74e884 ("[SCSI] libfcoe: Add fcoe_sysfs")
Signed-off-by: default avatarYang Yingliang <yangyingliang@huawei.com>
Link: https://lore.kernel.org/r/20221112094310.3633291-1-yangyingliang@huawei.com


Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 07e97ce1
Loading
Loading
Loading
Loading
+10 −9
Original line number Diff line number Diff line
@@ -752,14 +752,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;
@@ -958,16 +959,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;
}