// autogenerated by syzkaller (http://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include void gadgetfs_mkdir() { mkdir("/dev/gadget", 0755) != 0; } void gadgetfs_mount() { while (mount("none", "/dev/gadget", "gadgetfs", 0, NULL) != 0) { usleep(10 * 1000); umount2("/dev/gadget", MNT_FORCE | MNT_DETACH); } } static int gfs_handle_event_setup_get_descriptor(int fd, struct usb_ctrlrequest* setup) { char buffer[128]; int rv; switch (setup->wValue >> 8) { case USB_DT_STRING: buffer[0] = 4; buffer[1] = USB_DT_STRING; if ((setup->wValue & 0x0ff) == 0) { buffer[2] = 0x09; buffer[3] = 0x04; } else { buffer[2] = 0x61; buffer[3] = 0x00; } rv = write(fd, &buffer[0], 4); if (rv != 4) { return -1; } break; default: break; } return 0; } static int gfs_handle_event_setup_set_configuration(int fd, struct usb_ctrlrequest* setup) { int rv = read(fd, &rv, 0); if (rv != 0) { return -1; } return 0; } static int gfs_handle_event_setup(int fd, struct usb_ctrlrequest* setup) { switch (setup->bRequest) { case USB_REQ_GET_DESCRIPTOR: gfs_handle_event_setup_get_descriptor(fd, setup); break; case USB_REQ_SET_CONFIGURATION: gfs_handle_event_setup_set_configuration(fd, setup); break; case USB_REQ_GET_INTERFACE: break; case USB_REQ_SET_INTERFACE: break; default: break; } return 0; } static int gfs_handle_event(int fd, struct usb_gadgetfs_event* event) { switch (event->type) { case GADGETFS_NOP: break; case GADGETFS_CONNECT: break; case GADGETFS_SETUP: gfs_handle_event_setup(fd, &event->u.setup); break; case GADGETFS_DISCONNECT: break; case GADGETFS_SUSPEND: break; default: break; } return 0; } #define GFS_MAX_EVENTS 1 static int gfs_handle_ep0(int fd) { struct pollfd pfd; struct usb_gadgetfs_event events[GFS_MAX_EVENTS]; pfd.fd = fd; pfd.events = POLLIN | POLLOUT | POLLHUP; int i; for (i = 0; i < 15; i++) { int rv = poll(&pfd, 1, 100); if (rv < 0) { return -1; } if (rv == 0) continue; rv = read(fd, &events[0], sizeof(events)); if (rv < 0) { return -2; } if (rv == 0) continue; gfs_handle_event(fd, &events[0]); } return 0; } static uintptr_t syz_usb_config(uintptr_t a0, uintptr_t a1) { int fd = open("/dev/gadget/dummy_udc", O_RDWR); if (fd < 0) return -1; usleep(30 * 1000); int64_t length = a0; char* data = (char*)a1; int rv = write(fd, data, length); if (rv < 0) { return -2; } gfs_handle_ep0(fd); return fd; } long r[66]; void loop() { memset(r, -1, sizeof(r)); r[0] = (long)mmap((void*)0x23000ul, 0x1000ul, 0x3ul, 0x32ul, 0xfffffffful, 0x0ul); *(uint32_t*)0x23000 = (uint32_t)0x0; *(uint8_t*)0x23004 = (uint8_t)0x9; *(uint8_t*)0x23005 = (uint8_t)0x2; *(uint16_t*)0x23006 = (uint16_t)0x36; *(uint8_t*)0x23008 = (uint8_t)0x1; *(uint8_t*)0x23009 = (uint8_t)0x8; *(uint8_t*)0x2300a = (uint8_t)0x600; *(uint8_t*)0x2300b = (uint8_t)0x80; *(uint8_t*)0x2300c = (uint8_t)0x8; *(uint8_t*)0x2300d = (uint8_t)0x9; *(uint8_t*)0x2300e = (uint8_t)0x4; *(uint8_t*)0x2300f = (uint8_t)0x0; *(uint8_t*)0x23010 = (uint8_t)0x9; *(uint8_t*)0x23011 = (uint8_t)0x4; *(uint8_t*)0x23012 = (uint8_t)0xff; *(uint8_t*)0x23013 = (uint8_t)0x3; *(uint8_t*)0x23014 = (uint8_t)0x0; *(uint8_t*)0x23015 = (uint8_t)0x7; *(uint8_t*)0x23016 = (uint8_t)0x9; *(uint8_t*)0x23017 = (uint8_t)0x5; *(uint8_t*)0x23018 = (uint8_t)0x9; *(uint8_t*)0x23019 = (uint8_t)0x10; *(uint16_t*)0x2301a = (uint16_t)0x1; *(uint8_t*)0x2301c = (uint8_t)0x5; *(uint8_t*)0x2301d = (uint8_t)0xfffff800; *(uint8_t*)0x2301e = (uint8_t)0x2bba; *(uint8_t*)0x2301f = (uint8_t)0x9; *(uint8_t*)0x23020 = (uint8_t)0x5; *(uint8_t*)0x23021 = (uint8_t)0x898f; *(uint8_t*)0x23022 = (uint8_t)0x3; *(uint16_t*)0x23023 = (uint16_t)0x7c113347; *(uint8_t*)0x23025 = (uint8_t)0x0; *(uint8_t*)0x23026 = (uint8_t)0xbc; *(uint8_t*)0x23027 = (uint8_t)0x5; *(uint8_t*)0x23028 = (uint8_t)0x9; *(uint8_t*)0x23029 = (uint8_t)0x5; *(uint8_t*)0x2302a = (uint8_t)0x7; *(uint8_t*)0x2302b = (uint8_t)0x14; *(uint16_t*)0x2302c = (uint16_t)0x972f; *(uint8_t*)0x2302e = (uint8_t)0x1f; *(uint8_t*)0x2302f = (uint8_t)0x7; *(uint8_t*)0x23030 = (uint8_t)0x3f; *(uint8_t*)0x23031 = (uint8_t)0x9; *(uint8_t*)0x23032 = (uint8_t)0x5; *(uint8_t*)0x23033 = (uint8_t)0x8; *(uint8_t*)0x23034 = (uint8_t)0x0; *(uint16_t*)0x23035 = (uint16_t)0x7; *(uint8_t*)0x23037 = (uint8_t)0x81; *(uint8_t*)0x23038 = (uint8_t)0x7ff; *(uint8_t*)0x23039 = (uint8_t)0x200; *(uint8_t*)0x2303a = (uint8_t)0x12; *(uint8_t*)0x2303b = (uint8_t)0x1; *(uint16_t*)0x2303c = (uint16_t)0xffffffff; *(uint8_t*)0x2303e = (uint8_t)0x7fd; *(uint8_t*)0x2303f = (uint8_t)0x4; *(uint8_t*)0x23040 = (uint8_t)0x3; *(uint8_t*)0x23041 = (uint8_t)0x1000; *(uint16_t*)0x23042 = (uint16_t)0x403; *(uint16_t*)0x23044 = (uint16_t)0x1000f9e9; *(uint16_t*)0x23046 = (uint16_t)0x4; *(uint8_t*)0x23048 = (uint8_t)0x4; *(uint8_t*)0x23049 = (uint8_t)0x8; *(uint8_t*)0x2304a = (uint8_t)0x7ff; *(uint8_t*)0x2304b = (uint8_t)0x1; r[65] = syz_usb_config(0x4cul, 0x23000ul); } int main() { gadgetfs_mkdir(); gadgetfs_mount(); loop(); return 0; }