Commit 6c974d4d authored by Johan Hovold's avatar Johan Hovold Committed by Borislav Petkov

EDAC, i7core: Fix memleaks and use-after-free on probe and remove

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: default avatarJohan Hovold <johan@kernel.org>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: linux-edac <linux-edac@vger.kernel.org>
Fixes: 356f0a30 ("i7core_edac: change the mem allocation scheme to make Documentation/kobject.txt happy")
Link: http://lkml.kernel.org/r/20180612124335.6420-2-johan@kernel.orgSigned-off-by: default avatarBorislav Petkov <bp@suse.de>
parent 4708aa85
...@@ -1177,15 +1177,14 @@ static int i7core_create_sysfs_devices(struct mem_ctl_info *mci) ...@@ -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) ...@@ -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) ...@@ -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);
} }
/**************************************************************************** /****************************************************************************
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment