lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <CA+fCnZcQSYy63ichdivAH5-fYvN2UMzTtZ--h=F6nK0jfVou3Q@mail.gmail.com>
Date:   Fri, 18 Aug 2023 02:15:52 +0200
From:   Andrey Konovalov <andreyknvl@...il.com>
To:     Alan Stern <stern@...land.harvard.edu>,
        Thinh Nguyen <Thinh.Nguyen@...opsys.com>
Cc:     Felipe Balbi <balbi@...nel.org>,
        Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
        USB list <linux-usb@...r.kernel.org>,
        LKML <linux-kernel@...r.kernel.org>
Subject: dwc3: unusual handling of setup requests with wLength == 0

Hi Alan and Thinh,

I have been testing Raw Gadget with the dwc3 UDC driver and stumbled
upon an issue related to how dwc3 handles setup requests with wLength
== 0.

When running a simple Raw Gadget-based keyboard emulator [1],
everything works as expected until the point when the host sends a
SET_CONFIGURATION request, which has wLength == 0.

For setup requests with wLength != 0, just like the other UDC drivers
I tested, dwc3 calls the gadget driver's ->setup() callback and then
waits until the gadget driver queues an URB to EP0 as a response.

However, for a setup request with wLength == 0, dwc3 does not wait
until the gadget driver queues an URB to ack the transfer. It appears
that dwc3 just acks the request internally and then proceeds with
calling the ->setup() callback for the next request received from the
host. This confuses Raw Gadget, as it does not expect to get a new
->setup() call before it explicitly acks the previous one by queuing
an URB. As a result, the emulation fails.

I suspect this issue has not been observed with other gadget drivers,
as they queue an URB immediately after receiving a ->setup() call:
dwc3 appears to somehow correctly handle this internally even though
it acks the transfer by itself. But the timings with Raw Gadget are
different, as it requires userspace to ack the transfer. Sometimes
though, the Raw Gadget-based emulator also manages to queue an URB
before the next request is received from the host and the enumeration
continues properly (until the next request with wLength == 0).

What do you think would be the best approach to deal with this?

Can this be considered a bug in dwc3 that should be fixed? There's a
seemingly related comment in dwc3 code [2], but I'm not familiar
enough with its internals to understand whether this is what leads to
the issue I'm seeing.

Or should I adapt Raw Gadget to handle this unusual dwc3 behavior?
This might be tricky to do, as I cannot change the existing userspace
API.

On a side note, as an experiment, I tried returning
USB_GADGET_DELAYED_STATUS from the Raw Gadget's ->setup() callback if
the UDC driver calls it too early: some UDC drivers, including dwc3,
appear to contain a special handling for this return value. However,
that didn't work out. Perhaps, I misunderstand the meaning of this
value.

Thank you!

[1] https://github.com/xairy/raw-gadget/blob/master/examples/keyboard.c
[2] https://elixir.bootlin.com/linux/v6.5-rc6/source/drivers/usb/dwc3/ep0.c#L145

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ