// https://syzkaller.appspot.com/bug?id=4383f618da77d7caee6212ce8921a61f92ba95d7 #include #include #include #include #include #include #include #include void check_res(int res, const char *msg) { if (res < 0 && errno != EEXIST) { printf("[-] %s: %s\n", msg, strerror(errno)); exit(1); } } int main(void) { int res; res = mount("configfs", "/sys/kernel/config", "configfs", 0, NULL); if (res < 0 && errno != EBUSY) { printf("[-] Failed to mount configfs: %s\n", strerror(errno)); exit(1); } printf("[+] configfs mounted.\n"); res = mkdir("/sys/kernel/config/usb_gadget/g1", 0777); check_res(res, "Failed to mkdir g1"); res = mkdir("/sys/kernel/config/usb_gadget/g1/functions/uvc.0", 0777); check_res(res, "Failed to mkdir uvc.0"); res = mkdir("/sys/kernel/config/usb_gadget/g1/functions/uvc.0/streaming", 0777); check_res(res, "Failed to mkdir streaming"); res = mkdir("/sys/kernel/config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed", 0777); check_res(res, "Failed to mkdir uncompressed"); res = mkdir("/sys/kernel/config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u", 0777); check_res(res, "Failed to mkdir u"); // 1. frag_sem -> su_mutex res = mkdir("/sys/kernel/config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u/1080p", 0777); check_res(res, "Failed to mkdir 1080p"); int fd = open("/sys/kernel/config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u/1080p/dwFrameInterval", O_WRONLY); if (fd < 0) { printf("[-] Failed to open dwFrameInterval: %s\n", strerror(errno)); exit(1); } res = write(fd, "333333\n", 7); if (res < 0) { printf("[-] Failed to write dwFrameInterval: %s\n", strerror(errno)); } close(fd); printf("[+] Wrote to dwFrameInterval (frag_sem -> su_mutex).\n"); // 2. inode_lock -> frag_sem res = rmdir("/sys/kernel/config/usb_gadget/g1/functions/uvc.0/streaming/uncompressed/u/1080p"); if (res < 0) { printf("[-] Failed to rmdir 1080p: %s\n", strerror(errno)); exit(1); } printf("[+] Removed 1080p (inode_lock -> frag_sem).\n"); // 3. su_mutex -> opts->dep_lock res = mkdir("/sys/kernel/config/usb_gadget/g1/functions/tcm.0", 0777); check_res(res, "Failed to mkdir tcm.0"); printf("[+] Created tcm.0 (su_mutex -> opts->dep_lock).\n"); // 4. opts->dep_lock -> inode_lock mkdir("/sys/kernel/config/target", 0777); mkdir("/sys/kernel/config/target/usb_gadget", 0777); res = mkdir("/sys/kernel/config/target/usb_gadget/naa.123", 0777); if (res < 0 && errno != EEXIST) { printf("[-] Failed to mkdir naa.123: %s\n", strerror(errno)); } res = mkdir("/sys/kernel/config/target/usb_gadget/naa.123/tpgt_1", 0777); if (res < 0 && errno != EEXIST) { printf("[-] Failed to mkdir tpgt_1: %s\n", strerror(errno)); } else { printf("[+] Created tpgt_1 (opts->dep_lock -> inode_lock).\n"); } // Clean up rmdir("/sys/kernel/config/target/usb_gadget/naa.123/tpgt_1"); rmdir("/sys/kernel/config/target/usb_gadget/naa.123"); rmdir("/sys/kernel/config/usb_gadget/g1/functions/tcm.0"); printf("[+] Done.\n"); return 0; }