• Oliver Neukum's avatar
    HID: fix race between open() and disconnect() in usbhid · 69626f23
    Oliver Neukum authored
    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: default avatarOliver Neukum <oneukum@suse.de>
    Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
    69626f23
hid-core.c 31.2 KB