second race in hiddev

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

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.

	Regards
		Oliver

Signed-off-by: Oliver Neukum <oneukum@xxxxxxx>

---

@@ -878,16 +878,19 @@ int hiddev_connect(struct hid_device *hid, unsigned int force)
 	hiddev->hid = hid;
 	hiddev->exist = 1;
 
+	lock_kernel();
 	retval = usb_register_dev(usbhid->intf, &hiddev_class);
 	if (retval) {
 		err_hid("Not able to get a minor for this device.");
 		hid->hiddev = NULL;
+		unlock_kernel();
 		kfree(hiddev);
 		return -1;
 	} else {
 		hid->minor = usbhid->intf->minor;
 		hiddev_table[usbhid->intf->minor - HIDDEV_MINOR_BASE] = hiddev;
 	}
+	unlock_kernel();
 
 	return 0;
 }
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux