← Documents Documentation/usb/raw-gadget.rst GitHub 원문 ↗

Linux 6.18.37 · USB

USB Raw Gadget

Raw Gadget과 GadgetFS의 차이, ioctl interface, UDC endpoint 선택과 fuzzing 설계를 설명합니다.

Source pathDocumentation/usb/raw-gadget.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

raw-gadget.rst:1-91

Raw Gadget과 GadgetFS의 차이, ioctl interface, UDC endpoint 선택과 fuzzing 설계를 설명합니다.

원문 명령, symbol, source path, 수치와 ABI 이름을 그대로 유지하면서 각 절의 의미와 주의 사항을 한국어로 옮겼습니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 ==============
2 USB Raw Gadget
3 ==============
4
5 USB Raw Gadget is a gadget driver that gives userspace low-level control over
6 the gadget's communication process.
7
8 Like any other gadget driver, Raw Gadget implements USB devices via the
9 USB gadget API. Unlike most gadget drivers, Raw Gadget does not implement
10 any concrete USB functions itself but requires userspace to do that.
11
12 Raw Gadget is currently a strictly debugging feature and should not be used
13 in production. Use GadgetFS instead.
14
15 Enabled with CONFIG_USB_RAW_GADGET.
16
17 Comparison to GadgetFS
18 ~~~~~~~~~~~~~~~~~~~~~~
19
20 Raw Gadget is similar to GadgetFS but provides more direct access to the
21 USB gadget layer for userspace. The key differences are:
22
23 1. Raw Gadget passes every USB request to userspace to get a response, while
24 GadgetFS responds to some USB requests internally based on the provided
25 descriptors. Note that the UDC driver might respond to some requests on
26 its own and never forward them to the gadget layer.
27
28 2. Raw Gadget allows providing arbitrary data as responses to USB requests,
29 while GadgetFS performs sanity checks on the provided USB descriptors.
30 This makes Raw Gadget suitable for fuzzing by providing malformed data as
31 responses to USB requests.
32
33 3. Raw Gadget provides a way to select a UDC device/driver to bind to,
34 while GadgetFS currently binds to the first available UDC. This allows
35 having multiple Raw Gadget instances bound to different UDCs.
36
37 4. Raw Gadget explicitly exposes information about endpoints addresses and
38 capabilities. This allows the user to write UDC-agnostic gadgets.
39
40 5. Raw Gadget has an ioctl-based interface instead of a filesystem-based
41 one.
42
43 Userspace interface
44 ~~~~~~~~~~~~~~~~~~~
45
46 The user can interact with Raw Gadget by opening ``/dev/raw-gadget`` and
47 issuing ioctl calls; see the comments in include/uapi/linux/usb/raw_gadget.h
48 for details. Multiple Raw Gadget instances (bound to different UDCs) can be
49 used at the same time.
50
51 A typical usage scenario of Raw Gadget:
52
53 1. Create a Raw Gadget instance by opening ``/dev/raw-gadget``.
54 2. Initialize the instance via ``USB_RAW_IOCTL_INIT``.
55 3. Launch the instance with ``USB_RAW_IOCTL_RUN``.
56 4. In a loop issue ``USB_RAW_IOCTL_EVENT_FETCH`` to receive events from
57 Raw Gadget and react to those depending on what kind of USB gadget must
58 be implemented.
59
60 Note that some UDC drivers have fixed addresses assigned to endpoints, and
61 therefore arbitrary endpoint addresses cannot be used in the descriptors.
62 Nevertheless, Raw Gadget provides a UDC-agnostic way to write USB gadgets.
63 Once ``USB_RAW_EVENT_CONNECT`` is received via ``USB_RAW_IOCTL_EVENT_FETCH``,
64 ``USB_RAW_IOCTL_EPS_INFO`` can be used to find out information about the
65 endpoints that the UDC driver has. Based on that, userspace must choose UDC
66 endpoints for the gadget and assign addresses in the endpoint descriptors
67 correspondingly.
68
69 Raw Gadget usage examples and a test suite:
70
71 https://github.com/xairy/raw-gadget
72
73 Internal details
74 ~~~~~~~~~~~~~~~~
75
76 Every Raw Gadget endpoint read/write ioctl submits a USB request and waits
77 until its completion. This is done deliberately to assist with coverage-guided
78 fuzzing by having a single syscall fully process a single USB request. This
79 feature must be kept in the implementation.
80
81 Potential future improvements
82 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
83
84 - Support ``O_NONBLOCK`` I/O. This would be another mode of operation, where
85 Raw Gadget would not wait until the completion of each USB request.
86
87 - Support USB 3 features (accept SS endpoint companion descriptor when
88 enabling endpoints; allow providing ``stream_id`` for bulk transfers).
89
90 - Support ISO transfer features (expose ``frame_number`` for completed
91 requests).
92

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

개요와 사용 제한

1-16

USB Raw Gadget은 gadget 통신 과정을 사용자 공간에서 저수준으로 제어하게 하는 gadget driver입니다.

다른 gadget driver처럼 USB gadget API로 USB device를 구현하지만 구체적인 USB function은 자체 구현하지 않고 사용자 공간에 맡깁니다.

현재는 엄격히 debugging용 기능이며 production에서 사용하면 안 됩니다. production 용도에는 GadgetFS를 사용해야 합니다.

kernel option `CONFIG_USB_RAW_GADGET`으로 활성화합니다.

Raw Gadget 성격
항목설명
Kernel optionCONFIG_USB_RAW_GADGET
USB functionuserspace가 구현
Purposedebugging / fuzzing
Production사용 금지, GadgetFS 권장

구현 책임과 지원 범위를 요약합니다.

==============
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.

GadgetFS와 비교

17-42

Raw Gadget은 GadgetFS와 비슷하지만 USB gadget layer를 사용자 공간에 더 직접 노출합니다.

Raw Gadget은 모든 USB request를 사용자 공간에 전달해 응답을 받습니다. GadgetFS는 제공된 descriptor를 바탕으로 일부 request에 내부 응답합니다. 다만 UDC driver가 gadget layer로 넘기지 않고 자체 응답하는 request도 있습니다.

Raw Gadget은 arbitrary data를 응답으로 허용하지만 GadgetFS는 USB descriptor sanity check를 수행합니다. 그래서 malformed response를 제공하는 fuzzing에는 Raw Gadget이 적합합니다.

Raw Gadget은 bind할 UDC device/driver를 선택할 수 있어 여러 instance를 서로 다른 UDC에 연결할 수 있습니다. GadgetFS는 현재 첫 available UDC에 bind합니다.

Raw Gadget은 endpoint address와 capability를 명시적으로 노출해 UDC-independent gadget을 작성할 수 있게 합니다.

interface는 filesystem 기반이 아니라 ioctl 기반입니다.

Raw Gadget 대 GadgetFS
항목설명
USB requestRaw: 모두 userspace / GadgetFS: 일부 내부 응답
Response validationRaw: arbitrary data / GadgetFS: descriptor sanity check
UDC bindingRaw: 선택 가능 / GadgetFS: 첫 available UDC
Endpoint infoRaw: address/capability 명시 노출
InterfaceRaw: ioctl / GadgetFS: filesystem

request 처리, validation, UDC 선택, endpoint 정보와 interface 차이입니다.

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.

사용자 공간 interface

43-72

사용자는 `/dev/raw-gadget`을 열고 ioctl을 호출합니다. 자세한 계약은 `include/uapi/linux/usb/raw_gadget.h`의 주석에 있습니다.

서로 다른 UDC에 bind한 Raw Gadget instance를 동시에 여러 개 사용할 수 있습니다.

일반적인 순서는 device file open, `USB_RAW_IOCTL_INIT`, `USB_RAW_IOCTL_RUN`, 반복적인 `USB_RAW_IOCTL_EVENT_FETCH`와 event별 응답입니다.

일부 UDC driver는 endpoint address가 고정되어 descriptor에 arbitrary address를 사용할 수 없습니다.

`USB_RAW_EVENT_CONNECT`를 받으면 `USB_RAW_IOCTL_EPS_INFO`로 UDC endpoint 정보를 얻고 사용자 공간이 gadget endpoint를 고른 뒤 descriptor address를 맞춰야 합니다.

사용 예제와 test suite는 `https://github.com/xairy/raw-gadget`에 있습니다.

Raw Gadget instance 수명주기
open /dev/raw-gadgetUSB_RAW_IOCTL_INITUSB_RAW_IOCTL_RUNUSB_RAW_IOCTL_EVENT_FETCH loopevent별 userspace response

device open부터 event loop까지 ioctl 순서입니다.

UDC-independent endpoint 선택
USB_RAW_EVENT_CONNECTUSB_RAW_IOCTL_EPS_INFOUDC endpoint capability 확인endpoint 선택descriptor address 지정

connect event 뒤 실제 UDC capability에 맞춰 descriptor address를 결정합니다.

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

내부 동작

73-80

각 Raw Gadget endpoint read/write ioctl은 USB request를 submit하고 완료될 때까지 기다립니다.

한 syscall이 USB request 하나를 완전히 처리하게 해 coverage-guided fuzzing을 돕기 위한 의도적 설계이므로 구현에서 유지해야 합니다.

동기 endpoint ioctl
read/write ioctlUSB request submitcompletion 대기syscall return

한 syscall과 한 USB request를 대응시켜 fuzzing coverage를 명확하게 합니다.

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.

향후 개선 가능성

81-91

`O_NONBLOCK` I/O 지원을 추가하면 각 request 완료를 기다리지 않는 별도 operation mode를 제공할 수 있습니다.

USB 3 지원 후보에는 endpoint enable 시 SS endpoint companion descriptor 수용과 bulk transfer의 `stream_id` 제공이 있습니다.

ISO transfer 지원 후보에는 완료 request의 `frame_number` 노출이 있습니다.

Raw Gadget 향후 개선
항목설명
O_NONBLOCKrequest completion을 기다리지 않는 mode
USB 3SS companion descriptor, bulk stream_id
ISOcompleted request의 frame_number 노출

비동기 I/O와 USB 3/ISO 기능 후보입니다.

Potential future improvements
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

- 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).