• O
    HID: fix race between usb_register_dev() and hiddev_open() · e43bd67d
    Oliver Neukum 提交于
    upon further thought this code is still racy.
    
    	retval = usb_register_dev(usbhid->intf, &hiddev_class);
    
    here you open a window during which open can happen
    
    	if (retval) {
    		err_hid("Not able to get a minor for this device.");
    		hid->hiddev = NULL;
    		kfree(hiddev);
    		return -1;
    	} else {
    		hid->minor = usbhid->intf->minor;
    		hiddev_table[usbhid->intf->minor - HIDDEV_MINOR_BASE] = hiddev;
    
    and will fail because hiddev_table hasn't been updated
    
    The obvious fix of using a mutex to guard hiddev_table doesn't work because
    usb_open() and usb_register_dev() take minor_rwsem and we'd have an AB-BA
    deadlock. We need a lock usb_open() also takes in the right order and that leaves
    only one option, BKL. I don't like it but I see no alternative.
    
    Once the usb_open() implements something better than lock_kernel(), we could also
    do so.
    Signed-off-by: NOliver Neukum <oneukum@suse.de>
    Signed-off-by: NJiri Kosina <jkosina@suse.cz>
    e43bd67d
hiddev.c 23.5 KB