// https://syzkaller.appspot.com/bug?id=1d7471f4d1f6143f5dbd28e5d985c5451e635b89 #define _GNU_SOURCE #include #include #include #include #include #include #include int main(void) { char fail_nth_path[256]; snprintf(fail_nth_path, sizeof(fail_nth_path), "/proc/self/task/%ld/fail-nth", syscall(SYS_gettid)); int fd_fail = open(fail_nth_path, O_WRONLY); if (fd_fail < 0) { printf("[-] Failed to open %s: %s\n", fail_nth_path, strerror(errno)); exit(1); } printf("[+] Opened fail-nth.\n"); int fd_new = open("/sys/bus/netdevsim/new_device", O_WRONLY); if (fd_new < 0) { printf("[-] Failed to open new_device: %s\n", strerror(errno)); exit(1); } printf("[+] Opened new_device.\n"); int fd_del = open("/sys/bus/netdevsim/del_device", O_WRONLY); if (fd_del < 0) { printf("[-] Failed to open del_device: %s\n", strerror(errno)); exit(1); } printf("[+] Opened del_device.\n"); for (int i = 1; i <= 200; i++) { char buf[32]; int len = snprintf(buf, sizeof(buf), "%d", i); // 1. Enable fault injection for the i-th allocation if (pwrite(fd_fail, buf, len, 0) != len) { // Might fail if fault injection is not fully configured, but we ignore } // 2. Try to create device 1. If the fault hits device_register(), // the error path will drop the nsim_bus_devs refcount to 0. pwrite(fd_new, "1 1 1", 5, 0); // 3. Disable fault injection pwrite(fd_fail, "0", 1, 0); // 4. Try to create device 2. If the refcount was dropped to 0 in step 2, // this successful allocation will increment it from 0, triggering the WARNING. pwrite(fd_new, "2 1 1", 5, 0); // 5. Cleanup both devices for the next iteration pwrite(fd_del, "1", 1, 0); pwrite(fd_del, "2", 1, 0); } close(fd_fail); close(fd_new); close(fd_del); printf("[+] Done.\n"); return 0; }