Hi, On 07/06/2012 04:10 PM, Alan Stern wrote: > On Fri, 6 Jul 2012, Hans de Goede wrote: > >> I've been seeing these intermittent failures to reclaim an interface after >> a device reset. After much debugging and inserting sleeps in strategic >> places to make the race window larger I've found the following race: >> 1) A user is running some software using libusb which will automatically >> detect, and "bind" to, any newly plugged in USB-devices. For example >> a virtual machine viewer with automatic USB-redirection >> 2) The user plugs in a new usb-storage device >> 3) The usb-storage driver is not yet loaded, udev spawns >> "modprobe usb-storage", this blocks on disk-io >> 4) The libusb app opens the device, claims all interfaces, does a >> device-reset >> 5) While the IOCTL_USBFS_RESET is running the modprobe completes >> 6) The driver registration blocks on an USB lock held by the reset code path >> 7) When the reset finishes the driver registration completes and the driver >> binds itself tp the device, before IOCTL_USBFS_RESET returns to userspace >> 8) libusb tries to re-claim all interfaces it had claimed before the reset >> 9) libusb fails as usb-storage is now bound to it > > In theory we could prevent this problem by adding pre- and post-reset > handlers to usbfs. The difficulty is: What should such handlers do? > There's no way to inform client programs about the reset.
Right, so I see one option here: 1) Have devio.c: proc_resetdevice check it all interfaces are claimed by the caller (I've not yet looked how hard this is. 2) If all interfaces are claimed set a "self inflicted reset" flag. 3) In pre-reset check-n-clear the "self inflicted reset" if it was set, return success, if it was not set return failure which will make the reset behave as if there is no pre-reset Then we will only get the no unbind/rebind behavior on "self inflicted" resets, in which case we can assume userspace knows about the reset ... This would require adding a capability to signal to libusb the kernel now does things this way, and for libusb to be thought about this new capability, to check it has all interfaces claimed, and to then and only then not release / re-claim over a reset. This sounds like a lot of complications on both sides with little gain ... >> This patch works around this issue by simply unbinding the driver for all >> interfaces which were claimed before the reset. Normally this is a no-op as >> no driver (other then usbfs) can be bound for claimed interfaces before the >> reset. >> >> But as the above example shows, the exception is a driver completing >> registration, and as part of this binding to any elegible devices, between >> IOCTL_USBFS_RESET and our re-claiming of the interface. The largest part >> of the race window here is the time IOCTL_USBFS_RESET takes, as that does a >> fair amount of IO with the device. This part of the race window is >> worked around by this patch. >> >> This still leaves a theoretical race window where the driver registration >> finishes between our driver-unbind and interface-reclaim, I'm afraid there >> is nothing we can against this. > > Repeat the unbind and try again if the reclaim fails. Two iterations > should be sufficient. Oh, smart! Yes that will work, so unless we decide to add pre_reset to usbfs I guess I'll respin this patch to include this change. Regards, Hans ------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ _______________________________________________ libusbx-devel mailing list libusbx-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libusbx-devel