aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulia Lawall <julia@diku.dk>2011-11-01 10:13:04 -0400
committerJiri Kosina <jkosina@suse.cz>2011-11-01 10:13:08 -0400
commit8052ee5f5fd9be153129eaa06ced4a786415abc1 (patch)
tree4f33bf711486846f235426aa3eb365f51570a97d
parentad734bc1565364f9e4b70888d3ce5743b3c1030a (diff)
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 5666e7587b1..56ce12c23b0 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)
162 162
163 device = devices[minor]; 163 device = devices[minor];
164 164
165 mutex_lock(&device->readers_lock);
166
167 if (!device) { 165 if (!device) {
168 pr_emerg("roccat device with minor %d doesn't exist\n", minor); 166 pr_emerg("roccat device with minor %d doesn't exist\n", minor);
169 error = -ENODEV; 167 error = -ENODEV;
170 goto exit_err; 168 goto exit_err_devices;
171 } 169 }
172 170
171 mutex_lock(&device->readers_lock);
172
173 if (!device->open++) { 173 if (!device->open++) {
174 /* power on device on adding first reader */ 174 /* power on device on adding first reader */
175 error = hid_hw_power(device->hid, PM_HINT_FULLON); 175 error = hid_hw_power(device->hid, PM_HINT_FULLON);
176 if (error < 0) { 176 if (error < 0) {
177 --device->open; 177 --device->open;
178 goto exit_err; 178 goto exit_err_readers;
179 } 179 }
180 180
181 error = hid_hw_open(device->hid); 181 error = hid_hw_open(device->hid);
182 if (error < 0) { 182 if (error < 0) {
183 hid_hw_power(device->hid, PM_HINT_NORMAL); 183 hid_hw_power(device->hid, PM_HINT_NORMAL);
184 --device->open; 184 --device->open;
185 goto exit_err; 185 goto exit_err_readers;
186 } 186 }
187 } 187 }
188 188
@@ -193,13 +193,13 @@ static int roccat_open(struct inode *inode, struct file *file)
193 list_add_tail(&reader->node, &device->readers); 193 list_add_tail(&reader->node, &device->readers);
194 file->private_data = reader; 194 file->private_data = reader;
195 195
196exit_unlock: 196exit_err_readers:
197 mutex_unlock(&device->readers_lock); 197 mutex_unlock(&device->readers_lock);
198exit_err_devices:
198 mutex_unlock(&devices_lock); 199 mutex_unlock(&devices_lock);
200 if (error)
201 kfree(reader);
199 return error; 202 return error;
200exit_err:
201 kfree(reader);
202 goto exit_unlock;
203} 203}
204 204
205static int roccat_release(struct inode *inode, struct file *file) 205static int roccat_release(struct inode *inode, struct file *file)