ANNOUNCEMENT: Live Wireshark University & Allegro Packets online APAC Wireshark Training Session
April 17th, 2024 | 14:30-16:00 SGT (UTC+8) | Online

Wireshark-dev: [Wireshark-dev] How to deal with USB descriptor dissection

From: Tomasz Moń <desowin@xxxxxxxxx>
Date: Thu, 9 Jan 2020 15:05:14 +0100
Hello,

In USB control transfers the host decides how many bytes of data he
wants to receive. For example, when Windows requests STRING DESCRIPTOR
it first asks for only 2 bytes. The first two bytes are length and
descriptor type. Unfortunately, Wireshark dissector attempts
dissecting full string descriptor, even though host only requested 2
bytes. This leads to [Malformed Packet] while in reality everything
was perfectly fine.

Example request:
Frame 7: 36 bytes on wire (288 bits), 36 bytes captured (288 bits) on
interface wireshark_extcap2008, id 0
USB URB
Setup Data
    bmRequestType: 0x80
        1... .... = Direction: Device-to-host
        .00. .... = Type: Standard (0x0)
        ...0 0000 = Recipient: Device (0x00)
    bRequest: GET DESCRIPTOR (6)
    Descriptor Index: 0x00
    bDescriptorType: STRING (0x03)
    Language Id: no language specified (0x0000)
    wLength: 2

And response:
Frame 8: 30 bytes on wire (240 bits), 30 bytes captured (240 bits) on
interface wireshark_extcap2008, id 0
USB URB
STRING DESCRIPTOR
    bLength: 4
    bDescriptorType: 0x03 (STRING)
[Malformed Packet: USB]
    [Expert Info (Error/Malformed): Malformed Packet (Exception occurred)]
        [Malformed Packet (Exception occurred)]
        [Severity level: Error]
        [Group: Malformed]

The response is perfectly fine, if host asked for 4 bytes, he would
have gotten it. But here it asked only for 2 bytes, so according to
specification it got only 2. It is seen later in the capture that host
indeed asks for the full 4 bytes.

Frame 9: 36 bytes on wire (288 bits), 36 bytes captured (288 bits) on
interface wireshark_extcap2008, id 0
USB URB
Setup Data
    bmRequestType: 0x80
        1... .... = Direction: Device-to-host
        .00. .... = Type: Standard (0x0)
        ...0 0000 = Recipient: Device (0x00)
    bRequest: GET DESCRIPTOR (6)
    Descriptor Index: 0x00
    bDescriptorType: STRING (0x03)
    Language Id: no language specified (0x0000)
    wLength: 4
Frame 10: 32 bytes on wire (256 bits), 32 bytes captured (256 bits) on
interface wireshark_extcap2008, id 0
USB URB
STRING DESCRIPTOR
    bLength: 4
    bDescriptorType: 0x03 (STRING)
    wLANGID: English (United States) (0x0409)

The same applies to all control transfers that return data. The host
is allowed to request less than the full amount (and often does so, to
know how big the full structure is, e.g. when requesting CONFIGURATION
descriptor). Do we have some generic mechanism that could be used to
make Wireshark stop dissection at the specific byte count in such
cases?

Best Regards,
Tomasz Moń