github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/sys/linux/vusb.txt (about) 1 # Copyright 2019 syzkaller project authors. All rights reserved. 2 # Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. 3 4 include <linux/types.h> 5 include <linux/byteorder/generic.h> 6 7 include <uapi/linux/usb/ch9.h> 8 include <uapi/linux/usb/ch11.h> 9 10 include <uapi/linux/usb/audio.h> 11 include <uapi/linux/hid.h> 12 include <linux/hid.h> 13 include <uapi/linux/usb/cdc.h> 14 include <uapi/linux/if_ether.h> 15 include <linux/interrupt.h> 16 include <linux/usb/cdc_ncm.h> 17 include <drivers/net/usb/asix.h> 18 19 # This is a special fd for USB fuzzing and should only be used with syz_usb_* pseudo-syscalls. 20 # We don't inherit it from the fd resource, to discourage syzkaller calling raw ioctls on it. 21 resource fd_usb[int32]: -1 22 23 # These are generic pseudo-syscalls for emulating arbitrary USB devices. 24 # They are mostly targeted to cover the enumeration process. 25 syz_usb_connect(speed flags[usb_device_speed], dev_len len[dev], dev ptr[in, usb_device_descriptor], conn_descs ptr[in, vusb_connect_descriptors]) fd_usb (timeout[3000], prog_timeout[3000]) 26 syz_usb_control_io(fd fd_usb, descs ptr[in, vusb_descriptors], resps ptr[in, vusb_responses]) (timeout[300]) 27 syz_usb_ep_write(fd fd_usb, ep int8, len len[data], data ptr[in, array[int8, 0:256]]) (timeout[300]) 28 syz_usb_ep_read(fd fd_usb, ep int8, len len[data], data buffer[out]) (timeout[300]) 29 syz_usb_disconnect(fd fd_usb) (timeout[300]) 30 31 usb_device_speed = USB_SPEED_UNKNOWN, USB_SPEED_LOW, USB_SPEED_FULL, USB_SPEED_HIGH, USB_SPEED_WIRELESS, USB_SPEED_SUPER, USB_SPEED_SUPER_PLUS 32 33 # TODO: consider patching idVendor and idProduct for all class specific descriptions in Go code to cover more drivers. 34 # TODO: custom syz_usb_ep_write() descriptions for all class specific descriptions. 35 # TODO: consider adding custom vusb_connect_descriptors definitions to all class specific descriptions. 36 37 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 38 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 39 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 40 41 type usb_device_descriptor_verbose_t[USB, CLASS, SUBCLASS, PROTOCOL, PACKET, VENDOR, PRODUCT, DEVICE, CFS] { 42 bLength const[USB_DT_DEVICE_SIZE, int8] 43 bDescriptorType const[USB_DT_DEVICE, int8] 44 45 bcdUSB USB 46 bDeviceClass const[CLASS, int8] 47 bDeviceSubClass const[SUBCLASS, int8] 48 bDeviceProtocol const[PROTOCOL, int8] 49 bMaxPacketSize0 PACKET 50 idVendor const[VENDOR, int16] 51 idProduct const[PRODUCT, int16] 52 bcdDevice const[DEVICE, int16] 53 iManufacturer const[1, int8] 54 iProduct const[2, int8] 55 iSerialNumber const[3, int8] 56 bNumConfigurations len[configs, int8] 57 58 configs CFS 59 } [packed] 60 61 type usb_device_descriptor_t[CLASS, SUBCLASS, PROTOCOL, VENDOR, PRODUCT, DEVICE, CFS] usb_device_descriptor_verbose_t[flags[usb_versions, int16], CLASS, SUBCLASS, PROTOCOL, flags[usb_device_max_packet_sizes, int8], VENDOR, PRODUCT, DEVICE, CFS] 62 type usb_device_descriptor_fixed_t[USB, CLASS, SUBCLASS, PROTOCOL, PACKET, VENDOR, PRODUCT, DEVICE, CFS] usb_device_descriptor_verbose_t[const[USB, int16], CLASS, SUBCLASS, PROTOCOL, const[PACKET, int8], VENDOR, PRODUCT, DEVICE, CFS] 63 64 usb_versions = 0x110, 0x200, 0x201, 0x250, 0x300, 0x310 65 66 # https://elixir.bootlin.com/linux/v5.1.7/source/drivers/usb/core/hub.c#L4661 67 usb_device_max_packet_sizes = 8, 16, 32, 64, 255 68 69 type usb_config_descriptor_verbose_t[NUM, IFSNUM, ICONFIG, ATTRS, POWER, IFS] { 70 bLength const[USB_DT_CONFIG_SIZE, int8] 71 bDescriptorType const[USB_DT_CONFIG, int8] 72 73 wTotalLength len[parent, int16] 74 bNumInterfaces IFSNUM 75 bConfigurationValue NUM 76 iConfiguration ICONFIG 77 bmAttributes ATTRS 78 bMaxPower POWER 79 80 interfaces IFS 81 } [packed] 82 83 type usb_config_descriptor_t[NUM, IFSNUM, IFS] usb_config_descriptor_verbose_t[NUM, IFSNUM, int8, flags[usb_config_attributes, int8], int8, IFS] 84 type usb_config_descriptor_ifaces_array_t[NUM, IFS] usb_config_descriptor_t[NUM, len[interfaces, int8], IFS] 85 type usb_config_descriptor_fixed_t[NUM, IFSNUM, ATTRS, POWER, IFS] usb_config_descriptor_verbose_t[const[NUM, int8], const[IFSNUM, int8], const[0, int8], const[ATTRS, int8], const[POWER, int8], IFS] 86 87 type usb_interface_descriptor_verbose_t[IFNUM, ALTNUM, EPSNUM, CLASS, SUBCLASS, PROTOCOL, IIF, EXTRA, EPS] { 88 bLength const[USB_DT_INTERFACE_SIZE, int8] 89 bDescriptorType const[USB_DT_INTERFACE, int8] 90 91 bInterfaceNumber IFNUM 92 bAlternateSetting ALTNUM 93 bNumEndpoints EPSNUM 94 bInterfaceClass CLASS 95 bInterfaceSubClass SUBCLASS 96 bInterfaceProtocol PROTOCOL 97 iInterface IIF 98 99 extra EXTRA 100 endpoints EPS 101 } [packed] 102 103 type usb_interface_descriptor_t[IFNUM, ALTNUM, EPSNUM, CLASS, SUBCLASS, PROTOCOL, EXTRA, EPS] usb_interface_descriptor_verbose_t[IFNUM, ALTNUM, EPSNUM, CLASS, SUBCLASS, PROTOCOL, int8, EXTRA, EPS] 104 type usb_interface_descriptor_eps_array_t[IFNUM, ALTNUM, CLASS, SUBCLASS, PROTOCOL, EXTRA, EPS] usb_interface_descriptor_t[IFNUM, ALTNUM, len[endpoints, int8], CLASS, SUBCLASS, PROTOCOL, EXTRA, EPS] 105 type usb_interface_descriptor_fixed_t[IFNUM, ALTNUM, EPSNUM, CLASS, SUBCLASS, PROTOCOL, EXTRA, EPS] usb_interface_descriptor_verbose_t[const[IFNUM, int8], const[ALTNUM, int8], const[EPSNUM, int8], const[CLASS, int8], const[SUBCLASS, int8], const[PROTOCOL, int8], const[0, int8], EXTRA, EPS] 106 107 # TODO: non-audio endpoints have USB_DT_ENDPOINT_SIZE. 108 type usb_endpoint_descriptor_verbose_t[ADDR, ATTRS, PACKET, INTERVAL, REFRESH, SYNCH, EXTRA] { 109 bLength const[USB_DT_ENDPOINT_AUDIO_SIZE, int8] 110 bDescriptorType const[USB_DT_ENDPOINT, int8] 111 112 bEndpointAddress ADDR 113 bmAttributes ATTRS 114 wMaxPacketSize PACKET 115 bInterval INTERVAL 116 117 bRefresh REFRESH 118 bSynchAddress SYNCH 119 120 extra EXTRA 121 } [packed] 122 123 type usb_endpoint_descriptor_t[ADDR, ATTRS, EXTRA] usb_endpoint_descriptor_verbose_t[ADDR, ATTRS, flags[usb_endpoint_max_packet_sizes, int16], int8, int8, int8, EXTRA] 124 type usb_endpoint_descriptor_fixed_t[ADDR, ATTRS, PACKET, INTERVAL, EXTRA] usb_endpoint_descriptor_verbose_t[const[ADDR, int8], const[ATTRS, int8], const[PACKET, int16], const[INTERVAL, int8], const[0, int8], const[0, int8], EXTRA] 125 126 # TODO: dummy driver has complex requirements for packet sizes, account for those: 127 # https://elixir.bootlin.com/linux/v5.3.6/source/drivers/usb/gadget/udc/dummy_hcd.c#L497 128 usb_endpoint_max_packet_sizes = 8, 16, 32, 64, 512, 1023, 1024 129 130 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 131 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 132 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 133 134 # Generic USB device, configuration, interface and endpoint descriptors. 135 136 # We only support one configuration per device. 137 # bDeviceClass, bDeviceSubClass, bDeviceProtocol, idVendor, idProduct 138 # and bcdDevice are patched by Go code, see sys/linux/init_vusb.go. 139 usb_device_descriptor { 140 inner usb_device_descriptor_t[0, 0, 0, 0, 0, 0, array[usb_config_descriptor, 1]] 141 } [packed] 142 143 usb_config_descriptor { 144 inner usb_config_descriptor_ifaces_array_t[int8, array[usb_interface_descriptor, 1:4]] 145 } [packed] 146 147 usb_config_attributes = USB_CONFIG_ATT_ONE, USB_CONFIG_ATT_SELFPOWER, USB_CONFIG_ATT_WAKEUP, USB_CONFIG_ATT_BATTERY 148 149 # bInterfaceNumber, bInterfaceClass, bInterfaceSubClass and bInterfaceProtocol 150 # are patched by Go code, see sys/linux/init_vusb.go. 151 usb_interface_descriptor { 152 inner usb_interface_descriptor_eps_array_t[int8, int8, const[0, int8], const[0, int8], const[0, int8], array[usb_interface_extra_descriptor, 0:2], array[usb_endpoint_descriptor, 0:16]] 153 } [packed] 154 155 usb_endpoint_descriptor { 156 inner usb_endpoint_descriptor_t[flags[usb_endpoint_addresses, int8], flags[usb_endpoint_attributes, int8], array[usb_endpoint_extra_descriptor, 0:2]] 157 } [packed] 158 159 usb_endpoint_addresses = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, USB_DIR_OUT, USB_DIR_IN 160 161 usb_endpoint_attributes = USB_ENDPOINT_XFER_CONTROL, USB_ENDPOINT_XFER_ISOC, USB_ENDPOINT_XFER_BULK, USB_ENDPOINT_XFER_INT, USB_ENDPOINT_INTR_PERIODIC, USB_ENDPOINT_INTR_NOTIFICATION, USB_ENDPOINT_SYNC_NONE, USB_ENDPOINT_SYNC_ASYNC, USB_ENDPOINT_SYNC_ADAPTIVE, USB_ENDPOINT_SYNC_SYNC, USB_ENDPOINT_USAGE_DATA, USB_ENDPOINT_USAGE_FEEDBACK, USB_ENDPOINT_USAGE_FEEDBACK 162 163 vusb_connect_descriptors { 164 qual_len len[qual, int32] 165 qual ptr[in, usb_qualifier_descriptor] 166 bos_len len[bos, int32] 167 bos ptr[in, usb_bos_descriptor] 168 strs_len len[strs, int32] 169 strs array[vusb_connect_string_descriptor] 170 } [packed] 171 172 vusb_connect_string_descriptor { 173 len len[str, int32] 174 str ptr[in, usb_string_descriptor] 175 } [packed] 176 177 vusb_descriptors { 178 len len[parent, int32] 179 generic ptr[in, vusb_descriptor_generic] 180 181 string ptr[in, vusb_descriptor_t[USB_TYPE_STANDARD, USB_DT_STRING, usb_string_descriptor]] 182 bos ptr[in, vusb_descriptor_t[USB_TYPE_STANDARD, USB_DT_BOS, usb_bos_descriptor]] 183 184 hub_hs ptr[in, vusb_descriptor_t[USB_TYPE_CLASS, USB_DT_HUB, usb_hub_descriptor_hs]] 185 hub_ss ptr[in, vusb_descriptor_t[USB_TYPE_CLASS, USB_DT_SS_HUB, usb_hub_descriptor_ss]] 186 } [packed] 187 188 vusb_descriptor_generic { 189 req_type flags[usb_request_types, int8] 190 desc_type flags[usb_descriptor_types, int8] 191 len bytesize[data, int32] 192 data usb_generic_descriptor 193 } [packed] 194 195 usb_request_types = USB_TYPE_STANDARD, USB_TYPE_CLASS, USB_TYPE_VENDOR 196 197 type vusb_descriptor_t[CLASS, REQ, DATA] { 198 type const[CLASS, int8] 199 req const[REQ, int8] 200 len bytesize[data, int32] 201 data DATA 202 } [packed] 203 204 # TODO: consider doing lookups based on USB_RECIP values. 205 vusb_responses { 206 len len[parent, int32] 207 generic ptr[in, vusb_response_generic] 208 209 get_interface ptr[in, vusb_response_t[USB_TYPE_STANDARD, USB_REQ_GET_INTERFACE, int8]] 210 get_configuration ptr[in, vusb_response_t[USB_TYPE_STANDARD, USB_REQ_GET_CONFIGURATION, int8]] 211 212 # TODO: move these into custom descriptions for hub class when they are added. 213 hub_USB_REQ_GET_STATUS_hub ptr[in, vusb_response_t[USB_TYPE_CLASS, USB_REQ_GET_STATUS, usb_hub_status]] 214 hub_USB_REQ_GET_STATUS_port ptr[in, vusb_response_t[USB_TYPE_CLASS, USB_REQ_GET_STATUS, usb_port_status]] 215 216 # TODO: move these into custom descriptions for asix driver when they are added. 217 asix_AX_CMD_READ_MII_REG ptr[in, vusb_response_t[USB_TYPE_VENDOR, AX_CMD_READ_MII_REG, int16]] 218 asix_AX_CMD_STATMNGSTS_REG ptr[in, vusb_response_t[USB_TYPE_VENDOR, AX_CMD_STATMNGSTS_REG, int8]] 219 asix_AX_CMD_READ_EEPROM ptr[in, vusb_response_t[USB_TYPE_VENDOR, AX_CMD_READ_EEPROM, array[int8, 2]]] 220 asix_AX_CMD_READ_RX_CTL ptr[in, vusb_response_t[USB_TYPE_VENDOR, AX_CMD_READ_RX_CTL, int16]] 221 asix_AX_CMD_READ_NODE_ID ptr[in, vusb_response_t[USB_TYPE_VENDOR, AX_CMD_READ_NODE_ID, mac_addr]] 222 asix_AX88172_CMD_READ_NODE_ID ptr[in, vusb_response_t[USB_TYPE_VENDOR, AX88172_CMD_READ_NODE_ID, mac_addr]] 223 asix_AX_CMD_READ_PHY_ID ptr[in, vusb_response_t[USB_TYPE_VENDOR, AX_CMD_READ_PHY_ID, array[int8, 2]]] 224 asix_AX_CMD_READ_MEDIUM_STATUS ptr[in, vusb_response_t[USB_TYPE_VENDOR, AX_CMD_READ_MEDIUM_STATUS, int16]] 225 asix_AX_CMD_READ_MONITOR_MODE ptr[in, vusb_response_t[USB_TYPE_VENDOR, AX_CMD_READ_MONITOR_MODE, int8]] 226 asix_AX_CMD_READ_GPIOS ptr[in, vusb_response_t[USB_TYPE_VENDOR, AX_CMD_READ_GPIOS, int8]] 227 asix_AX_CMD_SW_PHY_STATUS ptr[in, vusb_response_t[USB_TYPE_VENDOR, AX_CMD_SW_PHY_STATUS, int8]] 228 } [packed] 229 230 vusb_response_generic { 231 type flags[usb_request_types, int8] 232 req flags[usb_requests, int8] 233 len bytesize[data, int32] 234 data array[int8, 0:256] 235 } [packed] 236 237 usb_requests = USB_REQ_GET_STATUS, USB_REQ_CLEAR_FEATURE, USB_REQ_SET_FEATURE, USB_REQ_SET_ADDRESS, USB_REQ_GET_DESCRIPTOR, USB_REQ_SET_DESCRIPTOR, USB_REQ_GET_CONFIGURATION, USB_REQ_SET_CONFIGURATION, USB_REQ_GET_INTERFACE, USB_REQ_SET_INTERFACE, USB_REQ_SYNCH_FRAME, USB_REQ_SET_SEL, USB_REQ_SET_ISOCH_DELAY, USB_REQ_SET_ENCRYPTION, USB_REQ_GET_ENCRYPTION, USB_REQ_RPIPE_ABORT, USB_REQ_SET_HANDSHAKE, USB_REQ_RPIPE_RESET, USB_REQ_GET_HANDSHAKE, USB_REQ_SET_CONNECTION, USB_REQ_SET_SECURITY_DATA, USB_REQ_GET_SECURITY_DATA, USB_REQ_SET_WUSB_DATA, USB_REQ_LOOPBACK_DATA_WRITE, USB_REQ_LOOPBACK_DATA_READ, USB_REQ_SET_INTERFACE_DS, USB_REQ_GET_PARTNER_PDO, USB_REQ_GET_BATTERY_STATUS, USB_REQ_SET_PDO, USB_REQ_GET_VDM, USB_REQ_SEND_VDM 238 239 type vusb_response_t[CLASS, REQ, DATA] { 240 type const[CLASS, int8] 241 req const[REQ, int8] 242 len bytesize[data, int32] 243 data DATA 244 } [packed] 245 246 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 247 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 248 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 249 250 # USB descriptors requested by the kernel before the SET_CONFIGURATION request. 251 252 # TODO: figure out when is the USB_DT_OTG descriptor used. 253 # TODO: figure out when is the USB_DT_INTERFACE_ASSOCIATION descriptor used. 254 # TODO: figure out when is the USB_DT_BOS descriptor used. 255 256 type usb_string_descriptor_t[DATA] { 257 bLength len[parent, int8] 258 bDescriptorType const[USB_DT_STRING, int8] 259 260 data DATA 261 } [packed] 262 263 usb_string_descriptor [ 264 lang_id usb_string_descriptor_t[flags[usb_lang_ids, int16]] 265 string usb_string_descriptor_t[array[int8, 0:256]] 266 ] [varlen] 267 268 usb_lang_ids = 0x436, 0x41c, 0x401, 0x801, 0xc01, 0x1001, 0x1401, 0x1801, 0x1c01, 0x2001, 0x2401, 0x2801, 0x2c01, 0x3001, 0x3401, 0x3801, 0x3c01, 0x4001, 0x42b, 0x44d, 0x42c, 0x82c, 0x42d, 0x423, 0x445, 0x402, 0x455, 0x403, 0x404, 0x804, 0xc04, 0x1004, 0x1404, 0x41a, 0x405, 0x406, 0x413, 0x813, 0x409, 0x809, 0xc09, 0x1009, 0x1409, 0x1809, 0x1c09, 0x2009, 0x2409, 0x2809, 0x2c09, 0x3009, 0x3409, 0x425, 0x438, 0x429, 0x40b, 0x40c, 0x80c, 0xc0c, 0x100c, 0x140c, 0x180c, 0x437, 0x407, 0x807, 0xc07, 0x1007, 0x1407, 0x408, 0x447, 0x40d, 0x439, 0x40e, 0x40f, 0x421, 0x410, 0x810, 0x411, 0x44b, 0x860, 0x43f, 0x457, 0x412, 0x812, 0x426, 0x427, 0x827, 0x42f, 0x43e, 0x83e, 0x44c, 0x458, 0x44e, 0x861, 0x414, 0x814, 0x448, 0x415, 0x416, 0x816, 0x446, 0x418, 0x419, 0x44f, 0xc1a, 0x81a, 0x459, 0x41b, 0x424, 0x40a, 0x80a, 0xc0a, 0x100a, 0x140a, 0x180a, 0x1c0a, 0x200a, 0x240a, 0x280a, 0x2c0a, 0x300a, 0x340a, 0x380a, 0x3c0a, 0x400a, 0x440a, 0x480a, 0x4c0a, 0x500a, 0x430, 0x441, 0x41d, 0x81d, 0x449, 0x444, 0x44a, 0x41e, 0x41f, 0x422, 0x420, 0x820, 0x443, 0x843, 0x42a, 0x4ff, 0xf0ff, 0xf4ff, 0xf8ff, 0xfcff 269 270 usb_qualifier_descriptor { 271 bLength len[parent, int8] 272 bDescriptorType const[USB_DT_DEVICE_QUALIFIER, int8] 273 274 bcdUSB flags[usb_versions, int16] 275 bDeviceClass int8 276 bDeviceSubClass int8 277 bDeviceProtocol int8 278 bMaxPacketSize0 flags[usb_device_max_packet_sizes, int8] 279 bNumConfigurations int8 280 bRESERVED const[0, int8] 281 } [packed] 282 283 usb_bos_descriptor { 284 bLength const[USB_DT_BOS_SIZE, int8] 285 bDescriptorType const[USB_DT_BOS, int8] 286 287 wTotalLength len[parent, int16] 288 bNumDeviceCaps len[caps, int8] 289 290 caps array[usb_dev_cap, 0:6] 291 } [packed] 292 293 usb_dev_cap [ 294 generic usb_generic_cap_descriptor 295 wireless usb_wireless_cap_descriptor 296 ext_cap usb_ext_cap_descriptor 297 ss_cap usb_ss_cap_descriptor 298 ss_container_id usb_ss_container_id_descriptor 299 ssp_cap usb_ssp_cap_descriptor 300 ptm_cap usb_ptm_cap_descriptor 301 ] [varlen] 302 303 usb_generic_cap_descriptor { 304 bLength len[parent, int8] 305 bDescriptorType const[USB_DT_DEVICE_CAPABILITY, int8] 306 bDevCapabilityType flags[usb_capability_types, int8] 307 308 data array[int8, 0:256] 309 } [packed] 310 311 usb_capability_types = USB_CAP_TYPE_WIRELESS_USB, USB_CAP_TYPE_EXT, USB_SS_CAP_TYPE, USB_SSP_CAP_TYPE, CONTAINER_ID_TYPE, USB_PTM_CAP_TYPE 312 313 usb_wireless_cap_descriptor { 314 bLength len[parent, int8] 315 bDescriptorType const[USB_DT_DEVICE_CAPABILITY, int8] 316 bDevCapabilityType const[USB_CAP_TYPE_WIRELESS_USB, int8] 317 318 bmAttributes flags[usb_wireless_cap_attributes, int8] 319 wPHYRates flags[usb_wireless_cap_phyrates, int16] 320 bmTFITXPowerInfo int8 321 bmFFITXPowerInfo int8 322 bmBandGroup int16 323 bReserved int8 324 } [packed] 325 326 usb_wireless_cap_attributes = USB_WIRELESS_P2P_DRD, USB_WIRELESS_BEACON_MASK, USB_WIRELESS_BEACON_SELF, USB_WIRELESS_BEACON_DIRECTED, USB_WIRELESS_BEACON_NONE 327 328 usb_wireless_cap_phyrates = USB_WIRELESS_PHY_53, USB_WIRELESS_PHY_80, USB_WIRELESS_PHY_107, USB_WIRELESS_PHY_160, USB_WIRELESS_PHY_200, USB_WIRELESS_PHY_320, USB_WIRELESS_PHY_400, USB_WIRELESS_PHY_480 329 330 usb_ext_cap_descriptor { 331 bLength len[parent, int8] 332 bDescriptorType const[USB_DT_DEVICE_CAPABILITY, int8] 333 bDevCapabilityType const[USB_CAP_TYPE_EXT, int8] 334 335 bmAttributes1 flags[usb_ext_cap_attributes, int32:8] 336 bmAttributes2 int32:4 337 bmAttributes3 int32:4 338 bmAttributes4 int32:16 339 } [packed] 340 341 usb_ext_cap_attributes = USB_LPM_SUPPORT, USB_BESL_SUPPORT, USB_BESL_BASELINE_VALID, USB_BESL_DEEP_VALID 342 343 usb_ss_cap_descriptor { 344 bLength len[parent, int8] 345 bDescriptorType const[USB_DT_DEVICE_CAPABILITY, int8] 346 bDevCapabilityType const[USB_SS_CAP_TYPE, int8] 347 348 bmAttributes flags[usb_ss_cap_attributes, int8] 349 wSpeedSupported flags[usb_ss_cap_speed, int16] 350 bFunctionalitySupport int8 351 bU1devExitLat int8 352 bU2DevExitLat int16 353 } [packed] 354 355 usb_ss_cap_attributes = USB_LTM_SUPPORT 356 357 usb_ss_cap_speed = USB_LOW_SPEED_OPERATION, USB_FULL_SPEED_OPERATION, USB_HIGH_SPEED_OPERATION, USB_5GBPS_OPERATION 358 359 usb_ss_container_id_descriptor { 360 bLength len[parent, int8] 361 bDescriptorType const[USB_DT_DEVICE_CAPABILITY, int8] 362 bDevCapabilityType const[CONTAINER_ID_TYPE, int8] 363 364 bReserved int8 365 ContainerID array[int8, 16] 366 } [packed] 367 368 usb_ssp_cap_descriptor { 369 bLength len[parent, int8] 370 bDescriptorType const[USB_DT_DEVICE_CAPABILITY, int8] 371 bDevCapabilityType const[USB_SSP_CAP_TYPE, int8] 372 373 bReserved int8 374 bmAttributesSublinkSpeeds len[bmSublinkSpeedAttr, int32:5] 375 bmAttributesSpeedIDs int32:27 376 wFunctionalitySupport flags[usb_ssp_cap_funcs, int16] 377 wReserved int16 378 bmSublinkSpeedAttr array[flags[usb_ssp_cap_sublink_speeds, int32], 0:6] 379 } [packed] 380 381 usb_ssp_cap_funcs = USB_SSP_MIN_SUBLINK_SPEED_ATTRIBUTE_ID, USB_SSP_MIN_RX_LANE_COUNT, USB_SSP_MIN_TX_LANE_COUNT 382 383 usb_ssp_cap_sublink_speeds = USB_SSP_SUBLINK_SPEED_SSID, USB_SSP_SUBLINK_SPEED_LSE, USB_SSP_SUBLINK_SPEED_ST, USB_SSP_SUBLINK_SPEED_RSVD, USB_SSP_SUBLINK_SPEED_LP, USB_SSP_SUBLINK_SPEED_LSM 384 385 usb_ptm_cap_descriptor { 386 bLength len[parent, int8] 387 bDescriptorType const[USB_DT_DEVICE_CAPABILITY, int8] 388 bDevCapabilityType const[USB_PTM_CAP_TYPE, int8] 389 } [packed] 390 391 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 392 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 393 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 394 395 # Extra USB descriptors that come after an interface or an endpoint descriptor. 396 397 # TODO: consider removing class specific descriptors here for described classes. 398 usb_interface_extra_descriptor [ 399 generic usb_generic_descriptor 400 hid_hid usb_hid_descriptor_hid 401 cdc_ecm usb_cdc_header_ecm 402 cdc_ncm usb_cdc_header_ncm 403 uac_control uac_control_iface_extra_descriptors 404 uac_as uac_as_iface_extra_descriptors 405 ] [varlen] 406 407 usb_endpoint_extra_descriptor [ 408 generic usb_generic_descriptor 409 uac_iso uac_iso_endpoint_descriptor 410 ] [varlen] 411 412 usb_generic_descriptor { 413 bLength len[parent, int8] 414 bDescriptorType flags[usb_descriptor_types, int8] 415 416 data array[int8, 0:256] 417 } [packed] 418 419 usb_descriptor_types = USB_DT_DEVICE, USB_DT_CONFIG, USB_DT_STRING, USB_DT_INTERFACE, USB_DT_ENDPOINT, USB_DT_DEVICE_QUALIFIER, USB_DT_OTHER_SPEED_CONFIG, USB_DT_INTERFACE_POWER, USB_DT_OTG, USB_DT_DEBUG, USB_DT_INTERFACE_ASSOCIATION, USB_DT_SECURITY, USB_DT_KEY, USB_DT_ENCRYPTION_TYPE, USB_DT_BOS, USB_DT_DEVICE_CAPABILITY, USB_DT_WIRELESS_ENDPOINT_COMP, USB_DT_WIRE_ADAPTER, USB_DT_RPIPE, USB_DT_CS_RADIO_CONTROL, USB_DT_PIPE_USAGE, USB_DT_SS_ENDPOINT_COMP, USB_DT_SSP_ISOC_ENDPOINT_COMP, HID_DT_HID, HID_DT_REPORT, HID_DT_PHYSICAL 420 421 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 422 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 423 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 424 425 # USB descriptors requested after the SET_CONFIGURATION request. 426 427 usb_hub_descriptor_hs { 428 bDescLength len[parent, int8] 429 bDescriptorType const[USB_DT_HUB, int8] 430 431 bNbrPorts int8 432 wHubCharacteristics flags[usb_hub_characteristics, int16] 433 bPwrOn2PwrGood int8 434 bHubContrCurrent int8 435 436 DeviceRemovable array[int8, USB_HUB_PORTS_BITS] 437 PortPwrCtrlMask array[int8, USB_HUB_PORTS_BITS] 438 } [packed] 439 440 usb_hub_descriptor_ss { 441 bDescLength len[parent, int8] 442 bDescriptorType const[USB_DT_SS_HUB, int8] 443 444 bNbrPorts int8 445 wHubCharacteristics flags[usb_hub_characteristics, int16] 446 bPwrOn2PwrGood int8 447 bHubContrCurrent int8 448 449 bHubHdrDecLat int8 450 wHubDelay int16 451 DeviceRemovable int16 452 } [packed] 453 454 define USB_HUB_PORTS_BITS ((USB_MAXCHILDREN + 1 + 7) / 8) 455 456 usb_hub_characteristics = HUB_CHAR_LPSM, HUB_CHAR_COMMON_LPSM, HUB_CHAR_INDV_PORT_LPSM, HUB_CHAR_NO_LPSM, HUB_CHAR_COMPOUND, HUB_CHAR_OCPM, HUB_CHAR_COMMON_OCPM, HUB_CHAR_INDV_PORT_OCPM, HUB_CHAR_NO_OCPM, HUB_CHAR_TTTT, HUB_CHAR_PORTIND 457 458 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 459 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 460 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 461 462 # Replies to USB control requests requested after the SET_CONFIGURATION request. 463 464 usb_port_status { 465 wPortStatus flags[usb_port_status_flags, int16] 466 wPortChange flags[usb_port_change_flags, int16] 467 dwExtPortStatus array[flags[usb_ext_port_status_flags, int32], 0:1] 468 } [packed] 469 470 usb_port_status_flags = USB_PORT_STAT_CONNECTION, USB_PORT_STAT_ENABLE, USB_PORT_STAT_SUSPEND, USB_PORT_STAT_OVERCURRENT, USB_PORT_STAT_RESET, USB_PORT_STAT_L1, USB_PORT_STAT_POWER, USB_PORT_STAT_LOW_SPEED, USB_PORT_STAT_HIGH_SPEED, USB_PORT_STAT_TEST, USB_PORT_STAT_INDICATOR, USB_PORT_STAT_LINK_STATE, USB_SS_PORT_STAT_POWER, USB_SS_PORT_STAT_SPEED, USB_PORT_STAT_SPEED_5GBPS, USB_SS_PORT_LS_U0, USB_SS_PORT_LS_U1, USB_SS_PORT_LS_U2, USB_SS_PORT_LS_U3, USB_SS_PORT_LS_SS_DISABLED, USB_SS_PORT_LS_RX_DETECT, USB_SS_PORT_LS_SS_INACTIVE, USB_SS_PORT_LS_POLLING, USB_SS_PORT_LS_RECOVERY, USB_SS_PORT_LS_HOT_RESET, USB_SS_PORT_LS_COMP_MOD, USB_SS_PORT_LS_LOOPBACK 471 472 usb_port_change_flags = USB_PORT_STAT_C_CONNECTION, USB_PORT_STAT_C_ENABLE, USB_PORT_STAT_C_SUSPEND, USB_PORT_STAT_C_OVERCURRENT, USB_PORT_STAT_C_RESET, USB_PORT_STAT_C_L1, USB_PORT_STAT_C_BH_RESET, USB_PORT_STAT_C_LINK_STATE, USB_PORT_STAT_C_CONFIG_ERROR 473 474 usb_ext_port_status_flags = USB_EXT_PORT_STAT_RX_SPEED_ID, USB_EXT_PORT_STAT_TX_SPEED_ID, USB_EXT_PORT_STAT_RX_LANES, USB_EXT_PORT_STAT_TX_LANES 475 476 usb_hub_status { 477 wHubStatus flags[usb_hub_status_flags, int16] 478 wHubChange flags[usb_hub_change_flags, int16] 479 } [packed] 480 481 usb_hub_status_flags = HUB_STATUS_LOCAL_POWER, HUB_STATUS_OVERCURRENT 482 483 usb_hub_change_flags = HUB_CHANGE_LOCAL_POWER, HUB_CHANGE_OVERCURRENT 484 485 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 486 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 487 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 488 489 # HID device class specific descriptions. 490 # https://www.usb.org/sites/default/files/documents/hid1_11.pdf 491 # https://elixir.bootlin.com/linux/latest/source/drivers/hid/usbhid/hid-core.c 492 # https://elixir.bootlin.com/linux/latest/source/drivers/hid/hid-core.c 493 # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/legacy/hid.c 494 # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/f_hid.c 495 496 # Connected HID devices are known to create the following /dev/ files: 497 # /dev/hidraw#, /dev/usb/hiddev# and /dev/input/event#. 498 499 resource fd_usb_hid[fd_usb] 500 501 syz_usb_connect$hid(speed flags[usb_device_speed], dev_len len[dev], dev ptr[in, usb_device_descriptor_hid], conn_descs ptr[in, vusb_connect_descriptors]) fd_usb_hid (timeout[3000], prog_timeout[3000]) 502 syz_usb_control_io$hid(fd fd_usb_hid, descs ptr[in, vusb_descriptors_hid], resps ptr[in, vusb_responses_hid]) (timeout[300]) 503 504 # idVendor and idProduct are patched by Go code, see sys/linux/init_vusb.go. 505 usb_device_descriptor_hid { 506 inner usb_device_descriptor_t[0, 0, 0, 0, 0, 64, array[usb_config_descriptor_hid, 1]] 507 } [packed] 508 509 usb_config_descriptor_hid { 510 inner usb_config_descriptor_ifaces_array_t[const[1, int8], array[usb_interface_descriptor_hid, 1]] 511 } [packed] 512 513 usb_interface_descriptor_hid { 514 inner usb_interface_descriptor_t[const[0, int8], int8, int8[1:2], const[USB_CLASS_HID, int8], const[USB_INTERFACE_SUBCLASS_BOOT, int8], flags[usb_hid_protocols, int8], usb_hid_descriptor_hid, usb_endpoint_descriptors_hid] 515 } [packed] 516 517 usb_hid_protocols = USB_INTERFACE_PROTOCOL_KEYBOARD, USB_INTERFACE_PROTOCOL_MOUSE 518 519 usb_endpoint_descriptors_hid { 520 in usb_endpoint_descriptor_hid_in 521 out array[usb_endpoint_descriptor_hid_out, 0:1] 522 } [packed] 523 524 usb_endpoint_descriptor_hid_in { 525 inner usb_endpoint_descriptor_t[const[USB_ENDPOINT_HID_IN_ADDRESS, int8], const[USB_ENDPOINT_HID_ATTRIBUTES, int8], void] 526 } [packed] 527 528 usb_endpoint_descriptor_hid_out { 529 inner usb_endpoint_descriptor_t[const[USB_ENDPOINT_HID_OUT_ADDRESS, int8], const[USB_ENDPOINT_HID_ATTRIBUTES, int8], void] 530 } [packed] 531 532 define USB_ENDPOINT_HID_ATTRIBUTES (USB_ENDPOINT_XFER_INT) 533 define USB_ENDPOINT_HID_IN_ADDRESS (1 | USB_DIR_IN) 534 define USB_ENDPOINT_HID_OUT_ADDRESS (2) 535 536 vusb_descriptors_hid { 537 len len[parent, int32] 538 generic ptr[in, vusb_descriptor_generic] 539 540 USB_DT_STRING ptr[in, vusb_descriptor_t[USB_TYPE_STANDARD, USB_DT_STRING, usb_string_descriptor]] 541 542 # For unknown reasons these are requested as USB_TYPE_STANDARD and not as USB_TYPE_CLASS. 543 # Linux doesn't request HID_DT_HID, but some hosts might do that. 544 HID_DT_REPORT ptr[in, vusb_descriptor_t[USB_TYPE_STANDARD, HID_DT_REPORT, hid_descriptor_report]] 545 HID_DT_HID ptr[in, vusb_descriptor_t[USB_TYPE_STANDARD, HID_DT_HID, usb_hid_descriptor_hid]] 546 } [packed] 547 548 vusb_responses_hid { 549 len len[parent, int32] 550 generic ptr[in, vusb_response_generic] 551 552 USB_REQ_GET_INTERFACE ptr[in, vusb_response_t[USB_TYPE_STANDARD, USB_REQ_GET_INTERFACE, int8]] 553 USB_REQ_GET_CONFIGURATION ptr[in, vusb_response_t[USB_TYPE_STANDARD, USB_REQ_GET_CONFIGURATION, int8]] 554 555 HID_REQ_GET_REPORT ptr[in, vusb_response_t[USB_TYPE_CLASS, HID_REQ_GET_REPORT, array[int8, 0:256]]] 556 HID_REQ_GET_PROTOCOL ptr[in, vusb_response_t[USB_TYPE_CLASS, HID_REQ_GET_PROTOCOL, int8]] 557 } [packed] 558 559 # USB HID specifications allows for multiple report and physical descriptors 560 # to be present, but I don't see any support for them in the Linux kernel, 561 # except for a single report descriptor. 562 usb_hid_descriptor_hid { 563 bLength len[parent, int8] 564 bDescriptorType const[HID_DT_HID, int8] 565 566 bcdHID int16 567 bCountryCode int8 568 bNumDescriptors const[1, int8] 569 570 report_desc usb_hid_class_descriptor_report 571 } [packed] 572 573 usb_hid_class_descriptor_report { 574 bDescriptorType const[HID_DT_REPORT, int8] 575 wDescriptorLength int16[0:HID_MAX_DESCRIPTOR_SIZE] 576 } [packed] 577 578 # TODO: it's hard to describe the REPORT descriptor structure via syzkaller 579 # descriptions, so consider generating it in Go code. 580 # TODO: the length of REPORT descriptor must match the value in HID descriptor. 581 # TODO: there are vendor specific REPORT descriptor formats (Logitech HID++). 582 583 # Linux HID stack doesn't support long items. 584 hid_descriptor_report { 585 items array[hid_report_item_short] 586 } [packed] 587 588 type hid_report_item_short_012_t[TYPE, TAGS] { 589 bSize len[data, int8:2] 590 bType const[TYPE, int8:2] 591 bTag flags[TAGS, int8:4] 592 data array[int8, 0:2] 593 } [packed] 594 595 type hid_report_item_short_4_t[TYPE, TAGS] { 596 bSize const[3, int8:2] 597 bType const[TYPE, int8:2] 598 bTag flags[TAGS, int8:4] 599 data array[int8, 4] 600 } [packed] 601 602 type hid_report_item_short_t[TYPE, TAGS] [ 603 item_012 hid_report_item_short_012_t[TYPE, TAGS] 604 item_4 hid_report_item_short_4_t[TYPE, TAGS] 605 ] [varlen] 606 607 hid_report_item_short [ 608 main hid_report_item_short_t[HID_ITEM_TYPE_MAIN, hid_report_item_main_tags] 609 global hid_report_item_short_t[HID_ITEM_TYPE_GLOBAL, hid_report_item_global_tags] 610 local hid_report_item_short_t[HID_ITEM_TYPE_LOCAL, hid_report_item_local_tags] 611 ] [varlen] 612 613 hid_report_item_main_tags = HID_MAIN_ITEM_TAG_INPUT, HID_MAIN_ITEM_TAG_OUTPUT, HID_MAIN_ITEM_TAG_FEATURE, HID_MAIN_ITEM_TAG_BEGIN_COLLECTION, HID_MAIN_ITEM_TAG_END_COLLECTION 614 hid_report_item_global_tags = HID_GLOBAL_ITEM_TAG_USAGE_PAGE, HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM, HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM, HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM, HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM, HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT, HID_GLOBAL_ITEM_TAG_UNIT, HID_GLOBAL_ITEM_TAG_REPORT_SIZE, HID_GLOBAL_ITEM_TAG_REPORT_ID, HID_GLOBAL_ITEM_TAG_REPORT_COUNT, HID_GLOBAL_ITEM_TAG_PUSH, HID_GLOBAL_ITEM_TAG_POP 615 hid_report_item_local_tags = HID_LOCAL_ITEM_TAG_USAGE, HID_LOCAL_ITEM_TAG_USAGE_MINIMUM, HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM, HID_LOCAL_ITEM_TAG_DESIGNATOR_INDEX, HID_LOCAL_ITEM_TAG_DESIGNATOR_MINIMUM, HID_LOCAL_ITEM_TAG_DESIGNATOR_MAXIMUM, HID_LOCAL_ITEM_TAG_STRING_INDEX, HID_LOCAL_ITEM_TAG_STRING_MINIMUM, HID_LOCAL_ITEM_TAG_STRING_MAXIMUM, HID_LOCAL_ITEM_TAG_DELIMITER 616 617 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 618 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 619 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 620 621 # PRINTER device class specific descriptions. 622 # https://www.usb.org/sites/default/files/usbprint11a021811.pdf 623 # https://elixir.bootlin.com/linux/latest/source/drivers/usb/class/usblp.c 624 # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/legacy/printer.c 625 # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/f_printer.c 626 627 # Connected PRINTER devices are known to create the following /dev/ files: 628 # /dev/usb/lp#. 629 # TODO: write descriptions for those. 630 631 # drivers/usb/class/usblp.c 632 define USBLP_REQ_GET_ID 0x00 633 define USBLP_REQ_GET_STATUS 0x01 634 define USBLP_REQ_RESET 0x02 635 define USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST 0x00 636 define USBLP_FIRST_PROTOCOL 1 637 define USBLP_LAST_PROTOCOL 3 638 639 resource fd_usb_printer[fd_usb] 640 641 syz_usb_connect$printer(speed flags[usb_device_speed], dev_len len[dev], dev ptr[in, usb_device_descriptor_printer], conn_descs ptr[in, vusb_connect_descriptors]) fd_usb_printer (timeout[3000], prog_timeout[3000]) 642 syz_usb_control_io$printer(fd fd_usb_printer, descs ptr[in, vusb_descriptors_printer], resps ptr[in, vusb_responses_printer]) (timeout[300]) 643 644 usb_device_descriptor_printer { 645 inner usb_device_descriptor_t[0, 0, 0, 0x525, 0xa4a8, 64, array[usb_config_descriptor_printer, 1]] 646 } [packed] 647 648 usb_config_descriptor_printer { 649 inner usb_config_descriptor_ifaces_array_t[const[1, int8], array[usb_interface_descriptor_printer, 1]] 650 } [packed] 651 652 usb_interface_descriptor_printer { 653 inner usb_interface_descriptor_t[const[0, int8], int8, int8[1:2], const[USB_CLASS_PRINTER, int8], const[1, int8], int8[USBLP_FIRST_PROTOCOL:USBLP_LAST_PROTOCOL], void, usb_endpoint_descriptors_printer] 654 } [packed] 655 656 usb_endpoint_descriptors_printer { 657 in usb_endpoint_descriptor_printer_out 658 out array[usb_endpoint_descriptor_printer_in, 0:1] 659 } [packed] 660 661 usb_endpoint_descriptor_printer_out { 662 inner usb_endpoint_descriptor_t[const[USB_ENDPOINT_PRINTER_OUT_ADDRESS, int8], const[USB_ENDPOINT_PRINTER_ATTRIBUTES, int8], void] 663 } [packed] 664 665 usb_endpoint_descriptor_printer_in { 666 inner usb_endpoint_descriptor_t[const[USB_ENDPOINT_PRINTER_IN_ADDRESS, int8], const[USB_ENDPOINT_PRINTER_ATTRIBUTES, int8], void] 667 } [packed] 668 669 define USB_ENDPOINT_PRINTER_ATTRIBUTES (USB_ENDPOINT_XFER_BULK) 670 define USB_ENDPOINT_PRINTER_OUT_ADDRESS (1) 671 define USB_ENDPOINT_PRINTER_IN_ADDRESS (2 | USB_DIR_IN) 672 673 vusb_descriptors_printer { 674 len len[parent, int32] 675 generic ptr[in, vusb_descriptor_generic] 676 677 USB_DT_STRING ptr[in, vusb_descriptor_t[USB_TYPE_STANDARD, USB_DT_STRING, usb_string_descriptor]] 678 } [packed] 679 680 vusb_responses_printer { 681 len len[parent, int32] 682 generic ptr[in, vusb_response_generic] 683 684 USB_REQ_GET_INTERFACE ptr[in, vusb_response_t[USB_TYPE_STANDARD, USB_REQ_GET_INTERFACE, int8]] 685 USB_REQ_GET_CONFIGURATION ptr[in, vusb_response_t[USB_TYPE_STANDARD, USB_REQ_GET_CONFIGURATION, int8]] 686 687 USBLP_REQ_GET_ID ptr[in, vusb_response_t[USB_TYPE_CLASS, USBLP_REQ_GET_ID, usb_printer_get_id_response]] 688 USBLP_REQ_GET_STATUS ptr[in, vusb_response_t[USB_TYPE_CLASS, USBLP_REQ_GET_STATUS, int8]] 689 USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST ptr[in, vusb_response_t[USB_TYPE_CLASS, USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST, int8]] 690 } [packed] 691 692 usb_printer_get_id_response { 693 length len[id, int16be] 694 id array[int8, 0:256] 695 } [packed] 696 697 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 698 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 699 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 700 701 # CDC ECM (Ethernet) device class specific descriptions. 702 # https://www.usb.org/document-library/class-definitions-communication-devices-12 703 # https://elixir.bootlin.com/linux/latest/source/drivers/net/usb/cdc_ether.c 704 # https://elixir.bootlin.com/linux/latest/source/drivers/net/usb/usbnet.c 705 # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/legacy/ether.c 706 # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/f_ecm.c 707 # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/u_ether.c 708 709 # Connected CDC ECM devices are known to create usbN network interfaces. 710 # TODO: write descriptions for those. 711 712 resource fd_usb_cdc_ecm[fd_usb] 713 714 syz_usb_connect$cdc_ecm(speed flags[usb_device_speed], dev_len len[dev], dev ptr[in, usb_device_descriptor_cdc_ecm], conn_descs ptr[in, vusb_connect_descriptors]) fd_usb_cdc_ecm (timeout[3000], prog_timeout[3000]) 715 syz_usb_control_io$cdc_ecm(fd fd_usb_cdc_ecm, descs ptr[in, vusb_descriptors_cdc_ecm], resps ptr[in, vusb_responses_cdc_ecm]) (timeout[300]) 716 717 usb_device_descriptor_cdc_ecm { 718 inner usb_device_descriptor_t[USB_CLASS_COMM, 0, 0, 0x525, 0xa4a1, 64, array[usb_config_descriptor_cdc_ecm, 1]] 719 } [packed] 720 721 usb_config_descriptor_cdc_ecm { 722 inner usb_config_descriptor_ifaces_array_t[const[1, int8], array[usb_interface_descriptor_cdc_ecm, 1]] 723 } [packed] 724 725 # Per specification CDC ECM devices have two interfaces (control and data), 726 # but here we're merging them into one for simplicity since Linux supports that. 727 usb_interface_descriptor_cdc_ecm { 728 inner usb_interface_descriptor_t[const[0, int8], int8, int8[2:3], const[USB_CLASS_COMM, int8], const[USB_CDC_SUBCLASS_ETHERNET, int8], const[USB_CDC_PROTO_NONE, int8], usb_cdc_header_ecm, usb_endpoint_descriptors_cdc_ecm] 729 } [packed] 730 731 usb_endpoint_descriptors_cdc_ecm { 732 notify array[usb_endpoint_descriptor_cdc_ecm_notify, 0:1] 733 in usb_endpoint_descriptor_cdc_ecm_in 734 out usb_endpoint_descriptor_cdc_ecm_out 735 } [packed] 736 737 usb_endpoint_descriptor_cdc_ecm_notify { 738 inner usb_endpoint_descriptor_t[const[USB_ENDPOINT_CDC_ECM_NOTIFY_ADDRESS, int8], const[USB_ENDPOINT_CDC_ECM_NOTIFY_ATTRIBUTES, int8], void] 739 } [packed] 740 741 usb_endpoint_descriptor_cdc_ecm_in { 742 inner usb_endpoint_descriptor_t[const[USB_ENDPOINT_CDC_ECM_IN_ADDRESS, int8], const[USB_ENDPOINT_CDC_ECM_DATA_ATTRIBUTES, int8], void] 743 } [packed] 744 745 usb_endpoint_descriptor_cdc_ecm_out { 746 inner usb_endpoint_descriptor_t[const[USB_ENDPOINT_CDC_ECM_OUT_ADDRESS, int8], const[USB_ENDPOINT_CDC_ECM_DATA_ATTRIBUTES, int8], void] 747 } [packed] 748 749 define USB_ENDPOINT_CDC_ECM_NOTIFY_ATTRIBUTES (USB_ENDPOINT_XFER_INT) 750 define USB_ENDPOINT_CDC_ECM_DATA_ATTRIBUTES (USB_ENDPOINT_XFER_BULK) 751 define USB_ENDPOINT_CDC_ECM_NOTIFY_ADDRESS (1 | USB_DIR_IN) 752 define USB_ENDPOINT_CDC_ECM_IN_ADDRESS (2 | USB_DIR_IN) 753 define USB_ENDPOINT_CDC_ECM_OUT_ADDRESS (3) 754 755 # https://elixir.bootlin.com/linux/v5.2.7/source/drivers/usb/core/message.c#L2137 756 # https://elixir.bootlin.com/linux/v5.2.7/source/drivers/net/usb/cdc_ether.c#L155 757 usb_cdc_header_ecm { 758 union usb_cdc_union_desc_t[0, 0] 759 header usb_cdc_header_desc 760 ether usb_cdc_ether_desc 761 762 other array[usb_cdc_header_ecm_other, 0:6] 763 } [packed] 764 765 usb_cdc_header_ecm_other [ 766 call_mgmt usb_cdc_call_mgmt_descriptor 767 acm usb_cdc_acm_descriptor 768 country_functional usb_cdc_country_functional_desc 769 network_terminal usb_cdc_network_terminal_desc 770 dmm usb_cdc_dmm_desc 771 mdlm usb_cdc_mdlm_desc 772 mdlm_detail usb_cdc_mdlm_detail_desc 773 obex usb_cdc_obex_desc 774 ncm usb_cdc_ncm_desc 775 mbim usb_cdc_mbim_desc 776 mbim_extended usb_cdc_mbim_extended_desc 777 ] [varlen] 778 779 usb_cdc_header_desc { 780 bLength len[parent, int8] 781 bDescriptorType const[USB_DT_CS_INTERFACE, int8] 782 bDescriptorSubType const[USB_CDC_HEADER_TYPE, int8] 783 784 bcdCDC int16 785 } [packed] 786 787 usb_cdc_call_mgmt_descriptor { 788 bLength len[parent, int8] 789 bDescriptorType const[USB_DT_CS_INTERFACE, int8] 790 bDescriptorSubType const[USB_CDC_CALL_MANAGEMENT_TYPE, int8] 791 792 bmCapabilities flags[usb_cdc_call_mgmt_caps, int8] 793 bDataInterface int8 794 } [packed] 795 796 usb_cdc_call_mgmt_caps = USB_CDC_CALL_MGMT_CAP_CALL_MGMT, USB_CDC_CALL_MGMT_CAP_DATA_INTF 797 798 usb_cdc_acm_descriptor { 799 bLength len[parent, int8] 800 bDescriptorType const[USB_DT_CS_INTERFACE, int8] 801 bDescriptorSubType const[USB_CDC_ACM_TYPE, int8] 802 803 bmCapabilities flags[usb_cdc_acm_caps, int8] 804 } [packed] 805 806 usb_cdc_acm_caps = USB_CDC_COMM_FEATURE, USB_CDC_CAP_LINE, USB_CDC_CAP_BRK, USB_CDC_CAP_NOTIFY 807 808 type usb_cdc_union_desc_t[MASTER, SLAVE] { 809 bLength len[parent, int8] 810 bDescriptorType const[USB_DT_CS_INTERFACE, int8] 811 bDescriptorSubType const[USB_CDC_UNION_TYPE, int8] 812 813 bMasterInterface0 const[MASTER, int8] 814 bSlaveInterface0 const[SLAVE, int8] 815 slave_interfaces array[int8, 0:6] 816 } [packed] 817 818 usb_cdc_country_functional_desc { 819 bLength len[parent, int8] 820 bDescriptorType const[USB_DT_CS_INTERFACE, int8] 821 bDescriptorSubType const[USB_CDC_COUNTRY_TYPE, int8] 822 823 iCountryCodeRelDate int8 824 wCountyCode0 int16 825 country_codes array[int16, 0:6] 826 } [packed] 827 828 usb_cdc_network_terminal_desc { 829 bLength len[parent, int8] 830 bDescriptorType const[USB_DT_CS_INTERFACE, int8] 831 bDescriptorSubType const[USB_CDC_NETWORK_TERMINAL_TYPE, int8] 832 833 bEntityId int8 834 iName int8 835 bChannelIndex int8 836 bPhysicalInterface int8 837 } [packed] 838 839 usb_cdc_ether_desc { 840 bLength len[parent, int8] 841 bDescriptorType const[USB_DT_CS_INTERFACE, int8] 842 bDescriptorSubType const[USB_CDC_ETHERNET_TYPE, int8] 843 844 iMACAddress const[1, int8] 845 bmEthernetStatistics int32 846 wMaxSegmentSize int16 847 wNumberMCFilters int16 848 bNumberPowerFilters int8 849 } [packed] 850 851 usb_cdc_dmm_desc { 852 bLength len[parent, int8] 853 bDescriptorType const[USB_DT_CS_INTERFACE, int8] 854 bDescriptorSubType const[USB_CDC_DMM_TYPE, int8] 855 856 bcdVersion int16 857 wMaxCommand int16 858 } [packed] 859 860 usb_cdc_mdlm_desc { 861 bLength len[parent, int8] 862 bDescriptorType const[USB_DT_CS_INTERFACE, int8] 863 bDescriptorSubType const[USB_CDC_MDLM_TYPE, int8] 864 865 bcdVersion int16 866 bGUID usb_cdc_ecm_mbm_guid 867 } [packed] 868 869 # https://elixir.bootlin.com/linux/v5.2.7/source/drivers/net/usb/cdc_ether.c#L61 870 usb_cdc_ecm_mbm_guid { 871 id0 const[0x14f5e048ba817a3, int64] 872 id1 const[0x2a397ecbffc007a6, int64] 873 } [packed] 874 875 usb_cdc_mdlm_detail_desc { 876 bLength len[parent, int8] 877 bDescriptorType const[USB_DT_CS_INTERFACE, int8] 878 bDescriptorSubType const[USB_CDC_MDLM_DETAIL_TYPE, int8] 879 880 bGuidDescriptorType int8 881 bDetailData array[int8, 0:256] 882 } [packed] 883 884 usb_cdc_obex_desc { 885 bLength len[parent, int8] 886 bDescriptorType const[USB_DT_CS_INTERFACE, int8] 887 bDescriptorSubType const[USB_CDC_OBEX_TYPE, int8] 888 889 bcdVersion int16 890 } [packed] 891 892 usb_cdc_ncm_desc { 893 bLength len[parent, int8] 894 bDescriptorType const[USB_DT_CS_INTERFACE, int8] 895 bDescriptorSubType const[USB_CDC_NCM_TYPE, int8] 896 897 bcdNcmVersion int16 898 bmNetworkCapabilities flags[usb_cdc_ncm_ncaps, int8] 899 } [packed] 900 901 usb_cdc_ncm_ncaps = USB_CDC_NCM_NCAP_ETH_FILTER, USB_CDC_NCM_NCAP_NET_ADDRESS, USB_CDC_NCM_NCAP_ENCAP_COMMAND, USB_CDC_NCM_NCAP_MAX_DATAGRAM_SIZE, USB_CDC_NCM_NCAP_CRC_MODE, USB_CDC_NCM_NCAP_NTB_INPUT_SIZE 902 903 usb_cdc_mbim_desc { 904 bLength len[parent, int8] 905 bDescriptorType const[USB_DT_CS_INTERFACE, int8] 906 bDescriptorSubType const[USB_CDC_MBIM_TYPE, int8] 907 908 bcdMBIMVersion int16 909 wMaxControlMessage int16 910 bNumberFilters int8 911 bMaxFilterSize int8 912 wMaxSegmentSize int16 913 bmNetworkCapabilities int8 914 } [packed] 915 916 usb_cdc_mbim_extended_desc { 917 bLength len[parent, int8] 918 bDescriptorType const[USB_DT_CS_INTERFACE, int8] 919 bDescriptorSubType const[USB_CDC_MBIM_EXTENDED_TYPE, int8] 920 921 bcdMBIMExtendedVersion int16 922 bMaxOutstandingCommandMessages int8 923 wMTU int16 924 } [packed] 925 926 vusb_descriptors_cdc_ecm { 927 len len[parent, int32] 928 generic ptr[in, vusb_descriptor_generic] 929 930 # https://elixir.bootlin.com/linux/v5.2.7/source/drivers/net/usb/usbnet.c#L147 931 USB_DT_STRING ptr[in, vusb_descriptor_t[USB_TYPE_STANDARD, USB_DT_STRING, usb_string_descriptor_t[usb_cdc_ecm_mac]]] 932 } [packed] 933 934 usb_cdc_ecm_mac { 935 # This is a UTF16 encoded string "424242424242". 936 data0 const[0x3400320034003200, int64be] 937 data1 const[0x3400320034003200, int64be] 938 data2 const[0x3400320034003200, int64be] 939 } [packed] 940 941 vusb_responses_cdc_ecm { 942 len len[parent, int32] 943 generic ptr[in, vusb_response_generic] 944 945 USB_REQ_GET_INTERFACE ptr[in, vusb_response_t[USB_TYPE_STANDARD, USB_REQ_GET_INTERFACE, int8]] 946 USB_REQ_GET_CONFIGURATION ptr[in, vusb_response_t[USB_TYPE_STANDARD, USB_REQ_GET_CONFIGURATION, int8]] 947 } [packed] 948 949 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 950 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 951 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 952 953 # CDC NCM class specific descriptions. 954 # CDC NCM is based on CDC ECM, so some of the descriptions are reused. 955 # https://www.usb.org/document-library/network-control-model-devices-specification-v10-and-errata-and-adopters-agreement 956 # https://elixir.bootlin.com/linux/latest/source/drivers/net/usb/cdc_ncm.c 957 # https://elixir.bootlin.com/linux/latest/source/drivers/net/usb/usbnet.c 958 # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/legacy/ncm.c 959 # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/f_ncm.c 960 961 resource fd_usb_cdc_ncm[fd_usb] 962 963 syz_usb_connect$cdc_ncm(speed flags[usb_device_speed], dev_len len[dev], dev ptr[in, usb_device_descriptor_cdc_ncm], conn_descs ptr[in, vusb_connect_descriptors]) fd_usb_cdc_ncm (timeout[3000], prog_timeout[3000]) 964 syz_usb_control_io$cdc_ncm(fd fd_usb_cdc_ncm, descs ptr[in, vusb_descriptors_cdc_ncm], resps ptr[in, vusb_responses_cdc_ncm]) (timeout[300]) 965 966 usb_device_descriptor_cdc_ncm { 967 inner usb_device_descriptor_t[USB_CLASS_COMM, 0, 0, 0x525, 0xa4a1, 64, array[usb_config_descriptor_cdc_ncm, 1]] 968 } [packed] 969 970 usb_config_descriptor_cdc_ncm { 971 inner usb_config_descriptor_t[const[1, int8], const[2, int8], usb_interface_descriptors_cdc_ncm] 972 } [packed] 973 974 usb_interface_descriptors_cdc_ncm { 975 control usb_interface_descriptor_fixed_t[0, CDC_NCM_COMM_ALTSETTING_NCM, 1, USB_CLASS_COMM, USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE, usb_cdc_header_ncm, usb_endpoint_descriptor_cdc_ecm_notify] 976 data_nop usb_interface_descriptor_fixed_t[1, 0, 0, USB_CLASS_COMM, USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE, void, void] 977 data usb_interface_descriptor_fixed_t[1, CDC_NCM_DATA_ALTSETTING_NCM, 2, USB_CLASS_COMM, USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE, void, usb_endpoint_descriptors_cdc_ncm_data] 978 } [packed] 979 980 usb_endpoint_descriptors_cdc_ncm_data { 981 in usb_endpoint_descriptor_cdc_ecm_in 982 out usb_endpoint_descriptor_cdc_ecm_out 983 } [packed] 984 985 # https://elixir.bootlin.com/linux/v5.2.7/source/drivers/usb/core/message.c#L2137 986 # https://elixir.bootlin.com/linux/v5.2.7/source/drivers/net/usb/cdc_ncm.c#L798 987 usb_cdc_header_ncm { 988 union usb_cdc_union_desc_t[0, 1] 989 header usb_cdc_header_desc 990 ether usb_cdc_ether_desc 991 ncm usb_cdc_ncm_desc 992 993 other array[usb_cdc_header_ncm_other, 0:6] 994 } [packed] 995 996 usb_cdc_header_ncm_other [ 997 call_mgmt usb_cdc_call_mgmt_descriptor 998 acm usb_cdc_acm_descriptor 999 country_functional usb_cdc_country_functional_desc 1000 network_terminal usb_cdc_network_terminal_desc 1001 dmm usb_cdc_dmm_desc 1002 mdlm usb_cdc_mdlm_desc 1003 mdlm_detail usb_cdc_mdlm_detail_desc 1004 obex usb_cdc_obex_desc 1005 mbim usb_cdc_mbim_desc 1006 mbim_extended usb_cdc_mbim_extended_desc 1007 ] [varlen] 1008 1009 vusb_descriptors_cdc_ncm { 1010 len len[parent, int32] 1011 generic ptr[in, vusb_descriptor_generic] 1012 1013 # https://elixir.bootlin.com/linux/v5.2.7/source/drivers/net/usb/usbnet.c#L147 1014 USB_DT_STRING ptr[in, vusb_descriptor_t[USB_TYPE_STANDARD, USB_DT_STRING, usb_string_descriptor_t[usb_cdc_ecm_mac]]] 1015 } [packed] 1016 1017 vusb_responses_cdc_ncm { 1018 len len[parent, int32] 1019 generic ptr[in, vusb_response_generic] 1020 1021 USB_REQ_GET_INTERFACE ptr[in, vusb_response_t[USB_TYPE_STANDARD, USB_REQ_GET_INTERFACE, int8]] 1022 USB_REQ_GET_CONFIGURATION ptr[in, vusb_response_t[USB_TYPE_STANDARD, USB_REQ_GET_CONFIGURATION, int8]] 1023 1024 USB_CDC_GET_NTB_PARAMETERS ptr[in, vusb_response_t[USB_TYPE_CLASS, USB_CDC_GET_NTB_PARAMETERS, usb_cdc_ncm_ntb_parameters]] 1025 USB_CDC_GET_NTB_INPUT_SIZE ptr[in, vusb_response_t[USB_TYPE_CLASS, USB_CDC_GET_NTB_INPUT_SIZE, int32]] 1026 USB_CDC_GET_NTB_FORMAT ptr[in, vusb_response_t[USB_TYPE_CLASS, USB_CDC_GET_NTB_FORMAT, int16[0:1]]] 1027 USB_CDC_GET_MAX_DATAGRAM_SIZE ptr[in, vusb_response_t[USB_TYPE_CLASS, USB_CDC_GET_MAX_DATAGRAM_SIZE, int16]] 1028 USB_CDC_GET_CRC_MODE ptr[in, vusb_response_t[USB_TYPE_CLASS, USB_CDC_GET_CRC_MODE, int16[0:1]]] 1029 } [packed] 1030 1031 usb_cdc_ncm_ntb_parameters { 1032 wLength int16 1033 bmNtbFormatsSupported int16 1034 dwNtbInMaxSize int32 1035 wNdpInDivisor int16 1036 wNdpInPayloadRemainder int16 1037 wNdpInAlignment int16 1038 wPadding1 int16 1039 dwNtbOutMaxSize int32 1040 wNdpOutDivisor int16 1041 wNdpOutPayloadRemainder int16 1042 wNdpOutAlignment int16 1043 wNtbOutMaxDatagrams int16 1044 } [packed] 1045 1046 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 1047 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 1048 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 1049 1050 # UAC1 device class specific descriptions. 1051 # https://www.usb.org/sites/default/files/audio10.pdf 1052 # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/legacy/audio.c 1053 # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/f_uac1.c 1054 # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/f_uac1_legacy.c 1055 # https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/usb/audio.h 1056 1057 # TODO: find out which /dev/ files are created by connected UAC1 devices and add descriptions for those. 1058 1059 resource fd_usb_uac1[fd_usb] 1060 1061 syz_usb_connect$uac1(speed flags[usb_device_speed], dev_len len[dev], dev ptr[in, usb_device_descriptor_uac1], conn_descs ptr[in, vusb_connect_descriptors]) fd_usb_uac1 (timeout[3000], prog_timeout[3000]) 1062 syz_usb_control_io$uac1(fd fd_usb_uac1, descs ptr[in, vusb_descriptors_uac1], resps ptr[in, vusb_responses_uac1]) (timeout[300]) 1063 1064 usb_device_descriptor_uac1 { 1065 inner usb_device_descriptor_t[0, 0, 0, 0x1d6b, 0x101, 64, array[usb_config_descriptor_uac1, 1]] 1066 } [packed] 1067 1068 usb_config_descriptor_uac1 { 1069 inner usb_config_descriptor_t[const[1, int8], const[3, int8], usb_interface_descriptors_uac1] 1070 } [packed] 1071 1072 # TODO: control interface might have and optional interrupt endpoint. 1073 usb_interface_descriptors_uac1 { 1074 control usb_interface_descriptor_fixed_t[0, 0, 0, USB_CLASS_AUDIO, USB_SUBCLASS_AUDIOCONTROL, 0, uac_control_iface_extra_descriptors, void] 1075 as_out_alt_0 usb_interface_descriptor_fixed_t[1, 0, 0, USB_CLASS_AUDIO, USB_SUBCLASS_AUDIOSTREAMING, 0, void, void] 1076 as_out_alt_1 usb_interface_descriptor_fixed_t[1, 1, 1, USB_CLASS_AUDIO, USB_SUBCLASS_AUDIOSTREAMING, 0, uac_as_iface_extra_descriptors, uac_as_out_endpoint_descriptor] 1077 as_in_alt_0 usb_interface_descriptor_fixed_t[2, 0, 0, USB_CLASS_AUDIO, USB_SUBCLASS_AUDIOSTREAMING, 0, void, void] 1078 as_in_alt_1 usb_interface_descriptor_fixed_t[2, 1, 1, USB_CLASS_AUDIO, USB_SUBCLASS_AUDIOSTREAMING, 0, uac_as_iface_extra_descriptors, uac_as_in_endpoint_descriptor] 1079 } [packed] 1080 1081 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 1082 1083 # UAC uses IDs to make it possible for terminals and units to refer to each other. 1084 # We don't have a way to describe this, so just use a limited number of ids. 1085 type uac_id int8[1:6] 1086 1087 uac_control_iface_extra_descriptors { 1088 header uac1_ac_header_descriptor_2 1089 others array[uac_control_iface_extra_descriptor, 0:6] 1090 } [packed] 1091 1092 uac_as_iface_extra_descriptors { 1093 others array[uac_as_iface_extra_descriptor, 0:6] 1094 } [packed] 1095 1096 uac_control_iface_extra_descriptor [ 1097 input_terminal uac_input_terminal_descriptor 1098 output_terminal uac1_output_terminal_descriptor 1099 mixer_unit uac_mixer_unit_descriptor 1100 selector_unit uac_selector_unit_descriptor 1101 feature_unit uac_feature_unit_descriptor 1102 processing_unit uac_processing_unit_descriptor 1103 extension_unit uac_extension_unit_descriptor 1104 ] [varlen] 1105 1106 uac_as_iface_extra_descriptor [ 1107 as_header uac1_as_header_descriptor 1108 format_type_i_continuous uac_format_type_i_continuous_descriptor 1109 format_type_i_discrete uac_format_type_i_discrete_descriptor 1110 format_type_ii_discrete uac_format_type_ii_discrete_descriptor 1111 ] [varlen] 1112 1113 define F_AUDIO_NUM_INTERFACES 2 1114 define UAC_DT_AC_HEADER_LENGTH UAC_DT_AC_HEADER_SIZE(F_AUDIO_NUM_INTERFACES) 1115 1116 uac1_ac_header_descriptor_2 { 1117 bLength const[UAC_DT_AC_HEADER_LENGTH, int8] 1118 bDescriptorType const[USB_DT_CS_INTERFACE, int8] 1119 bDescriptorSubType const[UAC_HEADER, int8] 1120 1121 bcdADC int16 1122 wTotalLength int8 1123 bInCollection const[F_AUDIO_NUM_INTERFACES, int8] 1124 1125 # These must match interfaces numbers. 1126 baInterfaceNr0 const[1, int8] 1127 baInterfaceNr1 const[2, int8] 1128 } [packed] 1129 1130 uac_input_terminal_descriptor { 1131 bLength len[parent, int8] 1132 bDescriptorType const[USB_DT_CS_INTERFACE, int8] 1133 bDescriptorSubType const[UAC_INPUT_TERMINAL, int8] 1134 1135 bTerminalID uac_id 1136 wTerminalType flags[uac_input_terminal_types, int16] 1137 bAssocTerminal uac_id 1138 bNrChannels int8 1139 wChannelConfig int16 1140 iChannelNames int8 1141 iTerminal int8 1142 } [packed] 1143 1144 uac_input_terminal_types = UAC_TERMINAL_UNDEFINED, UAC_TERMINAL_STREAMING, UAC_TERMINAL_VENDOR_SPEC, UAC_INPUT_TERMINAL_UNDEFINED, UAC_INPUT_TERMINAL_MICROPHONE, UAC_INPUT_TERMINAL_DESKTOP_MICROPHONE, UAC_INPUT_TERMINAL_PERSONAL_MICROPHONE, UAC_INPUT_TERMINAL_OMNI_DIR_MICROPHONE, UAC_INPUT_TERMINAL_MICROPHONE_ARRAY, UAC_INPUT_TERMINAL_PROC_MICROPHONE_ARRAY 1145 1146 uac1_output_terminal_descriptor { 1147 bLength len[parent, int8] 1148 bDescriptorType const[USB_DT_CS_INTERFACE, int8] 1149 bDescriptorSubType const[UAC_OUTPUT_TERMINAL, int8] 1150 1151 bTerminalID uac_id 1152 wTerminalType flags[uac_output_terminal_types, int16] 1153 bAssocTerminal uac_id 1154 bSourceID uac_id 1155 iTerminal int8 1156 } [packed] 1157 1158 uac_output_terminal_types = UAC_TERMINAL_UNDEFINED, UAC_TERMINAL_STREAMING, UAC_TERMINAL_VENDOR_SPEC, UAC_OUTPUT_TERMINAL_UNDEFINED, UAC_OUTPUT_TERMINAL_SPEAKER, UAC_OUTPUT_TERMINAL_HEADPHONES, UAC_OUTPUT_TERMINAL_HEAD_MOUNTED_DISPLAY_AUDIO, UAC_OUTPUT_TERMINAL_DESKTOP_SPEAKER, UAC_OUTPUT_TERMINAL_ROOM_SPEAKER, UAC_OUTPUT_TERMINAL_COMMUNICATION_SPEAKER, UAC_OUTPUT_TERMINAL_LOW_FREQ_EFFECTS_SPEAKER 1159 1160 uac_mixer_unit_descriptor { 1161 bLength len[parent, int8] 1162 bDescriptorType const[USB_DT_CS_INTERFACE, int8] 1163 bDescriptorSubType const[UAC_MIXER_UNIT, int8] 1164 1165 bUnitID uac_id 1166 bNrInPins int8 1167 baSourceID array[int8, 0:6] 1168 } [packed] 1169 1170 uac_selector_unit_descriptor { 1171 bLength len[parent, int8] 1172 bDescriptorType const[USB_DT_CS_INTERFACE, int8] 1173 bDescriptorSubType const[UAC_SELECTOR_UNIT, int8] 1174 1175 bUnitID uac_id 1176 bNrInPins int8 1177 baSourceID array[int8, 0:6] 1178 } [packed] 1179 1180 uac_feature_unit_descriptor { 1181 bLength len[parent, int8] 1182 bDescriptorType const[USB_DT_CS_INTERFACE, int8] 1183 bDescriptorSubType const[UAC_FEATURE_UNIT, int8] 1184 1185 bUnitID uac_id 1186 bSourceID uac_id 1187 bControlSize len[bmaControls, int8] 1188 bmaControls array[flags[uac_feature_unit_controls, int16], 1:6] 1189 iFeature int8 1190 } [packed] 1191 1192 uac_feature_unit_controls = UAC_FU_MUTE, UAC_FU_VOLUME, UAC_FU_BASS, UAC_FU_MID, UAC_FU_TREBLE, UAC_FU_GRAPHIC_EQUALIZER, UAC_FU_AUTOMATIC_GAIN, UAC_FU_DELAY, UAC_FU_BASS_BOOST, UAC_FU_LOUDNESS 1193 1194 uac_processing_unit_descriptor { 1195 bLength len[parent, int8] 1196 bDescriptorType const[USB_DT_CS_INTERFACE, int8] 1197 bDescriptorSubType const[UAC1_PROCESSING_UNIT, int8] 1198 1199 bUnitID uac_id 1200 wProcessType flags[uac_processing_unit_types, int16] 1201 bNrInPins int8 1202 baSourceID array[int8, 0:6] 1203 } [packed] 1204 1205 uac_processing_unit_types = UAC_PROCESS_UNDEFINED, UAC_PROCESS_UP_DOWNMIX, UAC_PROCESS_DOLBY_PROLOGIC, UAC_PROCESS_STEREO_EXTENDER, UAC_PROCESS_REVERB, UAC_PROCESS_CHORUS, UAC_PROCESS_DYN_RANGE_COMP 1206 1207 uac_extension_unit_descriptor { 1208 bLength len[parent, int8] 1209 bDescriptorType const[USB_DT_CS_INTERFACE, int8] 1210 bDescriptorSubType const[UAC1_EXTENSION_UNIT, int8] 1211 1212 bUnitID uac_id 1213 wProcessType int16 1214 bNrInPins int8 1215 baSourceID array[int8, 0:6] 1216 } [packed] 1217 1218 uac1_as_header_descriptor { 1219 bLength len[parent, int8] 1220 bDescriptorType const[USB_DT_CS_INTERFACE, int8] 1221 bDescriptorSubType const[UAC_AS_GENERAL, int8] 1222 1223 bTerminalLink int8 1224 bDelay int8 1225 wFormatTag flags[uac_format_types, int16] 1226 } [packed] 1227 1228 uac_format_types = UAC_FORMAT_TYPE_I_UNDEFINED, UAC_FORMAT_TYPE_I_PCM, UAC_FORMAT_TYPE_I_PCM8, UAC_FORMAT_TYPE_I_IEEE_FLOAT, UAC_FORMAT_TYPE_I_ALAW, UAC_FORMAT_TYPE_I_MULAW, UAC_FORMAT_TYPE_II_MPEG, UAC_FORMAT_TYPE_II_AC3 1229 1230 uac_format_type_i_continuous_descriptor { 1231 bLength len[parent, int8] 1232 bDescriptorType const[USB_DT_CS_INTERFACE, int8] 1233 bDescriptorSubType const[UAC_FORMAT_TYPE, int8] 1234 1235 bFormatType const[UAC_FORMAT_TYPE_I, int8] 1236 bNrChannels int8 1237 bSubframeSize int8[1:4] 1238 bBitResolution int8 1239 bSamFreqType int8 1240 tLowerSamFreq array[int8, 0:3] 1241 tUpperSamFreq array[int8, 0:3] 1242 } [packed] 1243 1244 uac_format_type_i_discrete_descriptor { 1245 bLength len[parent, int8] 1246 bDescriptorType const[USB_DT_CS_INTERFACE, int8] 1247 bDescriptorSubType const[UAC_FORMAT_TYPE, int8] 1248 1249 bFormatType const[UAC_FORMAT_TYPE_I, int8] 1250 bNrChannels int8 1251 bSubframeSize int8[1:4] 1252 bBitResolution int8 1253 bSamFreqType int8 1254 tSamFreq array[int8, 0:9] 1255 } [packed] 1256 1257 uac_format_type_ii_discrete_descriptor { 1258 bLength len[parent, int8] 1259 bDescriptorType const[USB_DT_CS_INTERFACE, int8] 1260 bDescriptorSubType const[UAC_FORMAT_TYPE, int8] 1261 1262 bFormatType const[UAC_FORMAT_TYPE_II, int8] 1263 wMaxBitRate int16 1264 wSamplesPerFrame int16 1265 bSamFreqType int8 1266 tSamFreq array[int8, 0:9] 1267 } [packed] 1268 1269 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 1270 1271 uac_as_out_endpoint_descriptor { 1272 inner usb_endpoint_descriptor_t[const[USB_ENDPOINT_UAC1_AS_OUT_ADDRESS, int8], const[USB_ENDPOINT_UAC1_AS_ATTRIBUTES, int8], uac_iso_endpoint_descriptor] 1273 } [packed] 1274 1275 uac_as_in_endpoint_descriptor { 1276 inner usb_endpoint_descriptor_t[const[USB_ENDPOINT_UAC1_AS_IN_ADDRESS, int8], const[USB_ENDPOINT_UAC1_AS_ATTRIBUTES, int8], uac_iso_endpoint_descriptor] 1277 } [packed] 1278 1279 define USB_ENDPOINT_UAC1_AS_OUT_ADDRESS (1 | USB_DIR_OUT) 1280 define USB_ENDPOINT_UAC1_AS_IN_ADDRESS (2 | USB_DIR_IN) 1281 define USB_ENDPOINT_UAC1_AS_ATTRIBUTES (USB_ENDPOINT_SYNC_ADAPTIVE | USB_ENDPOINT_XFER_ISOC) 1282 1283 uac_iso_endpoint_descriptor { 1284 bLength len[parent, int8] 1285 bDescriptorType const[USB_DT_CS_ENDPOINT, int8] 1286 bDescriptorSubType const[UAC_EP_GENERAL, int8] 1287 1288 bmAttributes flags[uac_iso_ep_attributes, int8] 1289 bLockDelayUnits int8 1290 wLockDelay int16 1291 } [packed] 1292 1293 uac_iso_ep_attributes = UAC_EP_CS_ATTR_SAMPLE_RATE, UAC_EP_CS_ATTR_PITCH_CONTROL, UAC_EP_CS_ATTR_FILL_MAX 1294 1295 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 1296 1297 vusb_descriptors_uac1 { 1298 len len[parent, int32] 1299 generic ptr[in, vusb_descriptor_generic] 1300 1301 USB_DT_STRING ptr[in, vusb_descriptor_t[USB_TYPE_STANDARD, USB_DT_STRING, usb_string_descriptor]] 1302 } [packed] 1303 1304 vusb_responses_uac1 { 1305 len len[parent, int32] 1306 generic ptr[in, vusb_response_generic] 1307 1308 USB_REQ_GET_INTERFACE ptr[in, vusb_response_t[USB_TYPE_STANDARD, USB_REQ_GET_INTERFACE, int8]] 1309 USB_REQ_GET_CONFIGURATION ptr[in, vusb_response_t[USB_TYPE_STANDARD, USB_REQ_GET_CONFIGURATION, int8]] 1310 1311 audio_UAC_GET_CUR ptr[in, vusb_response_t[USB_TYPE_CLASS, UAC_GET_CUR, array[int8, 1:3]]] 1312 audio_UAC_GET_MIN ptr[in, vusb_response_t[USB_TYPE_CLASS, UAC_GET_MIN, array[int8, 1:3]]] 1313 audio_UAC_GET_MAX ptr[in, vusb_response_t[USB_TYPE_CLASS, UAC_GET_MAX, array[int8, 1:3]]] 1314 audio_UAC_GET_RES ptr[in, vusb_response_t[USB_TYPE_CLASS, UAC_GET_RES, array[int8, 1:4]]] 1315 audio_UAC_GET_MEM ptr[in, vusb_response_t[USB_TYPE_CLASS, UAC_GET_MEM, array[int8, 3]]] 1316 } [packed] 1317 1318 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 1319 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 1320 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 1321 1322 # TODO: describe MIDI, UAC2, UAC3 1323 # https://www.usb.org/sites/default/files/midi10.pdf 1324 # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/f_midi.c 1325 # https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/f_uac2.c 1326 # https://elixir.bootlin.com/linux/latest/source/include/linux/usb/audio-v2.h 1327 1328 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 1329 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 1330 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 1331 1332 # ath9k driver specific descriptions. 1333 1334 include <drivers/net/wireless/ath/ath9k/htc_hst.h> 1335 include <drivers/net/wireless/ath/ath9k/hif_usb.h> 1336 1337 define USB_ENDPOINT_ATH9K_BULK_OUT_ADDRESS (1) 1338 define USB_ENDPOINT_ATH9K_BULK_IN_ADDRESS (2 | USB_DIR_IN) 1339 define USB_ENDPOINT_ATH9K_INT_IN_ADDRESS (3 | USB_DIR_IN) 1340 define USB_ENDPOINT_ATH9K_INT_OUT_ADDRESS (4) 1341 define USB_ENDPOINT_ATH9K_BULK_EXTRA1_ADDRESS (5) 1342 define USB_ENDPOINT_ATH9K_BULK_EXTRA2_ADDRESS (6) 1343 1344 resource fd_usb_ath9k[fd_usb] 1345 1346 syz_usb_connect_ath9k(speed const[USB_SPEED_HIGH], dev_len len[dev], dev ptr[in, usb_device_descriptor_ath9k], conn_descs const[0]) fd_usb_ath9k (timeout[3000], prog_timeout[3000]) 1347 syz_usb_ep_write$ath9k_ep1(fd fd_usb_ath9k, ep const[USB_ENDPOINT_ATH9K_BULK_IN_ADDRESS], len bytesize[data], data ptr[in, ath9k_bulk_frame]) (timeout[300]) 1348 syz_usb_ep_write$ath9k_ep2(fd fd_usb_ath9k, ep const[USB_ENDPOINT_ATH9K_INT_IN_ADDRESS], len bytesize[data], data ptr[in, htc_frame]) (timeout[300]) 1349 1350 usb_device_descriptor_ath9k { 1351 inner usb_device_descriptor_fixed_t[0x200, USB_CLASS_VENDOR_SPEC, USB_SUBCLASS_VENDOR_SPEC, 0xff, 64, 0xcf3, 0x9271, 0x108, array[usb_config_descriptor_ath9k, 1]] 1352 } [packed] 1353 1354 usb_config_descriptor_ath9k { 1355 inner usb_config_descriptor_fixed_t[1, 1, USB_CONFIG_ATT_ONE, 250, usb_interface_descriptor_ath9k] 1356 } [packed] 1357 1358 usb_interface_descriptor_ath9k { 1359 iface usb_interface_descriptor_fixed_t[0, 0, 6, USB_CLASS_VENDOR_SPEC, 0, 0, void, usb_endpoint_descriptors_ath9k] 1360 } [packed] 1361 1362 usb_endpoint_descriptors_ath9k { 1363 bulk_out usb_endpoint_descriptor_fixed_t[USB_ENDPOINT_ATH9K_BULK_OUT_ADDRESS, USB_ENDPOINT_ATH9K_BULK_ATTRIBUTES, 512, 0, void] 1364 bulk_in usb_endpoint_descriptor_fixed_t[USB_ENDPOINT_ATH9K_BULK_IN_ADDRESS, USB_ENDPOINT_ATH9K_BULK_ATTRIBUTES, 512, 0, void] 1365 int_in usb_endpoint_descriptor_fixed_t[USB_ENDPOINT_ATH9K_INT_IN_ADDRESS, USB_ENDPOINT_ATH9K_INT_ATTRIBUTES, 64, 1, void] 1366 int_out usb_endpoint_descriptor_fixed_t[USB_ENDPOINT_ATH9K_INT_OUT_ADDRESS, USB_ENDPOINT_ATH9K_INT_ATTRIBUTES, 64, 1, void] 1367 bulk_extra1 usb_endpoint_descriptor_fixed_t[USB_ENDPOINT_ATH9K_BULK_EXTRA1_ADDRESS, USB_ENDPOINT_ATH9K_BULK_ATTRIBUTES, 512, 0, void] 1368 bulk_extra2 usb_endpoint_descriptor_fixed_t[USB_ENDPOINT_ATH9K_BULK_EXTRA2_ADDRESS, USB_ENDPOINT_ATH9K_BULK_ATTRIBUTES, 512, 0, void] 1369 } [packed] 1370 1371 define USB_ENDPOINT_ATH9K_BULK_ATTRIBUTES (USB_ENDPOINT_XFER_BULK) 1372 define USB_ENDPOINT_ATH9K_INT_ATTRIBUTES (USB_ENDPOINT_XFER_INT) 1373 1374 ath9k_bulk_frame { 1375 packets array[ath9k_bulk_packet] 1376 } [packed] 1377 1378 ath9k_bulk_packet { 1379 pkt_len len[data, int16] 1380 pkt_tag const[ATH_USB_RX_STREAM_MODE_TAG, int16] 1381 data array[int8] 1382 } [packed, align[4]] 1383 1384 htc_frame [ 1385 ready htc_ready_frame 1386 conn_svc_rsp htc_conn_svc_rsp_frame 1387 generic htc_generic_frame 1388 ] [varlen] 1389 1390 # This is actually wrong, as the driver is buggy and doesn't skip the header 1391 # before processing the frame payload, but let's leave it like thise for now. 1392 htc_ready_frame { 1393 endpoint_id const[0, int8] 1394 flags const[0, int8] 1395 payload_len len[payload, int16be] 1396 control array[int8, 4] 1397 payload htc_ready_msg 1398 } [packed] 1399 1400 htc_ready_msg { 1401 message_id const[HTC_MSG_READY_ID, int16be] 1402 credits int16be 1403 credit_size int16be 1404 max_endpoints int8 1405 pad int8 1406 } [packed] 1407 1408 htc_conn_svc_rsp_frame { 1409 endpoint_id const[0, int8] 1410 flags const[0, int8] 1411 payload_len len[payload, int16be] 1412 control array[int8, 4] 1413 payload htc_conn_svc_rspmsg 1414 } [packed] 1415 1416 htc_conn_svc_rspmsg { 1417 message_id const[HTC_MSG_CONNECT_SERVICE_RESPONSE_ID, int16be] 1418 service_id flags[htc_svcs, int16be] 1419 status const[HTC_SERVICE_SUCCESS, int8] 1420 endpoint_id int8 1421 max_msg_len int16be 1422 svc_meta_len int8 1423 pad int8 1424 } [packed] 1425 1426 htc_svcs = HTC_CTRL_RSVD_SVC, HTC_LOOPBACK_RSVD_SVC, WMI_CONTROL_SVC, WMI_BEACON_SVC, WMI_CAB_SVC, WMI_UAPSD_SVC, WMI_MGMT_SVC, WMI_DATA_VO_SVC, WMI_DATA_VI_SVC, WMI_DATA_BE_SVC, WMI_DATA_BE_SVC 1427 1428 htc_generic_frame { 1429 endpoint_id int8[0:8] 1430 flags flags[htc_frame_flags, int8] 1431 payload_len len[payload, int16be] 1432 control array[int8, 4] 1433 payload array[int8, 0:256] 1434 } [packed] 1435 1436 htc_frame_flags = HTC_FLAGS_RECV_TRAILER 1437 1438 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 1439 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 1440 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #