소스 검색

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>
Dmitry Torokhov 19 년 전
부모
커밋
f60d2b111c
2개의 변경된 파일19개의 추가작업 그리고 7개의 파일을 삭제
  1. 18 1
      drivers/input/input.c
  2. 1 6
      include/linux/input.h

+ 18 - 1
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();
 }
 

+ 1 - 6
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 *);