Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=04a6217df28e3004ba4e76eb0a356a30f72c564f
Commit:     04a6217df28e3004ba4e76eb0a356a30f72c564f
Parent:     ec5e1a4b8faa6a3522171a185a5c6ac9609e14b4
Author:     Jean Delvare <[EMAIL PROTECTED]>
AuthorDate: Tue Jun 12 13:57:19 2007 +0200
Committer:  Mark M. Hoffman <[EMAIL PROTECTED]>
CommitDate: Thu Jul 19 14:22:14 2007 -0400

    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 <[EMAIL PROTECTED]>
    Signed-off-by: Mark M. Hoffman <[EMAIL PROTECTED]>
---
 drivers/hwmon/abituguru.c |    3 ++-
 drivers/hwmon/f71805f.c   |    2 +-
 drivers/hwmon/pc87427.c   |    2 +-
 drivers/hwmon/smsc47m1.c  |    3 ++-
 drivers/hwmon/vt8231.c    |    1 +
 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 bede4d9..11a40da 100644
--- a/drivers/hwmon/abituguru.c
+++ b/drivers/hwmon/abituguru.c
@@ -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;
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c
index e8b1504..8fe4d70 100644
--- a/drivers/hwmon/f71805f.c
+++ b/drivers/hwmon/f71805f.c
@@ -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);
diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c
index 29354fa..2915bc4 100644
--- a/drivers/hwmon/pc87427.c
+++ b/drivers/hwmon/pc87427.c
@@ -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);
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c
index 9bac3c2..1de2f2b 100644
--- a/drivers/hwmon/smsc47m1.c
+++ b/drivers/hwmon/smsc47m1.c
@@ -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;
diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c
index 320d814..c604972 100644
--- a/drivers/hwmon/vt8231.c
+++ b/drivers/hwmon/vt8231.c
@@ -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:
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index cd95360..1ce7817 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -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);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to