// https://syzkaller.appspot.com/bug?id=7ff8ae4abed51ff2354c1addb664143ec26ca588 #include #include #include #include #include #include #include #include int main() { printf("[+] Starting reproducer...\n"); // Lower the hung task timeout to 15 seconds to ensure the warning is printed // before the test infrastructure kills the VM at 150 seconds. int fd = open("/proc/sys/kernel/hung_task_timeout_secs", O_WRONLY); if (fd >= 0) { int res = write(fd, "15\n", 3); if (res < 0) { printf("[-] Failed to write hung_task_timeout_secs: %s\n", strerror(errno)); // Non-fatal if we can't write, but we should log it. } else { printf("[+] write hung_task_timeout_secs successful.\n"); } if (close(fd) < 0) { printf("[-] Failed to close hung_task_timeout_secs: %s\n", strerror(errno)); } else { printf("[+] close hung_task_timeout_secs successful.\n"); } } else { printf("[-] Failed to open hung_task_timeout_secs: %s\n", strerror(errno)); } int attach_fd = open("/sys/devices/platform/vhci_hcd.0/attach", O_WRONLY); if (attach_fd < 0) { printf("[-] Failed to open attach: %s\n", strerror(errno)); exit(1); } printf("[+] open attach successful.\n"); // 1. Attach device to port 0 (USB 2.0 hub) int sv1[2]; if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv1) < 0) { printf("[-] Failed to socketpair 1: %s\n", strerror(errno)); exit(1); } printf("[+] socketpair 1 successful.\n"); char buf1[256]; // Format: port sockfd devid speed (2 = USB_SPEED_FULL) snprintf(buf1, sizeof(buf1), "0 %d 1 2", sv1[1]); if (write(attach_fd, buf1, strlen(buf1)) < 0) { printf("[-] Failed to write attach port 0: %s\n", strerror(errno)); exit(1); } printf("[+] write attach port 0 successful.\n"); // 2. Attach device to port 8 (USB 3.0 hub) int sv2[2]; if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv2) < 0) { printf("[-] Failed to socketpair 2: %s\n", strerror(errno)); exit(1); } printf("[+] socketpair 2 successful.\n"); char buf2[256]; // Format: port sockfd devid speed (5 = USB_SPEED_SUPER) // Note: vhci_hcd requires USB_SPEED_SUPER for ports >= 8 snprintf(buf2, sizeof(buf2), "8 %d 2 5", sv2[1]); if (write(attach_fd, buf2, strlen(buf2)) < 0) { printf("[-] Failed to write attach port 8: %s\n", strerror(errno)); exit(1); } printf("[+] write attach port 8 successful.\n"); if (close(attach_fd) < 0) { printf("[-] Failed to close attach_fd: %s\n", strerror(errno)); exit(1); } printf("[+] close attach_fd successful.\n"); // 3. Keep the sockets open but do NOT read or write any USBIP packets. // This will cause the kernel's URB to timeout, send a CMD_UNLINK, // and wait indefinitely for a RET_UNLINK, holding the address0_mutex. // The second device attach will then block forever trying to acquire // the same mutex, triggering the hung task timeout. printf("[+] Sleeping to allow hung task timeout to trigger...\n"); sleep(300); return 0; }