aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2007-06-12 07:57:19 -0400
committerMark M. Hoffman <mhoffman@lightlink.com>2007-07-19 14:22:14 -0400
commit04a6217df28e3004ba4e76eb0a356a30f72c564f (patch)
treec2361be6f6a778dc769d77aa3e9ebfe0ebea366d
parentec5e1a4b8faa6a3522171a185a5c6ac9609e14b4 (diff)
hwmon: Fix a potential race condition on unload
Fix a potential race condition when some hardware monitoring platform drivers are being unloaded. I believe that the driver data pointer shouldn't be cleared before all the sysfs files are removed, otherwise a sysfs callback might attempt to dereference a NULL pointer. I'm not sure exactly what the driver core protects drivers against, so let's play it safe. While we're here, clear the driver data pointer when probe fails, so as to not leave an invalid pointer behind us. Signed-off-by: Jean Delvare <khali@linux-fr.org> Signed-off-by: Mark M. Hoffman <mhoffman@lightlink.com>
-rw-r--r--drivers/hwmon/abituguru.c3
-rw-r--r--drivers/hwmon/f71805f.c2
-rw-r--r--drivers/hwmon/pc87427.c2
-rw-r--r--drivers/hwmon/smsc47m1.c3
-rw-r--r--drivers/hwmon/vt8231.c1
-rw-r--r--drivers/hwmon/w83627hf.c3
6 files changed, 9 insertions, 5 deletions
diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c
index bede4d990ea6..11a40da13535 100644
--- a/drivers/hwmon/abituguru.c
+++ b/drivers/hwmon/abituguru.c
@@ -1287,6 +1287,7 @@ abituguru_probe_error:
1287 for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) 1287 for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++)
1288 device_remove_file(&pdev->dev, 1288 device_remove_file(&pdev->dev,
1289 &abituguru_sysfs_attr[i].dev_attr); 1289 &abituguru_sysfs_attr[i].dev_attr);
1290 platform_set_drvdata(pdev, NULL);
1290 kfree(data); 1291 kfree(data);
1291 return res; 1292 return res;
1292} 1293}
@@ -1296,13 +1297,13 @@ static int __devexit abituguru_remove(struct platform_device *pdev)
1296 int i; 1297 int i;
1297 struct abituguru_data *data = platform_get_drvdata(pdev); 1298 struct abituguru_data *data = platform_get_drvdata(pdev);
1298 1299
1299 platform_set_drvdata(pdev, NULL);
1300 hwmon_device_unregister(data->class_dev); 1300 hwmon_device_unregister(data->class_dev);
1301 for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++) 1301 for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++)
1302 device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr); 1302 device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr);
1303 for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) 1303 for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++)
1304 device_remove_file(&pdev->dev, 1304 device_remove_file(&pdev->dev,
1305 &abituguru_sysfs_attr[i].dev_attr); 1305 &abituguru_sysfs_attr[i].dev_attr);
1306 platform_set_drvdata(pdev, NULL);
1306 kfree(data); 1307 kfree(data);
1307 1308
1308 return 0; 1309 return 0;
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c
index e8b15047a6d3..8fe4d70d8f51 100644
--- a/drivers/hwmon/f71805f.c
+++ b/drivers/hwmon/f71805f.c
@@ -1242,12 +1242,12 @@ static int __devexit f71805f_remove(struct platform_device *pdev)
1242 struct resource *res; 1242 struct resource *res;
1243 int i; 1243 int i;
1244 1244
1245 platform_set_drvdata(pdev, NULL);
1246 hwmon_device_unregister(data->class_dev); 1245 hwmon_device_unregister(data->class_dev);
1247 sysfs_remove_group(&pdev->dev.kobj, &f71805f_group); 1246 sysfs_remove_group(&pdev->dev.kobj, &f71805f_group);
1248 for (i = 0; i < 4; i++) 1247 for (i = 0; i < 4; i++)
1249 sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]); 1248 sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]);
1250 sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_pwm_freq); 1249 sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_pwm_freq);
1250 platform_set_drvdata(pdev, NULL);
1251 kfree(data); 1251 kfree(data);
1252 1252
1253 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 1253 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c
index 29354fa26f81..2915bc4ad0d5 100644
--- a/drivers/hwmon/pc87427.c
+++ b/drivers/hwmon/pc87427.c
@@ -484,7 +484,6 @@ static int __devexit pc87427_remove(struct platform_device *pdev)
484 struct resource *res; 484 struct resource *res;
485 int i; 485 int i;
486 486
487 platform_set_drvdata(pdev, NULL);
488 hwmon_device_unregister(data->class_dev); 487 hwmon_device_unregister(data->class_dev);
489 device_remove_file(&pdev->dev, &dev_attr_name); 488 device_remove_file(&pdev->dev, &dev_attr_name);
490 for (i = 0; i < 8; i++) { 489 for (i = 0; i < 8; i++) {
@@ -492,6 +491,7 @@ static int __devexit pc87427_remove(struct platform_device *pdev)
492 continue; 491 continue;
493 sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]); 492 sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]);
494 } 493 }
494 platform_set_drvdata(pdev, NULL);
495 kfree(data); 495 kfree(data);
496 496
497 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 497 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c
index 9bac3c2d84f9..1de2f2be8708 100644
--- a/drivers/hwmon/smsc47m1.c
+++ b/drivers/hwmon/smsc47m1.c
@@ -597,6 +597,7 @@ static int __devinit smsc47m1_probe(struct platform_device *pdev)
597error_remove_files: 597error_remove_files:
598 sysfs_remove_group(&dev->kobj, &smsc47m1_group); 598 sysfs_remove_group(&dev->kobj, &smsc47m1_group);
599error_free: 599error_free:
600 platform_set_drvdata(pdev, NULL);
600 kfree(data); 601 kfree(data);
601error_release: 602error_release:
602 release_region(res->start, SMSC_EXTENT); 603 release_region(res->start, SMSC_EXTENT);
@@ -608,12 +609,12 @@ static int __devexit smsc47m1_remove(struct platform_device *pdev)
608 struct smsc47m1_data *data = platform_get_drvdata(pdev); 609 struct smsc47m1_data *data = platform_get_drvdata(pdev);
609 struct resource *res; 610 struct resource *res;
610 611
611 platform_set_drvdata(pdev, NULL);
612 hwmon_device_unregister(data->class_dev); 612 hwmon_device_unregister(data->class_dev);
613 sysfs_remove_group(&pdev->dev.kobj, &smsc47m1_group); 613 sysfs_remove_group(&pdev->dev.kobj, &smsc47m1_group);
614 614
615 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 615 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
616 release_region(res->start, SMSC_EXTENT); 616 release_region(res->start, SMSC_EXTENT);
617 platform_set_drvdata(pdev, NULL);
617 kfree(data); 618 kfree(data);
618 619
619 return 0; 620 return 0;
diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c
index 320d8141be78..c604972f0186 100644
--- a/drivers/hwmon/vt8231.c
+++ b/drivers/hwmon/vt8231.c
@@ -743,6 +743,7 @@ exit_remove_files:
743 sysfs_remove_group(&pdev->dev.kobj, &vt8231_group); 743 sysfs_remove_group(&pdev->dev.kobj, &vt8231_group);
744 744
745exit_free: 745exit_free:
746 platform_set_drvdata(pdev, NULL);
746 kfree(data); 747 kfree(data);
747 748
748exit_release: 749exit_release:
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index cd953604c38f..1ce78179b005 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -1306,6 +1306,7 @@ static int __devinit w83627hf_probe(struct platform_device *pdev)
1306 sysfs_remove_group(&dev->kobj, &w83627hf_group); 1306 sysfs_remove_group(&dev->kobj, &w83627hf_group);
1307 sysfs_remove_group(&dev->kobj, &w83627hf_group_opt); 1307 sysfs_remove_group(&dev->kobj, &w83627hf_group_opt);
1308 ERROR3: 1308 ERROR3:
1309 platform_set_drvdata(pdev, NULL);
1309 kfree(data); 1310 kfree(data);
1310 ERROR1: 1311 ERROR1:
1311 release_region(res->start, WINB_REGION_SIZE); 1312 release_region(res->start, WINB_REGION_SIZE);
@@ -1318,11 +1319,11 @@ static int __devexit w83627hf_remove(struct platform_device *pdev)
1318 struct w83627hf_data *data = platform_get_drvdata(pdev); 1319 struct w83627hf_data *data = platform_get_drvdata(pdev);
1319 struct resource *res; 1320 struct resource *res;
1320 1321
1321 platform_set_drvdata(pdev, NULL);
1322 hwmon_device_unregister(data->class_dev); 1322 hwmon_device_unregister(data->class_dev);
1323 1323
1324 sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group); 1324 sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group);
1325 sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group_opt); 1325 sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group_opt);
1326 platform_set_drvdata(pdev, NULL);
1326 kfree(data); 1327 kfree(data);
1327 1328
1328 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 1329 res = platform_get_resource(pdev, IORESOURCE_IO, 0);