github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/executor/common_usb_linux.h (about) 1 // Copyright 2020 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 // This file is shared between executor and csource package. 5 6 // Linux-specific implementation of syz_usb_* pseudo-syscalls. 7 8 #include "common_usb.h" 9 10 #define UDC_NAME_LENGTH_MAX 128 11 12 struct usb_raw_init { 13 __u8 driver_name[UDC_NAME_LENGTH_MAX]; 14 __u8 device_name[UDC_NAME_LENGTH_MAX]; 15 __u8 speed; 16 }; 17 18 enum usb_raw_event_type { 19 USB_RAW_EVENT_INVALID = 0, 20 USB_RAW_EVENT_CONNECT = 1, 21 USB_RAW_EVENT_CONTROL = 2, 22 }; 23 24 struct usb_raw_event { 25 __u32 type; 26 __u32 length; 27 __u8 data[0]; 28 }; 29 30 struct usb_raw_ep_io { 31 __u16 ep; 32 __u16 flags; 33 __u32 length; 34 __u8 data[0]; 35 }; 36 37 #define USB_RAW_EPS_NUM_MAX 30 38 #define USB_RAW_EP_NAME_MAX 16 39 #define USB_RAW_EP_ADDR_ANY 0xff 40 41 struct usb_raw_ep_caps { 42 __u32 type_control : 1; 43 __u32 type_iso : 1; 44 __u32 type_bulk : 1; 45 __u32 type_int : 1; 46 __u32 dir_in : 1; 47 __u32 dir_out : 1; 48 }; 49 50 struct usb_raw_ep_limits { 51 __u16 maxpacket_limit; 52 __u16 max_streams; 53 __u32 reserved; 54 }; 55 56 struct usb_raw_ep_info { 57 __u8 name[USB_RAW_EP_NAME_MAX]; 58 __u32 addr; 59 struct usb_raw_ep_caps caps; 60 struct usb_raw_ep_limits limits; 61 }; 62 63 struct usb_raw_eps_info { 64 struct usb_raw_ep_info eps[USB_RAW_EPS_NUM_MAX]; 65 }; 66 67 #define USB_RAW_IOCTL_INIT _IOW('U', 0, struct usb_raw_init) 68 #define USB_RAW_IOCTL_RUN _IO('U', 1) 69 #define USB_RAW_IOCTL_EVENT_FETCH _IOR('U', 2, struct usb_raw_event) 70 #define USB_RAW_IOCTL_EP0_WRITE _IOW('U', 3, struct usb_raw_ep_io) 71 #define USB_RAW_IOCTL_EP0_READ _IOWR('U', 4, struct usb_raw_ep_io) 72 #define USB_RAW_IOCTL_EP_ENABLE _IOW('U', 5, struct usb_endpoint_descriptor) 73 #define USB_RAW_IOCTL_EP_DISABLE _IOW('U', 6, __u32) 74 #define USB_RAW_IOCTL_EP_WRITE _IOW('U', 7, struct usb_raw_ep_io) 75 #define USB_RAW_IOCTL_EP_READ _IOWR('U', 8, struct usb_raw_ep_io) 76 #define USB_RAW_IOCTL_CONFIGURE _IO('U', 9) 77 #define USB_RAW_IOCTL_VBUS_DRAW _IOW('U', 10, __u32) 78 #define USB_RAW_IOCTL_EPS_INFO _IOR('U', 11, struct usb_raw_eps_info) 79 #define USB_RAW_IOCTL_EP0_STALL _IO('U', 12) 80 #define USB_RAW_IOCTL_EP_SET_HALT _IOW('U', 13, __u32) 81 #define USB_RAW_IOCTL_EP_CLEAR_HALT _IOW('U', 14, __u32) 82 #define USB_RAW_IOCTL_EP_SET_WEDGE _IOW('U', 15, __u32) 83 84 #if SYZ_EXECUTOR || __NR_syz_usb_connect || __NR_syz_usb_connect_ath9k 85 static int usb_raw_open() 86 { 87 return open("/dev/raw-gadget", O_RDWR); 88 } 89 90 static int usb_raw_init(int fd, uint32 speed, const char* driver, const char* device) 91 { 92 struct usb_raw_init arg; 93 strncpy((char*)&arg.driver_name[0], driver, sizeof(arg.driver_name)); 94 strncpy((char*)&arg.device_name[0], device, sizeof(arg.device_name)); 95 arg.speed = speed; 96 return ioctl(fd, USB_RAW_IOCTL_INIT, &arg); 97 } 98 99 static int usb_raw_run(int fd) 100 { 101 return ioctl(fd, USB_RAW_IOCTL_RUN, 0); 102 } 103 #endif // #if SYZ_EXECUTOR || __NR_syz_usb_connect || __NR_syz_usb_connect_ath9k 104 105 #if SYZ_EXECUTOR || __NR_syz_usb_ep_write 106 static int usb_raw_ep_write(int fd, struct usb_raw_ep_io* io) 107 { 108 return ioctl(fd, USB_RAW_IOCTL_EP_WRITE, io); 109 } 110 #endif // SYZ_EXECUTOR || __NR_syz_usb_ep_write 111 112 #if SYZ_EXECUTOR || __NR_syz_usb_ep_read 113 static int usb_raw_ep_read(int fd, struct usb_raw_ep_io* io) 114 { 115 return ioctl(fd, USB_RAW_IOCTL_EP_READ, io); 116 } 117 #endif // SYZ_EXECUTOR || __NR_syz_usb_ep_read 118 119 #if SYZ_EXECUTOR || __NR_syz_usb_connect || __NR_syz_usb_connect_ath9k 120 121 static int usb_raw_configure(int fd) 122 { 123 return ioctl(fd, USB_RAW_IOCTL_CONFIGURE, 0); 124 } 125 126 static int usb_raw_vbus_draw(int fd, uint32 power) 127 { 128 return ioctl(fd, USB_RAW_IOCTL_VBUS_DRAW, power); 129 } 130 131 #endif // #if SYZ_EXECUTOR || __NR_syz_usb_connect || __NR_syz_usb_connect_ath9k 132 133 #if SYZ_EXECUTOR || __NR_syz_usb_connect || __NR_syz_usb_connect_ath9k || __NR_syz_usb_control_io 134 static int usb_raw_ep0_write(int fd, struct usb_raw_ep_io* io) 135 { 136 return ioctl(fd, USB_RAW_IOCTL_EP0_WRITE, io); 137 } 138 139 static int usb_raw_ep0_read(int fd, struct usb_raw_ep_io* io) 140 { 141 return ioctl(fd, USB_RAW_IOCTL_EP0_READ, io); 142 } 143 144 static int usb_raw_event_fetch(int fd, struct usb_raw_event* event) 145 { 146 return ioctl(fd, USB_RAW_IOCTL_EVENT_FETCH, event); 147 } 148 149 static int usb_raw_ep_enable(int fd, struct usb_endpoint_descriptor* desc) 150 { 151 return ioctl(fd, USB_RAW_IOCTL_EP_ENABLE, desc); 152 } 153 154 static int usb_raw_ep_disable(int fd, int ep) 155 { 156 return ioctl(fd, USB_RAW_IOCTL_EP_DISABLE, ep); 157 } 158 159 static int usb_raw_ep0_stall(int fd) 160 { 161 return ioctl(fd, USB_RAW_IOCTL_EP0_STALL, 0); 162 } 163 #endif // #if SYZ_EXECUTOR || __NR_syz_usb_connect || __NR_syz_usb_connect_ath9k || __NR_syz_usb_control_io 164 165 #if SYZ_EXECUTOR || __NR_syz_usb_control_io 166 static int lookup_interface(int fd, uint8 bInterfaceNumber, uint8 bAlternateSetting) 167 { 168 struct usb_device_index* index = lookup_usb_index(fd); 169 if (!index) 170 return -1; 171 172 for (int i = 0; i < index->ifaces_num; i++) { 173 if (index->ifaces[i].bInterfaceNumber == bInterfaceNumber && 174 index->ifaces[i].bAlternateSetting == bAlternateSetting) 175 return i; 176 } 177 return -1; 178 } 179 #endif // SYZ_EXECUTOR || __NR_syz_usb_control_io 180 181 #if SYZ_EXECUTOR || __NR_syz_usb_ep_write || __NR_syz_usb_ep_read 182 static int lookup_endpoint(int fd, uint8 bEndpointAddress) 183 { 184 struct usb_device_index* index = lookup_usb_index(fd); 185 if (!index) 186 return -1; 187 if (index->iface_cur < 0) 188 return -1; 189 190 for (int ep = 0; ep < index->ifaces[index->iface_cur].eps_num; ep++) 191 if (index->ifaces[index->iface_cur].eps[ep].desc.bEndpointAddress == bEndpointAddress) 192 return index->ifaces[index->iface_cur].eps[ep].handle; 193 return -1; 194 } 195 #endif // SYZ_EXECUTOR || __NR_syz_usb_ep_write || __NR_syz_usb_ep_read 196 197 #define USB_MAX_PACKET_SIZE 4096 198 199 struct usb_raw_control_event { 200 struct usb_raw_event inner; 201 struct usb_ctrlrequest ctrl; 202 char data[USB_MAX_PACKET_SIZE]; 203 }; 204 205 struct usb_raw_ep_io_data { 206 struct usb_raw_ep_io inner; 207 char data[USB_MAX_PACKET_SIZE]; 208 }; 209 210 #if SYZ_EXECUTOR || __NR_syz_usb_connect || __NR_syz_usb_connect_ath9k || __NR_syz_usb_control_io 211 static void set_interface(int fd, int n) 212 { 213 struct usb_device_index* index = lookup_usb_index(fd); 214 if (!index) 215 return; 216 217 if (index->iface_cur >= 0 && index->iface_cur < index->ifaces_num) { 218 for (int ep = 0; ep < index->ifaces[index->iface_cur].eps_num; ep++) { 219 int rv = usb_raw_ep_disable(fd, index->ifaces[index->iface_cur].eps[ep].handle); 220 if (rv < 0) { 221 debug("set_interface: failed to disable endpoint 0x%02x\n", 222 index->ifaces[index->iface_cur].eps[ep].desc.bEndpointAddress); 223 } else { 224 debug("set_interface: endpoint 0x%02x disabled\n", 225 index->ifaces[index->iface_cur].eps[ep].desc.bEndpointAddress); 226 } 227 } 228 } 229 if (n >= 0 && n < index->ifaces_num) { 230 for (int ep = 0; ep < index->ifaces[n].eps_num; ep++) { 231 int rv = usb_raw_ep_enable(fd, &index->ifaces[n].eps[ep].desc); 232 if (rv < 0) { 233 debug("set_interface: failed to enable endpoint 0x%02x\n", 234 index->ifaces[n].eps[ep].desc.bEndpointAddress); 235 } else { 236 debug("set_interface: endpoint 0x%02x enabled as %d\n", 237 index->ifaces[n].eps[ep].desc.bEndpointAddress, rv); 238 index->ifaces[n].eps[ep].handle = rv; 239 } 240 } 241 index->iface_cur = n; 242 } 243 } 244 #endif // #if SYZ_EXECUTOR || __NR_syz_usb_connect || __NR_syz_usb_connect_ath9k || __NR_syz_usb_control_io 245 246 #if SYZ_EXECUTOR || __NR_syz_usb_connect || __NR_syz_usb_connect_ath9k 247 static int configure_device(int fd) 248 { 249 struct usb_device_index* index = lookup_usb_index(fd); 250 251 if (!index) 252 return -1; 253 254 int rv = usb_raw_vbus_draw(fd, index->bMaxPower); 255 if (rv < 0) { 256 debug("configure_device: usb_raw_vbus_draw failed with %d\n", rv); 257 return rv; 258 } 259 rv = usb_raw_configure(fd); 260 if (rv < 0) { 261 debug("configure_device: usb_raw_configure failed with %d\n", rv); 262 return rv; 263 } 264 set_interface(fd, 0); 265 return 0; 266 } 267 268 static volatile long syz_usb_connect_impl(uint64 speed, uint64 dev_len, const char* dev, 269 const struct vusb_connect_descriptors* descs, 270 lookup_connect_out_response_t lookup_connect_response_out) 271 { 272 debug("syz_usb_connect: dev: %p\n", dev); 273 if (!dev) { 274 debug("syz_usb_connect: dev is null\n"); 275 return -1; 276 } 277 278 debug("syz_usb_connect: device data:\n"); 279 debug_dump_data(dev, dev_len); 280 281 int fd = usb_raw_open(); 282 if (fd < 0) { 283 debug("syz_usb_connect: usb_raw_open failed with %d\n", fd); 284 return fd; 285 } 286 if (fd >= MAX_FDS) { 287 close(fd); 288 debug("syz_usb_connect: too many open fds\n"); 289 return -1; 290 } 291 debug("syz_usb_connect: usb_raw_open success\n"); 292 293 struct usb_device_index* index = add_usb_index(fd, dev, dev_len); 294 if (!index) { 295 debug("syz_usb_connect: add_usb_index failed\n"); 296 return -1; 297 } 298 debug("syz_usb_connect: add_usb_index success\n"); 299 300 #if USB_DEBUG 301 analyze_usb_device(index); 302 #endif 303 304 // TODO: consider creating two dummy_udc's per proc to increace the chance of 305 // triggering interaction between multiple USB devices within the same program. 306 char device[32]; 307 sprintf(&device[0], "dummy_udc.%llu", procid); 308 int rv = usb_raw_init(fd, speed, "dummy_udc", &device[0]); 309 if (rv < 0) { 310 debug("syz_usb_connect: usb_raw_init failed with %d\n", rv); 311 return rv; 312 } 313 debug("syz_usb_connect: usb_raw_init success\n"); 314 315 rv = usb_raw_run(fd); 316 if (rv < 0) { 317 debug("syz_usb_connect: usb_raw_run failed with %d\n", rv); 318 return rv; 319 } 320 debug("syz_usb_connect: usb_raw_run success\n"); 321 322 bool done = false; 323 while (!done) { 324 struct usb_raw_control_event event; 325 event.inner.type = 0; 326 event.inner.length = sizeof(event.ctrl); 327 rv = usb_raw_event_fetch(fd, (struct usb_raw_event*)&event); 328 if (rv < 0) { 329 debug("syz_usb_connect: usb_raw_event_fetch failed with %d\n", rv); 330 return rv; 331 } 332 if (event.inner.type != USB_RAW_EVENT_CONTROL) 333 continue; 334 335 debug("syz_usb_connect: bReqType: 0x%x (%s), bReq: 0x%x, wVal: 0x%x, wIdx: 0x%x, wLen: %d\n", 336 event.ctrl.bRequestType, (event.ctrl.bRequestType & USB_DIR_IN) ? "IN" : "OUT", 337 event.ctrl.bRequest, event.ctrl.wValue, event.ctrl.wIndex, event.ctrl.wLength); 338 339 #if USB_DEBUG 340 analyze_control_request(fd, &event.ctrl); 341 #endif 342 343 char* response_data = NULL; 344 uint32 response_length = 0; 345 struct usb_qualifier_descriptor qual; 346 347 if (event.ctrl.bRequestType & USB_DIR_IN) { 348 if (!lookup_connect_response_in(fd, descs, &event.ctrl, &qual, &response_data, &response_length)) { 349 debug("syz_usb_connect: unknown request, stalling\n"); 350 usb_raw_ep0_stall(fd); 351 continue; 352 } 353 } else { 354 if (!lookup_connect_response_out(fd, descs, &event.ctrl, &done)) { 355 debug("syz_usb_connect: unknown request, stalling\n"); 356 usb_raw_ep0_stall(fd); 357 continue; 358 } 359 response_data = NULL; 360 response_length = event.ctrl.wLength; 361 } 362 363 if ((event.ctrl.bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD && 364 event.ctrl.bRequest == USB_REQ_SET_CONFIGURATION) { 365 rv = configure_device(fd); 366 if (rv < 0) { 367 debug("syz_usb_connect: configure_device failed with %d\n", rv); 368 return rv; 369 } 370 } 371 372 struct usb_raw_ep_io_data response; 373 response.inner.ep = 0; 374 response.inner.flags = 0; 375 if (response_length > sizeof(response.data)) 376 response_length = 0; 377 if (event.ctrl.wLength < response_length) 378 response_length = event.ctrl.wLength; 379 response.inner.length = response_length; 380 if (response_data) 381 memcpy(&response.data[0], response_data, response_length); 382 else 383 memset(&response.data[0], 0, response_length); 384 385 if (event.ctrl.bRequestType & USB_DIR_IN) { 386 debug("syz_usb_connect: writing %d bytes\n", response.inner.length); 387 rv = usb_raw_ep0_write(fd, (struct usb_raw_ep_io*)&response); 388 } else { 389 rv = usb_raw_ep0_read(fd, (struct usb_raw_ep_io*)&response); 390 debug("syz_usb_connect: read %d bytes\n", response.inner.length); 391 debug_dump_data(&event.data[0], response.inner.length); 392 } 393 if (rv < 0) { 394 debug("syz_usb_connect: usb_raw_ep0_read/write failed with %d\n", rv); 395 return rv; 396 } 397 } 398 399 sleep_ms(200); 400 401 debug("syz_usb_connect: configured\n"); 402 403 return fd; 404 } 405 406 #endif // #if SYZ_EXECUTOR || __NR_syz_usb_connect || __NR_syz_usb_connect_ath9k 407 408 #if SYZ_EXECUTOR || __NR_syz_usb_connect 409 static volatile long syz_usb_connect(volatile long a0, volatile long a1, volatile long a2, volatile long a3) 410 { 411 uint64 speed = a0; 412 uint64 dev_len = a1; 413 const char* dev = (const char*)a2; 414 const struct vusb_connect_descriptors* descs = (const struct vusb_connect_descriptors*)a3; 415 416 return syz_usb_connect_impl(speed, dev_len, dev, descs, &lookup_connect_response_out_generic); 417 } 418 #endif // SYZ_EXECUTOR || __NR_syz_usb_connect 419 420 #if SYZ_EXECUTOR || __NR_syz_usb_connect_ath9k 421 static volatile long syz_usb_connect_ath9k(volatile long a0, volatile long a1, volatile long a2, volatile long a3) 422 { 423 uint64 speed = a0; 424 uint64 dev_len = a1; 425 const char* dev = (const char*)a2; 426 const struct vusb_connect_descriptors* descs = (const struct vusb_connect_descriptors*)a3; 427 428 return syz_usb_connect_impl(speed, dev_len, dev, descs, &lookup_connect_response_out_ath9k); 429 } 430 #endif // SYZ_EXECUTOR || __NR_syz_usb_connect_ath9k 431 432 #if SYZ_EXECUTOR || __NR_syz_usb_control_io 433 static volatile long syz_usb_control_io(volatile long a0, volatile long a1, volatile long a2) 434 { 435 int fd = a0; 436 const struct vusb_descriptors* descs = (const struct vusb_descriptors*)a1; 437 const struct vusb_responses* resps = (const struct vusb_responses*)a2; 438 439 struct usb_raw_control_event event; 440 event.inner.type = 0; 441 event.inner.length = USB_MAX_PACKET_SIZE; 442 int rv = usb_raw_event_fetch(fd, (struct usb_raw_event*)&event); 443 if (rv < 0) { 444 debug("syz_usb_control_io: usb_raw_ep0_read failed with %d\n", rv); 445 return rv; 446 } 447 if (event.inner.type != USB_RAW_EVENT_CONTROL) { 448 debug("syz_usb_control_io: wrong event type: %d\n", (int)event.inner.type); 449 return -1; 450 } 451 452 debug("syz_usb_control_io: bReqType: 0x%x (%s), bReq: 0x%x, wVal: 0x%x, wIdx: 0x%x, wLen: %d\n", 453 event.ctrl.bRequestType, (event.ctrl.bRequestType & USB_DIR_IN) ? "IN" : "OUT", 454 event.ctrl.bRequest, event.ctrl.wValue, event.ctrl.wIndex, event.ctrl.wLength); 455 456 #if USB_DEBUG 457 analyze_control_request(fd, &event.ctrl); 458 #endif 459 460 char* response_data = NULL; 461 uint32 response_length = 0; 462 463 if ((event.ctrl.bRequestType & USB_DIR_IN) && event.ctrl.wLength) { 464 if (!lookup_control_response(descs, resps, &event.ctrl, &response_data, &response_length)) { 465 debug("syz_usb_connect: unknown request, stalling\n"); 466 usb_raw_ep0_stall(fd); 467 return -1; 468 } 469 } else { 470 if ((event.ctrl.bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD || 471 event.ctrl.bRequest == USB_REQ_SET_INTERFACE) { 472 int iface_num = event.ctrl.wIndex; 473 int alt_set = event.ctrl.wValue; 474 debug("syz_usb_control_io: setting interface (%d, %d)\n", iface_num, alt_set); 475 int iface_index = lookup_interface(fd, iface_num, alt_set); 476 if (iface_index < 0) { 477 debug("syz_usb_control_io: interface (%d, %d) not found\n", iface_num, alt_set); 478 } else { 479 set_interface(fd, iface_index); 480 debug("syz_usb_control_io: interface (%d, %d) set\n", iface_num, alt_set); 481 } 482 } 483 484 response_length = event.ctrl.wLength; 485 } 486 487 struct usb_raw_ep_io_data response; 488 response.inner.ep = 0; 489 response.inner.flags = 0; 490 if (response_length > sizeof(response.data)) 491 response_length = 0; 492 if (event.ctrl.wLength < response_length) 493 response_length = event.ctrl.wLength; 494 if ((event.ctrl.bRequestType & USB_DIR_IN) && !event.ctrl.wLength) { 495 // Something fishy is going on, try to read more data. 496 response_length = USB_MAX_PACKET_SIZE; 497 } 498 response.inner.length = response_length; 499 if (response_data) 500 memcpy(&response.data[0], response_data, response_length); 501 else 502 memset(&response.data[0], 0, response_length); 503 504 if ((event.ctrl.bRequestType & USB_DIR_IN) && event.ctrl.wLength) { 505 debug("syz_usb_control_io: writing %d bytes\n", response.inner.length); 506 debug_dump_data(&response.data[0], response.inner.length); 507 rv = usb_raw_ep0_write(fd, (struct usb_raw_ep_io*)&response); 508 } else { 509 rv = usb_raw_ep0_read(fd, (struct usb_raw_ep_io*)&response); 510 debug("syz_usb_control_io: read %d bytes\n", response.inner.length); 511 debug_dump_data(&response.data[0], response.inner.length); 512 } 513 if (rv < 0) { 514 debug("syz_usb_control_io: usb_raw_ep0_read/write failed with %d\n", rv); 515 return rv; 516 } 517 518 sleep_ms(200); 519 520 return 0; 521 } 522 #endif // SYZ_EXECUTOR || __NR_syz_usb_control_io 523 524 #if SYZ_EXECUTOR || __NR_syz_usb_ep_write 525 static volatile long syz_usb_ep_write(volatile long a0, volatile long a1, volatile long a2, volatile long a3) 526 { 527 int fd = a0; 528 uint8 ep = a1; 529 uint32 len = a2; 530 char* data = (char*)a3; 531 532 int ep_handle = lookup_endpoint(fd, ep); 533 if (ep_handle < 0) { 534 debug("syz_usb_ep_write: endpoint not found\n"); 535 return -1; 536 } 537 debug("syz_usb_ep_write: endpoint handle: %d\n", ep_handle); 538 539 struct usb_raw_ep_io_data io_data; 540 io_data.inner.ep = ep_handle; 541 io_data.inner.flags = 0; 542 if (len > sizeof(io_data.data)) 543 len = sizeof(io_data.data); 544 io_data.inner.length = len; 545 memcpy(&io_data.data[0], data, len); 546 547 int rv = usb_raw_ep_write(fd, (struct usb_raw_ep_io*)&io_data); 548 if (rv < 0) { 549 debug("syz_usb_ep_write: usb_raw_ep_write failed with %d\n", rv); 550 return rv; 551 } 552 553 sleep_ms(200); 554 555 return 0; 556 } 557 #endif // SYZ_EXECUTOR || __NR_syz_usb_ep_write 558 559 #if SYZ_EXECUTOR || __NR_syz_usb_ep_read 560 static volatile long syz_usb_ep_read(volatile long a0, volatile long a1, volatile long a2, volatile long a3) 561 { 562 int fd = a0; 563 uint8 ep = a1; 564 uint32 len = a2; 565 char* data = (char*)a3; 566 567 int ep_handle = lookup_endpoint(fd, ep); 568 if (ep_handle < 0) { 569 debug("syz_usb_ep_read: endpoint not found\n"); 570 return -1; 571 } 572 debug("syz_usb_ep_read: endpoint handle: %d\n", ep_handle); 573 574 struct usb_raw_ep_io_data io_data; 575 io_data.inner.ep = ep_handle; 576 io_data.inner.flags = 0; 577 if (len > sizeof(io_data.data)) 578 len = sizeof(io_data.data); 579 io_data.inner.length = len; 580 581 int rv = usb_raw_ep_read(fd, (struct usb_raw_ep_io*)&io_data); 582 if (rv < 0) { 583 debug("syz_usb_ep_read: usb_raw_ep_read failed with %d\n", rv); 584 return rv; 585 } 586 587 memcpy(&data[0], &io_data.data[0], io_data.inner.length); 588 589 debug("syz_usb_ep_read: received data:\n"); 590 debug_dump_data(&io_data.data[0], io_data.inner.length); 591 592 sleep_ms(200); 593 594 return 0; 595 } 596 #endif // SYZ_EXECUTOR || __NR_syz_usb_ep_read 597 598 #if SYZ_EXECUTOR || __NR_syz_usb_disconnect 599 static volatile long syz_usb_disconnect(volatile long a0) 600 { 601 int fd = a0; 602 603 int rv = close(fd); 604 605 sleep_ms(200); 606 607 return rv; 608 } 609 #endif // SYZ_EXECUTOR || __NR_syz_usb_disconnect