From: Greg Kroah-Hartman Date: Tue, 9 Oct 2012 23:59:52 +0000 (+0900) Subject: 3.6-stable patches X-Git-Tag: v3.0.46~25 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=eea5abed9a26b866fafb93c447ad4685cc81c414;p=thirdparty%2Fkernel%2Fstable-queue.git 3.6-stable patches added patches: hid-hidraw-don-t-deallocate-memory-when-it-is-in-use.patch --- diff --git a/queue-3.6/hid-hidraw-don-t-deallocate-memory-when-it-is-in-use.patch b/queue-3.6/hid-hidraw-don-t-deallocate-memory-when-it-is-in-use.patch new file mode 100644 index 00000000000..ee552ad25c3 --- /dev/null +++ b/queue-3.6/hid-hidraw-don-t-deallocate-memory-when-it-is-in-use.patch @@ -0,0 +1,135 @@ +From 4fe9f8e203fdad1524c04beb390f3c6099781ed9 Mon Sep 17 00:00:00 2001 +From: Ratan Nalumasu +Date: Sat, 22 Sep 2012 11:46:30 -0700 +Subject: HID: hidraw: don't deallocate memory when it is in use + +From: Ratan Nalumasu + +commit 4fe9f8e203fdad1524c04beb390f3c6099781ed9 upstream. + +When a device is unplugged, wait for all processes that have opened the device +to close before deallocating the device. + +Signed-off-by: Ratan Nalumasu +Signed-off-by: Jiri Kosina +Cc: Kees Cook +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hid/hidraw.c | 69 +++++++++++++++++++-------------------------------- + 1 file changed, 26 insertions(+), 43 deletions(-) + +--- a/drivers/hid/hidraw.c ++++ b/drivers/hid/hidraw.c +@@ -42,6 +42,7 @@ static struct cdev hidraw_cdev; + static struct class *hidraw_class; + static struct hidraw *hidraw_table[HIDRAW_MAX_DEVICES]; + static DEFINE_MUTEX(minors_lock); ++static void drop_ref(struct hidraw *hid, int exists_bit); + + static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) + { +@@ -113,7 +114,7 @@ static ssize_t hidraw_send_report(struct + __u8 *buf; + int ret = 0; + +- if (!hidraw_table[minor]) { ++ if (!hidraw_table[minor] || !hidraw_table[minor]->exist) { + ret = -ENODEV; + goto out; + } +@@ -261,7 +262,7 @@ static int hidraw_open(struct inode *ino + } + + mutex_lock(&minors_lock); +- if (!hidraw_table[minor]) { ++ if (!hidraw_table[minor] || !hidraw_table[minor]->exist) { + err = -ENODEV; + goto out_unlock; + } +@@ -298,36 +299,12 @@ out: + 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; +- int i; +- +- mutex_lock(&minors_lock); +- if (!hidraw_table[minor]) { +- ret = -ENODEV; +- goto unlock; +- } + ++ drop_ref(hidraw_table[minor], 0); + list_del(&list->node); +- dev = hidraw_table[minor]; +- if (!--dev->open) { +- if (list->hidraw->exist) { +- hid_hw_power(dev->hid, PM_HINT_NORMAL); +- hid_hw_close(dev->hid); +- } else { +- kfree(list->hidraw); +- } +- } +- +- for (i = 0; i < HIDRAW_BUFFER_SIZE; ++i) +- kfree(list->buffer[i].value); + kfree(list); +- ret = 0; +-unlock: +- mutex_unlock(&minors_lock); +- +- return ret; ++ return 0; + } + + static long hidraw_ioctl(struct file *file, unsigned int cmd, +@@ -529,21 +506,7 @@ EXPORT_SYMBOL_GPL(hidraw_connect); + void hidraw_disconnect(struct hid_device *hid) + { + struct hidraw *hidraw = hid->hidraw; +- +- mutex_lock(&minors_lock); +- hidraw->exist = 0; +- +- device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); +- +- hidraw_table[hidraw->minor] = NULL; +- +- if (hidraw->open) { +- hid_hw_close(hid); +- wake_up_interruptible(&hidraw->wait); +- } else { +- kfree(hidraw); +- } +- mutex_unlock(&minors_lock); ++ drop_ref(hidraw, 1); + } + EXPORT_SYMBOL_GPL(hidraw_disconnect); + +@@ -585,3 +548,23 @@ void hidraw_exit(void) + unregister_chrdev_region(dev_id, HIDRAW_MAX_DEVICES); + + } ++ ++static void drop_ref(struct hidraw *hidraw, int exists_bit) ++{ ++ mutex_lock(&minors_lock); ++ if (exists_bit) { ++ hid_hw_close(hidraw->hid); ++ hidraw->exist = 0; ++ if (hidraw->open) ++ wake_up_interruptible(&hidraw->wait); ++ } else { ++ --hidraw->open; ++ } ++ ++ if (!hidraw->open && !hidraw->exist) { ++ device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); ++ hidraw_table[hidraw->minor] = NULL; ++ kfree(hidraw); ++ } ++ mutex_unlock(&minors_lock); ++} diff --git a/queue-3.6/series b/queue-3.6/series index 2210e648f13..0a042ac1a3c 100644 --- a/queue-3.6/series +++ b/queue-3.6/series @@ -80,3 +80,4 @@ drm-radeon-kms-allow-strmout_base_update-on-rs780-and-rs880.patch drm-radeon-allow-mip_address-0-for-msaa-textures-on-evergreen.patch drm-radeon-add-msi-quirk-for-gateway-rs690.patch drm-radeon-force-msis-on-rs690-asics.patch +hid-hidraw-don-t-deallocate-memory-when-it-is-in-use.patch