aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Torokhov <dtor_core@ameritech.net>2006-06-26 01:48:36 -0400
committerDmitry Torokhov <dtor_core@ameritech.net>2006-06-26 01:48:36 -0400
commitf60d2b111cd55c335c2b70e50d66a612d2b10856 (patch)
tree95ec2063e270ad8f87ab07d507d4c20affacb2a5
parentInput: return correct size when reading modalias attribute (diff)
downloadlinux-dev-f60d2b111cd55c335c2b70e50d66a612d2b10856.tar.xz
linux-dev-f60d2b111cd55c335c2b70e50d66a612d2b10856.zip
Input: reset name, phys and uniq when unregistering
Name, phys and uniq are quite often constant strings in moules implementing particular input device. If a module unregisters input device and then gets unloaded, the device could still be present in memory (pinned via sysfs), but aforementioned members would point to some random memory. Set them all to NULL when unregistering so sysfs handlers won't try dereferencing them. Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
-rw-r--r--drivers/input/input.c19
-rw-r--r--include/linux/input.h7
2 files changed, 19 insertions, 7 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c
index b149c9434849..d3cdb139e962 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -29,6 +29,7 @@ MODULE_DESCRIPTION("Input core");
MODULE_LICENSE("GPL");
EXPORT_SYMBOL(input_allocate_device);
+EXPORT_SYMBOL(input_free_device);
EXPORT_SYMBOL(input_register_device);
EXPORT_SYMBOL(input_unregister_device);
EXPORT_SYMBOL(input_register_handler);
@@ -872,6 +873,7 @@ struct input_dev *input_allocate_device(void)
dev->dynalloc = 1;
dev->cdev.class = &input_class;
class_device_initialize(&dev->cdev);
+ mutex_init(&dev->mutex);
INIT_LIST_HEAD(&dev->h_list);
INIT_LIST_HEAD(&dev->node);
}
@@ -879,6 +881,18 @@ struct input_dev *input_allocate_device(void)
return dev;
}
+void input_free_device(struct input_dev *dev)
+{
+ if (dev) {
+
+ mutex_lock(&dev->mutex);
+ dev->name = dev->phys = dev->uniq = NULL;
+ mutex_unlock(&dev->mutex);
+
+ input_put_device(dev);
+ }
+}
+
int input_register_device(struct input_dev *dev)
{
static atomic_t input_no = ATOMIC_INIT(0);
@@ -895,7 +909,6 @@ int input_register_device(struct input_dev *dev)
return -EINVAL;
}
- mutex_init(&dev->mutex);
set_bit(EV_SYN, dev->evbit);
/*
@@ -979,6 +992,10 @@ void input_unregister_device(struct input_dev *dev)
sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group);
class_device_unregister(&dev->cdev);
+ mutex_lock(&dev->mutex);
+ dev->name = dev->phys = dev->uniq = NULL;
+ mutex_unlock(&dev->mutex);
+
input_wakeup_procfs_readers();
}
diff --git a/include/linux/input.h b/include/linux/input.h
index b32c2b6e53f6..8d2b874d9e72 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -1005,6 +1005,7 @@ static inline void init_input_dev(struct input_dev *dev)
}
struct input_dev *input_allocate_device(void);
+void input_free_device(struct input_dev *dev);
static inline struct input_dev *input_get_device(struct input_dev *dev)
{
@@ -1016,12 +1017,6 @@ static inline void input_put_device(struct input_dev *dev)
class_device_put(&dev->cdev);
}
-static inline void input_free_device(struct input_dev *dev)
-{
- if (dev)
- input_put_device(dev);
-}
-
int input_register_device(struct input_dev *);
void input_unregister_device(struct input_dev *);