summaryrefslogtreecommitdiffstats
path: root/drivers/staging/android
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-08-24 10:27:29 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-08-24 10:27:29 -0700
commit9d3ab801740ab5ff1e22932fdfecdaacd0d64a18 (patch)
tree70061c043912a0e7dd36c36428160e87f5eb040a /drivers/staging/android
parent76e1f486b2e6775bba31118b362e01ea6033a0e6 (diff)
downloadlinux-9d3ab801740ab5ff1e22932fdfecdaacd0d64a18.tar.bz2
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.c27
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);
}