diff options
author | Jean Delvare <khali@linux-fr.org> | 2007-06-12 07:57:19 -0400 |
---|---|---|
committer | Mark M. Hoffman <mhoffman@lightlink.com> | 2007-07-19 14:22:14 -0400 |
commit | 04a6217df28e3004ba4e76eb0a356a30f72c564f (patch) | |
tree | c2361be6f6a778dc769d77aa3e9ebfe0ebea366d /drivers/hwmon | |
parent | ec5e1a4b8faa6a3522171a185a5c6ac9609e14b4 (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>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/abituguru.c | 3 | ||||
-rw-r--r-- | drivers/hwmon/f71805f.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/pc87427.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/smsc47m1.c | 3 | ||||
-rw-r--r-- | drivers/hwmon/vt8231.c | 1 | ||||
-rw-r--r-- | drivers/hwmon/w83627hf.c | 3 |
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) | |||
597 | error_remove_files: | 597 | error_remove_files: |
598 | sysfs_remove_group(&dev->kobj, &smsc47m1_group); | 598 | sysfs_remove_group(&dev->kobj, &smsc47m1_group); |
599 | error_free: | 599 | error_free: |
600 | platform_set_drvdata(pdev, NULL); | ||
600 | kfree(data); | 601 | kfree(data); |
601 | error_release: | 602 | error_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 | ||
745 | exit_free: | 745 | exit_free: |
746 | platform_set_drvdata(pdev, NULL); | ||
746 | kfree(data); | 747 | kfree(data); |
747 | 748 | ||
748 | exit_release: | 749 | exit_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); |