forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
3.7 KiB
94 lines
3.7 KiB
============== |
|
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).
|
|
|