EDAC, i7core: Fix memleaks and use-after-free on probe and remove
[ Upstream commitpull/10/head6c974d4dfa
] Make sure to free and deregister the addrmatch and chancounts devices allocated during probe in all error paths. Also fix use-after-free in a probe error path and in the remove success path where the devices were being put before before deregistration. Signed-off-by: Johan Hovold <johan@kernel.org> Cc: Mauro Carvalho Chehab <mchehab@kernel.org> Cc: linux-edac <linux-edac@vger.kernel.org> Fixes:356f0a3086
("i7core_edac: change the mem allocation scheme to make Documentation/kobject.txt happy") Link: http://lkml.kernel.org/r/20180612124335.6420-2-johan@kernel.org Signed-off-by: Borislav Petkov <bp@suse.de> Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
parent
c96c2f2b11
commit
3fd534a548
|
@ -1177,15 +1177,14 @@ static int i7core_create_sysfs_devices(struct mem_ctl_info *mci)
|
||||||
|
|
||||||
rc = device_add(pvt->addrmatch_dev);
|
rc = device_add(pvt->addrmatch_dev);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return rc;
|
goto err_put_addrmatch;
|
||||||
|
|
||||||
if (!pvt->is_registered) {
|
if (!pvt->is_registered) {
|
||||||
pvt->chancounts_dev = kzalloc(sizeof(*pvt->chancounts_dev),
|
pvt->chancounts_dev = kzalloc(sizeof(*pvt->chancounts_dev),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!pvt->chancounts_dev) {
|
if (!pvt->chancounts_dev) {
|
||||||
put_device(pvt->addrmatch_dev);
|
rc = -ENOMEM;
|
||||||
device_del(pvt->addrmatch_dev);
|
goto err_del_addrmatch;
|
||||||
return -ENOMEM;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pvt->chancounts_dev->type = &all_channel_counts_type;
|
pvt->chancounts_dev->type = &all_channel_counts_type;
|
||||||
|
@ -1199,9 +1198,18 @@ static int i7core_create_sysfs_devices(struct mem_ctl_info *mci)
|
||||||
|
|
||||||
rc = device_add(pvt->chancounts_dev);
|
rc = device_add(pvt->chancounts_dev);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return rc;
|
goto err_put_chancounts;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_put_chancounts:
|
||||||
|
put_device(pvt->chancounts_dev);
|
||||||
|
err_del_addrmatch:
|
||||||
|
device_del(pvt->addrmatch_dev);
|
||||||
|
err_put_addrmatch:
|
||||||
|
put_device(pvt->addrmatch_dev);
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void i7core_delete_sysfs_devices(struct mem_ctl_info *mci)
|
static void i7core_delete_sysfs_devices(struct mem_ctl_info *mci)
|
||||||
|
@ -1211,11 +1219,11 @@ static void i7core_delete_sysfs_devices(struct mem_ctl_info *mci)
|
||||||
edac_dbg(1, "\n");
|
edac_dbg(1, "\n");
|
||||||
|
|
||||||
if (!pvt->is_registered) {
|
if (!pvt->is_registered) {
|
||||||
put_device(pvt->chancounts_dev);
|
|
||||||
device_del(pvt->chancounts_dev);
|
device_del(pvt->chancounts_dev);
|
||||||
|
put_device(pvt->chancounts_dev);
|
||||||
}
|
}
|
||||||
put_device(pvt->addrmatch_dev);
|
|
||||||
device_del(pvt->addrmatch_dev);
|
device_del(pvt->addrmatch_dev);
|
||||||
|
put_device(pvt->addrmatch_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|
Loading…
Reference in New Issue