Linux sysfs usb descriptors file has broken configuration length handling

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

 



Hi All,

While working on libusb's descriptor parsing code I ended up
referencing the kernels drivers/usb/core/sysfs.c and
drivers/usb/core/devio.c files. And I noticed a worrisome
discrepancy.

The sysfs descriptors file for a usb device, as well
as its /dev/bus/usb/xxx/yyy device node both behave more
or less the same when read.

There is 1 difference which is by-design / has historical
grown that way. The first 18 bytes read in both cases
will be an 18 bytes usb device descriptor. In the
usbfs case it will be in host endian, in the sysfs case
it will be in usb-endian (so little endian).

But there is another difference which I believe to
be a problem, after the usb device descriptor both
implementations follow with the config descriptor(s) in
raw format, using struct usb_device->rawdescriptors[x]
as the source.

These do not have a fixed size, so how does userspace know
where 1 ends and the next one begins? Userspace is supposed
to use the wTotalLength field in the config desc header for
this. Which comes from the device, and the actual read of
the config desc from the device may have returned less
bytes, so usb_device->rawdescriptors[x] may contain less
data then this.

Both the usbfs and sysfs code ensure to not return bogus
data by limiting the amount of read data to
usb_device->config[x].desc.wTotalLength
which has been set to the actual amount of available data.

But then things start to differ, usbfs leaves holes in
the file the size of the missing data, so that in
case of usb_device->config[x].desc.wTotalLength being
less then the length advertised by the rawdescriptors,
the next descriptor will still start where user space
expects it to start.

But the sysfs descriptors file will just packs the
rawdescriptors one behind the other, using
usb_device->config[x].desc.wTotalLength, where as
userspace only sees the length advertised by
the rawdescriptors, which may be different, and when
it is userspace will this have no idea where the next
descriptor starts.

I believe the proper way to fix this is to make the
sysfs code deal with this the same way the usbfs code
does (filling the holes with 0 to avoid leaking kmem),
if people agree I can write a patch for this.

Regards,

Hans

p.s.

In the mean time I will switch libusb to use usbfs
device nodes to get the descriptors exclusively,
since those will work reliable (even on non fixed
kernels), whereas the sysfs descriptors file will not.

Neither causes any device io, so the performance
impact should be negligible.
--
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