95 lines
3.7 KiB
ReStructuredText
95 lines
3.7 KiB
ReStructuredText
|
==============
|
||
|
USB Raw Gadget
|
||
|
==============
|
||
|
|
||
|
USB Raw Gadget is a gadget driver that gives userspace low-level control over
|
||
|
the gadget's communication process.
|
||
|
|
||
|
Like any other gadget driver, Raw Gadget implements USB devices via the
|
||
|
USB gadget API. Unlike most gadget drivers, Raw Gadget does not implement
|
||
|
any concrete USB functions itself but requires userspace to do that.
|
||
|
|
||
|
Raw Gadget is currently a strictly debugging feature and should not be used
|
||
|
in production. Use GadgetFS instead.
|
||
|
|
||
|
Enabled with CONFIG_USB_RAW_GADGET.
|
||
|
|
||
|
Comparison to GadgetFS
|
||
|
~~~~~~~~~~~~~~~~~~~~~~
|
||
|
|
||
|
Raw Gadget is similar to GadgetFS but provides more direct access to the
|
||
|
USB gadget layer for userspace. The key differences are:
|
||
|
|
||
|
1. Raw Gadget passes every USB request to userspace to get a response, while
|
||
|
GadgetFS responds to some USB requests internally based on the provided
|
||
|
descriptors. Note that the UDC driver might respond to some requests on
|
||
|
its own and never forward them to the gadget layer.
|
||
|
|
||
|
2. Raw Gadget allows providing arbitrary data as responses to USB requests,
|
||
|
while GadgetFS performs sanity checks on the provided USB descriptors.
|
||
|
This makes Raw Gadget suitable for fuzzing by providing malformed data as
|
||
|
responses to USB requests.
|
||
|
|
||
|
3. Raw Gadget provides a way to select a UDC device/driver to bind to,
|
||
|
while GadgetFS currently binds to the first available UDC. This allows
|
||
|
having multiple Raw Gadget instances bound to different UDCs.
|
||
|
|
||
|
4. Raw Gadget explicitly exposes information about endpoints addresses and
|
||
|
capabilities. This allows the user to write UDC-agnostic gadgets.
|
||
|
|
||
|
5. Raw Gadget has an ioctl-based interface instead of a filesystem-based
|
||
|
one.
|
||
|
|
||
|
Userspace interface
|
||
|
~~~~~~~~~~~~~~~~~~~
|
||
|
|
||
|
The user can interact with Raw Gadget by opening ``/dev/raw-gadget`` and
|
||
|
issuing ioctl calls; see the comments in include/uapi/linux/usb/raw_gadget.h
|
||
|
for details. Multiple Raw Gadget instances (bound to different UDCs) can be
|
||
|
used at the same time.
|
||
|
|
||
|
A typical usage scenario of Raw Gadget:
|
||
|
|
||
|
1. Create a Raw Gadget instance by opening ``/dev/raw-gadget``.
|
||
|
2. Initialize the instance via ``USB_RAW_IOCTL_INIT``.
|
||
|
3. Launch the instance with ``USB_RAW_IOCTL_RUN``.
|
||
|
4. In a loop issue ``USB_RAW_IOCTL_EVENT_FETCH`` to receive events from
|
||
|
Raw Gadget and react to those depending on what kind of USB gadget must
|
||
|
be implemented.
|
||
|
|
||
|
Note that some UDC drivers have fixed addresses assigned to endpoints, and
|
||
|
therefore arbitrary endpoint addresses cannot be used in the descriptors.
|
||
|
Nevertheless, Raw Gadget provides a UDC-agnostic way to write USB gadgets.
|
||
|
Once ``USB_RAW_EVENT_CONNECT`` is received via ``USB_RAW_IOCTL_EVENT_FETCH``,
|
||
|
``USB_RAW_IOCTL_EPS_INFO`` can be used to find out information about the
|
||
|
endpoints that the UDC driver has. Based on that, userspace must choose UDC
|
||
|
endpoints for the gadget and assign addresses in the endpoint descriptors
|
||
|
correspondingly.
|
||
|
|
||
|
Raw Gadget usage examples and a test suite:
|
||
|
|
||
|
https://github.com/xairy/raw-gadget
|
||
|
|
||
|
Internal details
|
||
|
~~~~~~~~~~~~~~~~
|
||
|
|
||
|
Every Raw Gadget endpoint read/write ioctl submits a USB request and waits
|
||
|
until its completion. This is done deliberately to assist with coverage-guided
|
||
|
fuzzing by having a single syscall fully process a single USB request. This
|
||
|
feature must be kept in the implementation.
|
||
|
|
||
|
Potential future improvements
|
||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
|
||
|
- Report more events (suspend, resume, etc.) through
|
||
|
``USB_RAW_IOCTL_EVENT_FETCH``.
|
||
|
|
||
|
- Support ``O_NONBLOCK`` I/O. This would be another mode of operation, where
|
||
|
Raw Gadget would not wait until the completion of each USB request.
|
||
|
|
||
|
- Support USB 3 features (accept SS endpoint companion descriptor when
|
||
|
enabling endpoints; allow providing ``stream_id`` for bulk transfers).
|
||
|
|
||
|
- Support ISO transfer features (expose ``frame_number`` for completed
|
||
|
requests).
|