Package: libusb
Version: 1.0.6-1~bpo50+1
Severity: normal

One of my programs uses libusb. Among other things, it listens for
hotplug events via a uevent socket, and after receiving one, calls
libusb_get_device_list() to list the USB devices and handle those
I'm interested in. Between the hotplug event and the call to
libusb_get_device_list() there may be some delay (which may or may
not be relevant to causing the bug) while the program does other
things.

The problem is that libusb_get_device_list() sometimes fails at some
point, i.e. returns 0, and keeps doing so for the rest of the
program run. It is not easy to reproduce. It typically occurs after
I plug and unplug some USB devices quickly and/or often.

Since I can't give a procedure to reproduce it, I did some debugging
with gdb, and I found that before the error occurs, the program
reaches line 939 (in this version) in sysfs_scan_device():

  sysfs_can_relate_devices = 0;

At this point filename == "/sys/bus/usb/devices/1-1/busnum" which is
a valid path at this moment. Since this line should be executed only
if opening filename failed, and because of the apparent behaviour of
the bug, I suspect some kind of race condition here, such as a newly
connected USB device that was already unconnected again before it
was handled here (or unconnected just at the wrong moment).

I wouldn't be surprised if such a situation caused strange, or even
undefined, behaviour WRT that device, but it seems to break libusb
permanently (i.e., for the lifetime of the process). I traced this
to the following events:

Because sysfs_can_relate_devices == 0, op_get_device_list() does not
call sysfs_get_device_list() anymore, but usbfs_get_device_list(),
which via usbfs_scan_busdir() calls enumerate_device() with
sysfs_dir == NULL which calls initialize_device() still with
sysfs_dir == NULL, so priv->sysfs_dir is not set and left NULL.
Since sysfs_has_descriptors == 1, the function returns early (this
might already be an error at this point, I'm not sure).

Afterwards, enumerate_device() calls usbi_sanitize_device(), and via
op_get_device_descriptor() and sysfs_get_device_descriptor() calls
__open_sysfs_attr() which does
snprintf(filename, ..., priv->sysfs_dir) which thus creates an
invalid path such as "/sys/bus/usb/devices/(null)/descriptors", so
open() fails which ultimately causes the failure of
libusb_get_device_list().

So it seems to me that the failure to handle one device causes a
permanent flag (sysfs_can_relate_devices) to be changed which seems
to be the root cause of the bug.

I hope this description helps you to find and fix the problem.

-- System Information:
Debian Release: 4.0
Architecture: i386 (i686)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.25-2-686
Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968)
gcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)

I.e., Debian etch, with a kernel from etch backports, and libusb
sources from lenny backports, self compiled with "debuild -us -uc"
without any additional patches.



-- 
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]

Reply via email to