HID: fix race between open() and disconnect() in usbhid
authorOliver Neukum <oliver@neukum.org>
Mon, 31 Mar 2008 14:27:30 +0000 (16:27 +0200)
committerJiri Kosina <jkosina@suse.cz>
Tue, 22 Apr 2008 09:34:58 +0000 (11:34 +0200)
commit69626f23bce6521367ac1e6a2a6e8fba8f0a848a
tree46342a02c79e0e69a1c1eed1239944c4f952b13c
parentabdff0f7749a6696ba2a4238b675cbc55abcdb7a
HID: fix race between open() and disconnect() in usbhid

There is a window:

task A task B
spin_lock_irq(&usbhid->inlock); /* Sync with error handler */
usb_set_intfdata(intf, NULL);
spin_unlock_irq(&usbhid->inlock);
usb_kill_urb(usbhid->urbin);
usb_kill_urb(usbhid->urbout);
usb_kill_urb(usbhid->urbctrl);

del_timer_sync(&usbhid->io_retry);
cancel_work_sync(&usbhid->reset_work);

if (!hid->open++) {
res = usb_autopm_get_interface(usbhid->intf);
if (res < 0) {
hid->open--;
return -EIO;
}
}
if (hid_start_in(hid))

if (hid->claimed & HID_CLAIMED_INPUT)
hidinput_disconnect(hid);

in which an open() to an already disconnected device will submit an URB
to an undead device. In case disconnect() was called by an ioctl, this'll
oops. Fix by introducing a new flag and checking it in hid_start_in().

Signed-off-by: Oliver Neukum <oneukum@suse.de>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
drivers/hid/usbhid/hid-core.c
include/linux/hid.h