diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-08-24 10:27:29 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-08-24 10:27:29 -0700 |
commit | 9d3ab801740ab5ff1e22932fdfecdaacd0d64a18 (patch) | |
tree | 70061c043912a0e7dd36c36428160e87f5eb040a /drivers/staging/android | |
parent | 76e1f486b2e6775bba31118b362e01ea6033a0e6 (diff) |
staging: android: timed_output: fix sysfs file creation race
The sysfs file for the driver was being created _after_ the device was
announced to userspace, causing a race with any tools looking for sysfs
files.
Fix the race by using the default attribute group for the class.
Cc: Kees Cook <keescook@chromium.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/android')
-rw-r--r-- | drivers/staging/android/timed_output.c | 27 |
1 files changed, 10 insertions, 17 deletions
diff --git a/drivers/staging/android/timed_output.c b/drivers/staging/android/timed_output.c index ee3a57f22832..2c617834dc46 100644 --- a/drivers/staging/android/timed_output.c +++ b/drivers/staging/android/timed_output.c @@ -28,7 +28,7 @@ static struct class *timed_output_class; static atomic_t device_count; static ssize_t enable_show(struct device *dev, struct device_attribute *attr, - char *buf) + char *buf) { struct timed_output_dev *tdev = dev_get_drvdata(dev); int remaining = tdev->get_time(tdev); @@ -36,9 +36,8 @@ static ssize_t enable_show(struct device *dev, struct device_attribute *attr, return sprintf(buf, "%d\n", remaining); } -static ssize_t enable_store( - struct device *dev, struct device_attribute *attr, - const char *buf, size_t size) +static ssize_t enable_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) { struct timed_output_dev *tdev = dev_get_drvdata(dev); int value; @@ -50,8 +49,13 @@ static ssize_t enable_store( return size; } +static DEVICE_ATTR_RW(enable); -static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store); +static struct attribute *timed_output_attrs[] = { + &dev_attr_enable.attr, + NULL, +}; +ATTRIBUTE_GROUPS(timed_output); static int create_timed_output_class(void) { @@ -60,6 +64,7 @@ static int create_timed_output_class(void) if (IS_ERR(timed_output_class)) return PTR_ERR(timed_output_class); atomic_set(&device_count, 0); + timed_output_class->dev_groups = timed_output_groups; } return 0; @@ -82,27 +87,15 @@ int timed_output_dev_register(struct timed_output_dev *tdev) if (IS_ERR(tdev->dev)) return PTR_ERR(tdev->dev); - ret = device_create_file(tdev->dev, &dev_attr_enable); - if (ret < 0) - goto err_create_file; - dev_set_drvdata(tdev->dev, tdev); tdev->state = 0; return 0; - -err_create_file: - device_destroy(timed_output_class, MKDEV(0, tdev->index)); - pr_err("failed to register driver %s\n", - tdev->name); - - return ret; } EXPORT_SYMBOL_GPL(timed_output_dev_register); void timed_output_dev_unregister(struct timed_output_dev *tdev) { tdev->enable(tdev, 0); - device_remove_file(tdev->dev, &dev_attr_enable); device_destroy(timed_output_class, MKDEV(0, tdev->index)); dev_set_drvdata(tdev->dev, NULL); } |