Use of usb_find_interface in open is racy

From: Russ Dill
Date: Tue Nov 17 2009 - 16:06:14 EST


Many usb drivers that create character devices use "struct
usb_class_driver", a set of fops, and a usb_find_interface in their
open call. A prime example is drivers/usb/usb-skeleton.c. A race
occurs when userspace receives a hotplug event for the addition for
the interface and then opens the associated device file before the
device is added to the driver's klist_devices.

The usb core senses a new usb device (usb_new_device) and calls
device_add. This eventually gets down to really_probe and the
usb-skeleton probe function, skel_probe. skel_probe calls
usb_register_dev() which registers the associated character device for
skel_class. The hotplug events for the class device get emitted.

User space receives the hotplug event for the class device, makes the
device node and notifies another program that opens the device node.
The program opens the device node which calls into usb_open and then
skel_open. skel_open calls usb_find_interface. usb_find_interfaces
searches the klist_devices of skel_driver, finds no device associated
with the minor number and returns NULL. skel_open returns -ENODEV.

Control returns to really_probe and really_probe calls driver_bound
which adds the device to the list of devices associated with
skel_driver (klist_devices).

I'm not sure what the right way to solve this is. A call to
wait_for_device_probe() in the skel_open call before calling
usb_find_interface fixes the problem, but it is a rather large hammer.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/