summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiri Slaby <jslaby@suse.cz>2010-10-19 11:29:55 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2011-01-07 14:43:13 -0800
commit32aba3cf35c2fd0dde82d1acac9c76424f576c67 (patch)
tree0c1325844845835e41c388d36e50692d1fc8f075
parentec955e326e90b693011f6429b4cc0a72fe795168 (diff)
HID: hidraw: fix window in hidraw_release
commit cb174681a9ececa6702f114b85bdf82144b6a5af upstream. [ Backport to .32.y by Antonio Ospite <ospite@studenti.unina.it> ] There is a window between hidraw_table check and its dereference. In that window, the device may be unplugged and removed form the system and we will then dereference NULL. Lock that place properly so that either we get NULL and jump out or we can work with real pointer. Signed-off-by: Jiri Slaby <jslaby@suse.cz> Signed-off-by: Jiri Kosina <jkosina@suse.cz> Signed-off-by: Antonio Ospite <ospite@studenti.unina.it> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/hid/hidraw.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 66579c0bf328..5b57551233f4 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -211,11 +211,14 @@ static int hidraw_release(struct inode * inode, struct file * file)
unsigned int minor = iminor(inode);
struct hidraw *dev;
struct hidraw_list *list = file->private_data;
+ int ret;
+ mutex_lock(&minors_lock);
if (!hidraw_table[minor]) {
printk(KERN_EMERG "hidraw device with minor %d doesn't exist\n",
minor);
- return -ENODEV;
+ ret = -ENODEV;
+ goto unlock;
}
list_del(&list->node);
@@ -229,10 +232,12 @@ static int hidraw_release(struct inode * inode, struct file * file)
kfree(list->hidraw);
}
}
-
kfree(list);
+ ret = 0;
+unlock:
+ mutex_unlock(&minors_lock);
- return 0;
+ return ret;
}
static long hidraw_ioctl(struct file *file, unsigned int cmd,