^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) ==============
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) USB Raw Gadget
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) ==============
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) USB Raw Gadget is a kernel module that provides a userspace interface for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) the USB Gadget subsystem. Essentially it allows to emulate USB devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) from userspace. Enabled with CONFIG_USB_RAW_GADGET. Raw Gadget is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) currently a strictly debugging feature and shouldn't be used in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) production, use GadgetFS instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) Comparison to GadgetFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) ~~~~~~~~~~~~~~~~~~~~~~
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) Raw Gadget is similar to GadgetFS, but provides a more low-level and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) direct access to the USB Gadget layer for the userspace. The key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) differences are:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) 1. Every USB request is passed to the userspace to get a response, while
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) GadgetFS responds to some USB requests internally based on the provided
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) descriptors. However note, that the UDC driver might respond to some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) requests on its own and never forward them to the Gadget layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) 2. GadgetFS performs some sanity checks on the provided USB descriptors,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) while Raw Gadget allows you to provide arbitrary data as responses to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) USB requests.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) 3. Raw Gadget provides a way to select a UDC device/driver to bind to,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) while GadgetFS currently binds to the first available UDC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) 4. Raw Gadget explicitly exposes information about endpoints addresses and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) capabilities allowing a user to write UDC-agnostic gadgets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) 5. Raw Gadget has ioctl-based interface instead of a filesystem-based one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) Userspace interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) ~~~~~~~~~~~~~~~~~~~
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) To create a Raw Gadget instance open /dev/raw-gadget. Multiple raw-gadget
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) instances (bound to different UDCs) can be used at the same time. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) interaction with the opened file happens through the ioctl() calls, see
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) comments in include/uapi/linux/usb/raw_gadget.h for details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) The typical usage of Raw Gadget looks like:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) 1. Open Raw Gadget instance via /dev/raw-gadget.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) 2. Initialize the instance via USB_RAW_IOCTL_INIT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) 3. Launch the instance with USB_RAW_IOCTL_RUN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) 4. In a loop issue USB_RAW_IOCTL_EVENT_FETCH calls to receive events from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) Raw Gadget and react to those depending on what kind of USB device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) needs to be emulated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) Note, that some UDC drivers have fixed addresses assigned to endpoints, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) therefore arbitrary endpoint addresses can't be used in the descriptors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) Nevertheles, Raw Gadget provides a UDC-agnostic way to write USB gadgets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) Once a USB_RAW_EVENT_CONNECT event is received via USB_RAW_IOCTL_EVENT_FETCH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) the USB_RAW_IOCTL_EPS_INFO ioctl can be used to find out information about
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) endpoints that the UDC driver has. Based on that information, the user must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) chose UDC endpoints that will be used for the gadget being emulated, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) properly assign addresses in endpoint descriptors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) You can find usage examples (along with a test suite) here:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) https://github.com/xairy/raw-gadget
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) Internal details
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) ~~~~~~~~~~~~~~~~
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) Currently every endpoint read/write ioctl submits a USB request and waits until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) its completion. This is the desired mode for coverage-guided fuzzing (as we'd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) like all USB request processing happen during the lifetime of a syscall),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) and must be kept in the implementation. (This might be slow for real world
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) applications, thus the O_NONBLOCK improvement suggestion below.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) Potential future improvements
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) - Report more events (suspend, resume, etc.) through USB_RAW_IOCTL_EVENT_FETCH.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) - Support O_NONBLOCK I/O.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) - Support USB 3 features (accept SS endpoint companion descriptor when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) enabling endpoints; allow providing stream_id for bulk transfers).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) - Support ISO transfer features (expose frame_number for completed requests).