Commit 8052ee5f authored by Julia Lawall's avatar Julia Lawall Committed by Jiri Kosina

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: default avatarJulia Lawall <julia@diku.dk>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent ad734bc1
...@@ -162,27 +162,27 @@ static int roccat_open(struct inode *inode, struct file *file) ...@@ -162,27 +162,27 @@ static int roccat_open(struct inode *inode, struct file *file)
device = devices[minor]; device = devices[minor];
mutex_lock(&device->readers_lock);
if (!device) { if (!device) {
pr_emerg("roccat device with minor %d doesn't exist\n", minor); pr_emerg("roccat device with minor %d doesn't exist\n", minor);
error = -ENODEV; error = -ENODEV;
goto exit_err; goto exit_err_devices;
} }
mutex_lock(&device->readers_lock);
if (!device->open++) { if (!device->open++) {
/* power on device on adding first reader */ /* power on device on adding first reader */
error = hid_hw_power(device->hid, PM_HINT_FULLON); error = hid_hw_power(device->hid, PM_HINT_FULLON);
if (error < 0) { if (error < 0) {
--device->open; --device->open;
goto exit_err; goto exit_err_readers;
} }
error = hid_hw_open(device->hid); error = hid_hw_open(device->hid);
if (error < 0) { if (error < 0) {
hid_hw_power(device->hid, PM_HINT_NORMAL); hid_hw_power(device->hid, PM_HINT_NORMAL);
--device->open; --device->open;
goto exit_err; goto exit_err_readers;
} }
} }
...@@ -193,13 +193,13 @@ static int roccat_open(struct inode *inode, struct file *file) ...@@ -193,13 +193,13 @@ static int roccat_open(struct inode *inode, struct file *file)
list_add_tail(&reader->node, &device->readers); list_add_tail(&reader->node, &device->readers);
file->private_data = reader; file->private_data = reader;
exit_unlock: exit_err_readers:
mutex_unlock(&device->readers_lock); mutex_unlock(&device->readers_lock);
exit_err_devices:
mutex_unlock(&devices_lock); mutex_unlock(&devices_lock);
if (error)
kfree(reader);
return error; return error;
exit_err:
kfree(reader);
goto exit_unlock;
} }
static int roccat_release(struct inode *inode, struct file *file) static int roccat_release(struct inode *inode, struct file *file)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment