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
parent8a3cf456adbde8317a15fc038cfe82c630512f2e (diff)
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");
29MODULE_LICENSE("GPL"); 29MODULE_LICENSE("GPL");
30 30
31EXPORT_SYMBOL(input_allocate_device); 31EXPORT_SYMBOL(input_allocate_device);
32EXPORT_SYMBOL(input_free_device);
32EXPORT_SYMBOL(input_register_device); 33EXPORT_SYMBOL(input_register_device);
33EXPORT_SYMBOL(input_unregister_device); 34EXPORT_SYMBOL(input_unregister_device);
34EXPORT_SYMBOL(input_register_handler); 35EXPORT_SYMBOL(input_register_handler);
@@ -872,6 +873,7 @@ struct input_dev *input_allocate_device(void)
872 dev->dynalloc = 1; 873 dev->dynalloc = 1;
873 dev->cdev.class = &input_class; 874 dev->cdev.class = &input_class;
874 class_device_initialize(&dev->cdev); 875 class_device_initialize(&dev->cdev);
876 mutex_init(&dev->mutex);
875 INIT_LIST_HEAD(&dev->h_list); 877 INIT_LIST_HEAD(&dev->h_list);
876 INIT_LIST_HEAD(&dev->node); 878 INIT_LIST_HEAD(&dev->node);
877 } 879 }
@@ -879,6 +881,18 @@ struct input_dev *input_allocate_device(void)
879 return dev; 881 return dev;
880} 882}
881 883
884void input_free_device(struct input_dev *dev)
885{
886 if (dev) {
887
888 mutex_lock(&dev->mutex);
889 dev->name = dev->phys = dev->uniq = NULL;
890 mutex_unlock(&dev->mutex);
891
892 input_put_device(dev);
893 }
894}
895
882int input_register_device(struct input_dev *dev) 896int input_register_device(struct input_dev *dev)
883{ 897{
884 static atomic_t input_no = ATOMIC_INIT(0); 898 static atomic_t input_no = ATOMIC_INIT(0);
@@ -895,7 +909,6 @@ int input_register_device(struct input_dev *dev)
895 return -EINVAL; 909 return -EINVAL;
896 } 910 }
897 911
898 mutex_init(&dev->mutex);
899 set_bit(EV_SYN, dev->evbit); 912 set_bit(EV_SYN, dev->evbit);
900 913
901 /* 914 /*
@@ -979,6 +992,10 @@ void input_unregister_device(struct input_dev *dev)
979 sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group); 992 sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group);
980 class_device_unregister(&dev->cdev); 993 class_device_unregister(&dev->cdev);
981 994
995 mutex_lock(&dev->mutex);
996 dev->name = dev->phys = dev->uniq = NULL;
997 mutex_unlock(&dev->mutex);
998
982 input_wakeup_procfs_readers(); 999 input_wakeup_procfs_readers();
983} 1000}
984 1001
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)
1005} 1005}
1006 1006
1007struct input_dev *input_allocate_device(void); 1007struct input_dev *input_allocate_device(void);
1008void input_free_device(struct input_dev *dev);
1008 1009
1009static inline struct input_dev *input_get_device(struct input_dev *dev) 1010static inline struct input_dev *input_get_device(struct input_dev *dev)
1010{ 1011{
@@ -1016,12 +1017,6 @@ static inline void input_put_device(struct input_dev *dev)
1016 class_device_put(&dev->cdev); 1017 class_device_put(&dev->cdev);
1017} 1018}
1018 1019
1019static inline void input_free_device(struct input_dev *dev)
1020{
1021 if (dev)
1022 input_put_device(dev);
1023}
1024
1025int input_register_device(struct input_dev *); 1020int input_register_device(struct input_dev *);
1026void input_unregister_device(struct input_dev *); 1021void input_unregister_device(struct input_dev *);
1027 1022