usb: gadget: add raw-gadget interface
Subsystems (3)
v6 cover usb: gadget: add raw-gadget interface
This patchset (currently a single patch) adds a new userspace interface for the USB Gadget subsystem called USB Raw Gadget. This is what is currently being used to enable coverage-guided USB fuzzing with syzkaller:
https://github.com/google/syzkaller/blob/master/docs/linux/external_fuzzing_usb.md
Initially I was using GadgetFS (together with the Dummy HCD/UDC module) to perform emulation of USB devices for fuzzing, but later switched to a custom written interface. The incentive to implement a different interface was to provide a somewhat raw and direct access to the USB Gadget layer for the userspace, where every USB request is passed to the userspace to get a response. See documentation for the list of differences between Raw Gadget and GadgetFS.
Currently Raw Gadget only supports blocking I/O mode, that synchronously waits for the result of each operation to allow collecting coverage per operation.
This patchset has been pushed to the public Linux kernel Gerrit instance:
https://linux-review.googlesource.com/c/linux/kernel/git/torvalds/linux/+/2144
Changes v5 -> v6:
- Prevent raw_process_ep_io() racing with raw_ioctl_ep_disable() by checking urb_queued flag in the latter.
- Use GFP_KERNEL instead of GFP_ATOMIC where possible.
- Reject opening raw-gadget with O_NONBLOCK to allow future extensions to support nonblocking IO.
- Reduce RAW_EVENT_QUEUE_SIZE to 16.
Changes v4 -> v5:
- Specified explicit usb_raw_event_type enum values for all entries.
- Dropped pointless locking in gadget_unbind().
Changes v3 -> v4:
- Print debug message when maxpacket check fails.
- Use module_misc_device() instead of module_init/exit().
- Reuse DRIVER_NAME macro in raw_device struct definition.
- Don't print WARNING in raw_release().
- Add comment that explains locking into raw_event_queue_fetch().
- Print a WARNING when event queue size is exceeded.
- Rename raw.c to raw_gadget.c.
- Mention module name in Kconfig.
- Reworked logging to use dev_err/dbg() instead of pr_err/debug().
Changes v2 -> v3:
- Updated device path in documentation.
- Changed usb_raw_init struct layout to make it the same for 32 bit compat mode.
- Added compat_ioctl to raw_fops.
- Changed raw_ioctl_init() to return EINVAL for invalid USB speeds, except for USB_SPEED_UNKNOWN, which defaults to USB_SPEED_HIGH.
- Reject endpoints with maxpacket = 0 in raw_ioctl_ep_enable().
Changes v1 -> v2:
- Moved raw.c to legacy/.
- Changed uapi header to use __u* types.
- Switched from debugfs entry to a misc device.
- Changed raw_dev from refcount to kref.
- Moved UDC_NAME_LENGTH_MAX to uapi headers.
- Used usb_endpoint_type() and usb_endpoint_dir_in/out() functions instead of open coding them.
- Added "WITH Linux-syscall-note" to SPDX id in the uapi header.
- Removed pr_err() if case dev_new() fails.
- Reduced the number of debugging messages.
Andrey Konovalov (1):
usb: gadget: add raw-gadget interface
Documentation/usb/index.rst | 1 + Documentation/usb/raw-gadget.rst | 61 ++ drivers/usb/gadget/legacy/Kconfig | 11 + drivers/usb/gadget/legacy/Makefile | 1 + drivers/usb/gadget/legacy/raw_gadget.c | 1078 ++++++++++++++++++++++++ include/uapi/linux/usb/raw_gadget.h | 167 ++++ 6 files changed, 1319 insertions(+) create mode 100644 Documentation/usb/raw-gadget.rst create mode 100644 drivers/usb/gadget/legacy/raw_gadget.c create mode 100644 include/uapi/linux/usb/raw_gadget.h
Signature · 1 line
2.25.0.265.gbab2e86ba0-goog
PATCH v6 1/1 usb: gadget: add raw-gadget interface
USB Raw Gadget is a kernel module that provides a userspace interface for the USB Gadget subsystem. Essentially it allows to emulate USB devices from userspace. Enabled with CONFIG_USB_RAW_GADGET. Raw Gadget is currently a strictly debugging feature and shouldn't be used in production.
Raw Gadget is similar to GadgetFS, but provides a more low-level and direct access to the USB Gadget layer for the userspace. The key differences are:
1. Every USB request is passed to the userspace to get a response, while GadgetFS responds to some USB requests internally based on the provided descriptors. However note, that the UDC driver might respond to some requests on its own and never forward them to the Gadget layer.
2. GadgetFS performs some sanity checks on the provided USB descriptors, while Raw Gadget allows you to provide arbitrary 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.
4. Raw Gadget uses predictable endpoint names (handles) across different UDCs (as long as UDCs have enough endpoints of each required transfer type).
5. Raw Gadget has ioctl-based interface instead of a filesystem-based one.
--- Documentation/usb/index.rst | 1 + Documentation/usb/raw-gadget.rst | 61 ++ drivers/usb/gadget/legacy/Kconfig | 11 + drivers/usb/gadget/legacy/Makefile | 1 + drivers/usb/gadget/legacy/raw_gadget.c | 1078 ++++++++++++++++++++++++ include/uapi/linux/usb/raw_gadget.h | 167 ++++ 6 files changed, 1319 insertions(+) create mode 100644 Documentation/usb/raw-gadget.rst create mode 100644 drivers/usb/gadget/legacy/raw_gadget.c create mode 100644 include/uapi/linux/usb/raw_gadget.h
Documentation/usb/index.rst +1 -0
@@ -22,6 +22,7 @@ USB support misc_usbsevseg mtouchusb ohci + raw-gadget usbip_protocol usbmon usb-serial
Documentation/usb/raw-gadget.rst new file +61 -0
61 lines not on this page · raw message
drivers/usb/gadget/legacy/Kconfig +11 -0
@@ -516,4 +516,15 @@ config USB_G_WEBCAM Say "y" to link the driver statically, or "m" to build a dynamically linked module called "g_webcam". +config USB_RAW_GADGET + tristate "USB Raw Gadget" + help + USB Raw Gadget is a kernel module that provides a userspace interface + for the USB Gadget subsystem. Essentially it allows to emulate USB + devices from userspace. See Documentation/usb/raw-gadget.rst for + details. + + Say "y" to link the driver statically, or "m" to build a + dynamically linked module called "raw_gadget". + endchoice
drivers/usb/gadget/legacy/Makefile +1 -0
@@ -43,3 +43,4 @@ obj-$(CONFIG_USB_G_WEBCAM) += g_webcam.o obj-$(CONFIG_USB_G_NCM) += g_ncm.o obj-$(CONFIG_USB_G_ACM_MS) += g_acm_ms.o obj-$(CONFIG_USB_GADGET_TARGET) += tcm_usb_gadget.o +obj-$(CONFIG_USB_RAW_GADGET) += raw_gadget.o
drivers/usb/gadget/legacy/raw_gadget.c new file +1078 -0
1,078 lines not on this page · raw message
include/uapi/linux/usb/raw_gadget.h new file +167 -0
167 lines not on this page · raw message
Signature · 1 line
2.25.0.265.gbab2e86ba0-goog
Quoted 23 lines · Andrey Konovalov
This patchset (currently a single patch) adds a new userspace interface for the USB Gadget subsystem called USB Raw Gadget. This is what is currently being used to enable coverage-guided USB fuzzing with syzkaller:
https://github.com/google/syzkaller/blob/master/docs/linux/external_fuzzing_usb.md
Initially I was using GadgetFS (together with the Dummy HCD/UDC module) to perform emulation of USB devices for fuzzing, but later switched to a custom written interface. The incentive to implement a different interface was to provide a somewhat raw and direct access to the USB Gadget layer for the userspace, where every USB request is passed to the userspace to get a response. See documentation for the list of differences between Raw Gadget and GadgetFS.
Currently Raw Gadget only supports blocking I/O mode, that synchronously waits for the result of each operation to allow collecting coverage per operation.
This patchset has been pushed to the public Linux kernel Gerrit instance:
https://linux-review.googlesource.com/c/linux/kernel/git/torvalds/linux/+/2144
Quoted 7 lines
Changes v5 -> v6:
- Preventraw_process_ep_io()racing withraw_ioctl_ep_disable()by checkingurb_queuedflag in the latter.
- UseGFP_KERNELinstead ofGFP_ATOMICwhere possible.
- Reject opening raw-gadget withO_NONBLOCKto allow future extensions to support nonblocking IO.
- ReduceRAW_EVENT_QUEUE_SIZEto 16.
Hi Felipe! I'm still hoping for a review :)
(Forgot to add a link to the example that emulates a USB keyboard via Raw Gadget into the cover letter:
https://github.com/xairy/raw-gadget/blob/master/examples/keyboard.c)
Quoted 54 lines
Changes v4 -> v5:
- Specified explicitusb_raw_event_typeenum values for all entries.
- Dropped pointless locking ingadget_unbind().Changes v3 -> v4:
- Print debug message when maxpacket check fails.
- Usemodule_misc_device()instead of module_init/exit().
- ReuseDRIVER_NAMEmacro inraw_devicestruct definition.
- Don't print WARNING inraw_release().
- Add comment that explains locking intoraw_event_queue_fetch().
- Print a WARNING when event queue size is exceeded.
- Renameraw.ctoraw_gadget.c.
- Mention module name inKconfig.
- Reworked logging to use dev_err/dbg() instead of pr_err/debug().Changes v2 -> v3:
- Updated device path in documentation.
- Changedusb_raw_initstruct layout to make it the same for 32 bit compat mode.
- Addedcompat_ioctltoraw_fops.
- Changedraw_ioctl_init()to return EINVAL for invalid USB speeds, except forUSB_SPEED_UNKNOWN, which defaults toUSB_SPEED_HIGH.
- Reject endpoints with maxpacket = 0 inraw_ioctl_ep_enable().Changes v1 -> v2:
- Movedraw.cto legacy/.
- Changed uapi header to use __u* types.
- Switched from debugfs entry to a misc device.
- Changedraw_devfrom refcount to kref.
- MovedUDC_NAME_LENGTH_MAXto uapi headers.
- Usedusb_endpoint_type()and usb_endpoint_dir_in/out() functions instead of open coding them.
- Added "WITH Linux-syscall-note" to SPDX id in the uapi header.
- Removedpr_err()if casedev_new()fails.
- Reduced the number of debugging messages.Andrey Konovalov (1):
usb: gadget: add raw-gadget interfaceDocumentation/usb/index.rst | 1 + Documentation/usb/raw-gadget.rst | 61 ++ drivers/usb/gadget/legacy/Kconfig | 11 + drivers/usb/gadget/legacy/Makefile | 1 + drivers/usb/gadget/legacy/raw_gadget.c | 1078 ++++++++++++++++++++++++ include/uapi/linux/usb/raw_gadget.h | 167 ++++ 6 files changed, 1319 insertions(+) create mode 100644 Documentation/usb/raw-gadget.rst create mode 100644 drivers/usb/gadget/legacy/raw_gadget.c create mode 100644 include/uapi/linux/usb/raw_gadget.h--
2.25.0.265.gbab2e86ba0-goog
Quoted 33 lines · Andrey Konovalov
Quoted 23 lines · Andrey Konovalov
This patchset (currently a single patch) adds a new userspace interface for the USB Gadget subsystem called USB Raw Gadget. This is what is currently being used to enable coverage-guided USB fuzzing with syzkaller:
https://github.com/google/syzkaller/blob/master/docs/linux/external_fuzzing_usb.md
Initially I was using GadgetFS (together with the Dummy HCD/UDC module) to perform emulation of USB devices for fuzzing, but later switched to a custom written interface. The incentive to implement a different interface was to provide a somewhat raw and direct access to the USB Gadget layer for the userspace, where every USB request is passed to the userspace to get a response. See documentation for the list of differences between Raw Gadget and GadgetFS.
Currently Raw Gadget only supports blocking I/O mode, that synchronously waits for the result of each operation to allow collecting coverage per operation.
This patchset has been pushed to the public Linux kernel Gerrit instance:
https://linux-review.googlesource.com/c/linux/kernel/git/torvalds/linux/+/2144
Quoted 7 lines
Changes v5 -> v6:
- Preventraw_process_ep_io()racing withraw_ioctl_ep_disable()by checkingurb_queuedflag in the latter.
- UseGFP_KERNELinstead ofGFP_ATOMICwhere possible.
- Reject opening raw-gadget withO_NONBLOCKto allow future extensions to support nonblocking IO.
- ReduceRAW_EVENT_QUEUE_SIZEto 16.
Quoted 6 lines
Hi Felipe! I'm still hoping for a review :)
(Forgot to add a link to the example that emulates a USB keyboard via Raw Gadget into the cover letter:
https://github.com/xairy/raw-gadget/blob/master/examples/keyboard.c)
Hi Greg, Felipe, and Alan,
I was wondering if there's a way to move forward with this patch?
Alan, since you have a very good knowledge of the USB subsystem, could I ask you to take a look at the patch, while Felipe is busy?
Thanks!
Quoted 55 lines
Quoted 55 lines
Changes v4 -> v5:
- Specified explicitusb_raw_event_typeenum values for all entries.
- Dropped pointless locking ingadget_unbind().Changes v3 -> v4:
- Print debug message when maxpacket check fails.
- Usemodule_misc_device()instead of module_init/exit().
- ReuseDRIVER_NAMEmacro inraw_devicestruct definition.
- Don't print WARNING inraw_release().
- Add comment that explains locking intoraw_event_queue_fetch().
- Print a WARNING when event queue size is exceeded.
- Renameraw.ctoraw_gadget.c.
- Mention module name inKconfig.
- Reworked logging to use dev_err/dbg() instead of pr_err/debug().Changes v2 -> v3:
- Updated device path in documentation.
- Changedusb_raw_initstruct layout to make it the same for 32 bit compat mode.
- Addedcompat_ioctltoraw_fops.
- Changedraw_ioctl_init()to return EINVAL for invalid USB speeds, except forUSB_SPEED_UNKNOWN, which defaults toUSB_SPEED_HIGH.
- Reject endpoints with maxpacket = 0 inraw_ioctl_ep_enable().Changes v1 -> v2:
- Movedraw.cto legacy/.
- Changed uapi header to use __u* types.
- Switched from debugfs entry to a misc device.
- Changedraw_devfrom refcount to kref.
- MovedUDC_NAME_LENGTH_MAXto uapi headers.
- Usedusb_endpoint_type()and usb_endpoint_dir_in/out() functions instead of open coding them.
- Added "WITH Linux-syscall-note" to SPDX id in the uapi header.
- Removedpr_err()if casedev_new()fails.
- Reduced the number of debugging messages.Andrey Konovalov (1):
usb: gadget: add raw-gadget interfaceDocumentation/usb/index.rst | 1 + Documentation/usb/raw-gadget.rst | 61 ++ drivers/usb/gadget/legacy/Kconfig | 11 + drivers/usb/gadget/legacy/Makefile | 1 + drivers/usb/gadget/legacy/raw_gadget.c | 1078 ++++++++++++++++++++++++ include/uapi/linux/usb/raw_gadget.h | 167 ++++ 6 files changed, 1319 insertions(+) create mode 100644 Documentation/usb/raw-gadget.rst create mode 100644 drivers/usb/gadget/legacy/raw_gadget.c create mode 100644 include/uapi/linux/usb/raw_gadget.h--
2.25.0.265.gbab2e86ba0-goog
Quoted 6 lines · Andrey Konovalov
Hi Greg, Felipe, and Alan,
I was wondering if there's a way to move forward with this patch?
Alan, since you have a very good knowledge of the USB subsystem, could I ask you to take a look at the patch, while Felipe is busy?
I'll look through the driver when I get a chance. That might not be for a while, though...
Alan Stern