mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-11-07 04:09:21 +00:00
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>
This commit is contained in:
parent
ec5e1a4b8f
commit
04a6217df2
6 changed files with 9 additions and 5 deletions
|
@ -1287,6 +1287,7 @@ abituguru_probe_error:
|
|||
for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++)
|
||||
device_remove_file(&pdev->dev,
|
||||
&abituguru_sysfs_attr[i].dev_attr);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
kfree(data);
|
||||
return res;
|
||||
}
|
||||
|
@ -1296,13 +1297,13 @@ static int __devexit abituguru_remove(struct platform_device *pdev)
|
|||
int i;
|
||||
struct abituguru_data *data = platform_get_drvdata(pdev);
|
||||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
hwmon_device_unregister(data->class_dev);
|
||||
for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++)
|
||||
device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr);
|
||||
for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++)
|
||||
device_remove_file(&pdev->dev,
|
||||
&abituguru_sysfs_attr[i].dev_attr);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
kfree(data);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -1242,12 +1242,12 @@ static int __devexit f71805f_remove(struct platform_device *pdev)
|
|||
struct resource *res;
|
||||
int i;
|
||||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
hwmon_device_unregister(data->class_dev);
|
||||
sysfs_remove_group(&pdev->dev.kobj, &f71805f_group);
|
||||
for (i = 0; i < 4; i++)
|
||||
sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]);
|
||||
sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_pwm_freq);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
kfree(data);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
||||
|
|
|
@ -484,7 +484,6 @@ static int __devexit pc87427_remove(struct platform_device *pdev)
|
|||
struct resource *res;
|
||||
int i;
|
||||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
hwmon_device_unregister(data->class_dev);
|
||||
device_remove_file(&pdev->dev, &dev_attr_name);
|
||||
for (i = 0; i < 8; i++) {
|
||||
|
@ -492,6 +491,7 @@ static int __devexit pc87427_remove(struct platform_device *pdev)
|
|||
continue;
|
||||
sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]);
|
||||
}
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
kfree(data);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
||||
|
|
|
@ -597,6 +597,7 @@ static int __devinit smsc47m1_probe(struct platform_device *pdev)
|
|||
error_remove_files:
|
||||
sysfs_remove_group(&dev->kobj, &smsc47m1_group);
|
||||
error_free:
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
kfree(data);
|
||||
error_release:
|
||||
release_region(res->start, SMSC_EXTENT);
|
||||
|
@ -608,12 +609,12 @@ static int __devexit smsc47m1_remove(struct platform_device *pdev)
|
|||
struct smsc47m1_data *data = platform_get_drvdata(pdev);
|
||||
struct resource *res;
|
||||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
hwmon_device_unregister(data->class_dev);
|
||||
sysfs_remove_group(&pdev->dev.kobj, &smsc47m1_group);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
||||
release_region(res->start, SMSC_EXTENT);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
kfree(data);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -743,6 +743,7 @@ exit_remove_files:
|
|||
sysfs_remove_group(&pdev->dev.kobj, &vt8231_group);
|
||||
|
||||
exit_free:
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
kfree(data);
|
||||
|
||||
exit_release:
|
||||
|
|
|
@ -1306,6 +1306,7 @@ static int __devinit w83627hf_probe(struct platform_device *pdev)
|
|||
sysfs_remove_group(&dev->kobj, &w83627hf_group);
|
||||
sysfs_remove_group(&dev->kobj, &w83627hf_group_opt);
|
||||
ERROR3:
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
kfree(data);
|
||||
ERROR1:
|
||||
release_region(res->start, WINB_REGION_SIZE);
|
||||
|
@ -1318,11 +1319,11 @@ static int __devexit w83627hf_remove(struct platform_device *pdev)
|
|||
struct w83627hf_data *data = platform_get_drvdata(pdev);
|
||||
struct resource *res;
|
||||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
hwmon_device_unregister(data->class_dev);
|
||||
|
||||
sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group);
|
||||
sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group_opt);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
kfree(data);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
||||
|
|
Loading…
Reference in a new issue