summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulia Lawall <julia@diku.dk>2011-11-01 15:13:04 +0100
committerJiri Kosina <jkosina@suse.cz>2011-11-01 15:13:08 +0100
commit8052ee5f5fd9be153129eaa06ced4a786415abc1 (patch)
tree4f33bf711486846f235426aa3eb365f51570a97d
parentad734bc1565364f9e4b70888d3ce5743b3c1030a (diff)
downloadlinux-stable-8052ee5f5fd9be153129eaa06ced4a786415abc1.tar.gz
linux-stable-8052ee5f5fd9be153129eaa06ced4a786415abc1.tar.bz2
linux-stable-8052ee5f5fd9be153129eaa06ced4a786415abc1.zip
HID: drivers/hid/hid-roccat.c: eliminate a null pointer dereference
It is not possible to take the lock in device if device is NULL. The mutex_lock is thus moved after the NULL test. New error handling labels are added at the end to differentiate between the cases where different sets of locks should be unlocks, and between whether or not reader should be freed (only on error). The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // <smpl> @r@ expression E, E1; identifier f; statement S1,S2,S3; @@ if (E == NULL) { ... when != if (E == NULL || ...) S1 else S2 when != E = E1 *E->f ... when any return ...; } else S3 // </smpl> Signed-off-by: Julia Lawall <julia@diku.dk> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/hid-roccat.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/drivers/hid/hid-roccat.c b/drivers/hid/hid-roccat.c
index 5666e7587b18..56ce12c23b02 100644
--- a/drivers/hid/hid-roccat.c
+++ b/drivers/hid/hid-roccat.c
@@ -162,27 +162,27 @@ static int roccat_open(struct inode *inode, struct file *file)
device = devices[minor];
- mutex_lock(&device->readers_lock);
-
if (!device) {
pr_emerg("roccat device with minor %d doesn't exist\n", minor);
error = -ENODEV;
- goto exit_err;
+ goto exit_err_devices;
}
+ mutex_lock(&device->readers_lock);
+
if (!device->open++) {
/* power on device on adding first reader */
error = hid_hw_power(device->hid, PM_HINT_FULLON);
if (error < 0) {
--device->open;
- goto exit_err;
+ goto exit_err_readers;
}
error = hid_hw_open(device->hid);
if (error < 0) {
hid_hw_power(device->hid, PM_HINT_NORMAL);
--device->open;
- goto exit_err;
+ goto exit_err_readers;
}
}
@@ -193,13 +193,13 @@ static int roccat_open(struct inode *inode, struct file *file)
list_add_tail(&reader->node, &device->readers);
file->private_data = reader;
-exit_unlock:
+exit_err_readers:
mutex_unlock(&device->readers_lock);
+exit_err_devices:
mutex_unlock(&devices_lock);
+ if (error)
+ kfree(reader);
return error;
-exit_err:
- kfree(reader);
- goto exit_unlock;
}
static int roccat_release(struct inode *inode, struct file *file)