aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2018-06-12 08:43:35 -0400
committerBorislav Petkov <bp@suse.de>2018-06-18 07:26:05 -0400
commit6c974d4dfafe5e9ee754f2a6fba0eb1864f1649e (patch)
tree11dc79e35c192a794f6e36e996651f727e5507d0
parent4708aa85d50cc6e962dfa8acf5ad4e0d290a21db (diff)
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: Johan Hovold <johan@kernel.org> Cc: Mauro Carvalho Chehab <mchehab@kernel.org> Cc: linux-edac <linux-edac@vger.kernel.org> Fixes: 356f0a30860d ("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>
-rw-r--r--drivers/edac/i7core_edac.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c
index 8ed4dd9c571b..8e120bf60624 100644
--- a/drivers/edac/i7core_edac.c
+++ b/drivers/edac/i7core_edac.c
@@ -1177,15 +1177,14 @@ static int i7core_create_sysfs_devices(struct mem_ctl_info *mci)
1177 1177
1178 rc = device_add(pvt->addrmatch_dev); 1178 rc = device_add(pvt->addrmatch_dev);
1179 if (rc < 0) 1179 if (rc < 0)
1180 return rc; 1180 goto err_put_addrmatch;
1181 1181
1182 if (!pvt->is_registered) { 1182 if (!pvt->is_registered) {
1183 pvt->chancounts_dev = kzalloc(sizeof(*pvt->chancounts_dev), 1183 pvt->chancounts_dev = kzalloc(sizeof(*pvt->chancounts_dev),
1184 GFP_KERNEL); 1184 GFP_KERNEL);
1185 if (!pvt->chancounts_dev) { 1185 if (!pvt->chancounts_dev) {
1186 put_device(pvt->addrmatch_dev); 1186 rc = -ENOMEM;
1187 device_del(pvt->addrmatch_dev); 1187 goto err_del_addrmatch;
1188 return -ENOMEM;
1189 } 1188 }
1190 1189
1191 pvt->chancounts_dev->type = &all_channel_counts_type; 1190 pvt->chancounts_dev->type = &all_channel_counts_type;
@@ -1199,9 +1198,18 @@ static int i7core_create_sysfs_devices(struct mem_ctl_info *mci)
1199 1198
1200 rc = device_add(pvt->chancounts_dev); 1199 rc = device_add(pvt->chancounts_dev);
1201 if (rc < 0) 1200 if (rc < 0)
1202 return rc; 1201 goto err_put_chancounts;
1203 } 1202 }
1204 return 0; 1203 return 0;
1204
1205err_put_chancounts:
1206 put_device(pvt->chancounts_dev);
1207err_del_addrmatch:
1208 device_del(pvt->addrmatch_dev);
1209err_put_addrmatch:
1210 put_device(pvt->addrmatch_dev);
1211
1212 return rc;
1205} 1213}
1206 1214
1207static void i7core_delete_sysfs_devices(struct mem_ctl_info *mci) 1215static 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 edac_dbg(1, "\n"); 1219 edac_dbg(1, "\n");
1212 1220
1213 if (!pvt->is_registered) { 1221 if (!pvt->is_registered) {
1214 put_device(pvt->chancounts_dev);
1215 device_del(pvt->chancounts_dev); 1222 device_del(pvt->chancounts_dev);
1223 put_device(pvt->chancounts_dev);
1216 } 1224 }
1217 put_device(pvt->addrmatch_dev);
1218 device_del(pvt->addrmatch_dev); 1225 device_del(pvt->addrmatch_dev);
1226 put_device(pvt->addrmatch_dev);
1219} 1227}
1220 1228
1221/**************************************************************************** 1229/****************************************************************************