// 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 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] = syscall(__NR_mmap, 0x20003000ul, 0x1000ul, 0x3ul, 0x32ul, 0xfffffffffffffffful, 0x0ul); *(uint32_t*)0x20003000 = (uint32_t)0x0; *(uint8_t*)0x20003004 = (uint8_t)0x9; *(uint8_t*)0x20003005 = (uint8_t)0x2; *(uint16_t*)0x20003006 = (uint16_t)0x36; *(uint8_t*)0x20003008 = (uint8_t)0x1; *(uint8_t*)0x20003009 = (uint8_t)0x8; *(uint8_t*)0x2000300a = (uint8_t)0x600; *(uint8_t*)0x2000300b = (uint8_t)0x80; *(uint8_t*)0x2000300c = (uint8_t)0x8; *(uint8_t*)0x2000300d = (uint8_t)0x9; *(uint8_t*)0x2000300e = (uint8_t)0x4; *(uint8_t*)0x2000300f = (uint8_t)0x0; *(uint8_t*)0x20003010 = (uint8_t)0x9; *(uint8_t*)0x20003011 = (uint8_t)0x4; *(uint8_t*)0x20003012 = (uint8_t)0xff; *(uint8_t*)0x20003013 = (uint8_t)0x3; *(uint8_t*)0x20003014 = (uint8_t)0x0; *(uint8_t*)0x20003015 = (uint8_t)0x7; *(uint8_t*)0x20003016 = (uint8_t)0x9; *(uint8_t*)0x20003017 = (uint8_t)0x5; *(uint8_t*)0x20003018 = (uint8_t)0x9; *(uint8_t*)0x20003019 = (uint8_t)0x10; *(uint16_t*)0x2000301a = (uint16_t)0x1; *(uint8_t*)0x2000301c = (uint8_t)0x5; *(uint8_t*)0x2000301d = (uint8_t)0xfffffffffffff800; *(uint8_t*)0x2000301e = (uint8_t)0x2bba; *(uint8_t*)0x2000301f = (uint8_t)0x9; *(uint8_t*)0x20003020 = (uint8_t)0x5; *(uint8_t*)0x20003021 = (uint8_t)0x898f; *(uint8_t*)0x20003022 = (uint8_t)0x3; *(uint16_t*)0x20003023 = (uint16_t)0x7c113347; *(uint8_t*)0x20003025 = (uint8_t)0x0; *(uint8_t*)0x20003026 = (uint8_t)0xbc; *(uint8_t*)0x20003027 = (uint8_t)0x5; *(uint8_t*)0x20003028 = (uint8_t)0x9; *(uint8_t*)0x20003029 = (uint8_t)0x5; *(uint8_t*)0x2000302a = (uint8_t)0x7; *(uint8_t*)0x2000302b = (uint8_t)0x14; *(uint16_t*)0x2000302c = (uint16_t)0x972f; *(uint8_t*)0x2000302e = (uint8_t)0x1f; *(uint8_t*)0x2000302f = (uint8_t)0x7; *(uint8_t*)0x20003030 = (uint8_t)0x3f; *(uint8_t*)0x20003031 = (uint8_t)0x9; *(uint8_t*)0x20003032 = (uint8_t)0x5; *(uint8_t*)0x20003033 = (uint8_t)0x8; *(uint8_t*)0x20003034 = (uint8_t)0x0; *(uint16_t*)0x20003035 = (uint16_t)0x7; *(uint8_t*)0x20003037 = (uint8_t)0x81; *(uint8_t*)0x20003038 = (uint8_t)0x7ff; *(uint8_t*)0x20003039 = (uint8_t)0x200; *(uint8_t*)0x2000303a = (uint8_t)0x12; *(uint8_t*)0x2000303b = (uint8_t)0x1; *(uint16_t*)0x2000303c = (uint16_t)0xffffffffffffffff; *(uint8_t*)0x2000303e = (uint8_t)0x7fd; *(uint8_t*)0x2000303f = (uint8_t)0x4; *(uint8_t*)0x20003040 = (uint8_t)0x3; *(uint8_t*)0x20003041 = (uint8_t)0x1000; *(uint16_t*)0x20003042 = (uint16_t)0x403; *(uint16_t*)0x20003044 = (uint16_t)0x1000f9e9; *(uint16_t*)0x20003046 = (uint16_t)0x4; *(uint8_t*)0x20003048 = (uint8_t)0x4; *(uint8_t*)0x20003049 = (uint8_t)0x8; *(uint8_t*)0x2000304a = (uint8_t)0x7ff; *(uint8_t*)0x2000304b = (uint8_t)0x1; r[65] = syz_usb_config(0x4cul, 0x20003000ul); } int main() { gadgetfs_mkdir(); gadgetfs_mount(); loop(); return 0; }