// https://syzkaller.appspot.com/bug?id=902cef233ea1783f126435e47d22a10593f19c4f #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef IOPRIO_WHO_PROCESS #define IOPRIO_WHO_PROCESS 1 #endif #ifndef IOPRIO_CLASS_BE #define IOPRIO_CLASS_BE 2 #endif void setup_env() { int fd = open("/proc/sys/kernel/core_pattern", O_WRONLY); if (fd >= 0) { if (write(fd, "core", 4) != 4) { printf("[-] Failed to write to core_pattern: %s\n", strerror(errno)); } close(fd); } int fd2 = open("/proc/sys/kernel/core_uses_pid", O_WRONLY); if (fd2 >= 0) { if (write(fd2, "0", 1) != 1) { printf("[-] Failed to write to core_uses_pid: %s\n", strerror(errno)); } close(fd2); } if (mkdir("/tmp/coredump", 0777) < 0 && errno != EEXIST) { printf("[-] Failed to mkdir /tmp/coredump: %s\n", strerror(errno)); exit(1); } if (mount("tmpfs", "/tmp/coredump", "tmpfs", 0, "size=200M") < 0) { printf("[-] Failed to mount tmpfs: %s\n", strerror(errno)); exit(1); } if (chdir("/tmp/coredump") < 0) { printf("[-] Failed to chdir to /tmp/coredump: %s\n", strerror(errno)); exit(1); } printf("[+] Environment setup successful.\n"); } int main() { setvbuf(stdout, NULL, _IONBF, 0); setup_env(); printf("[+] Starting Phase 1: Core dump method...\n"); for (int i = 0; i < 1000; i++) { int sync_pipe[2]; if (pipe(sync_pipe) < 0) { printf("[-] Failed to pipe: %s\n", strerror(errno)); exit(1); } pid_t pid = fork(); if (pid < 0) { printf("[-] Failed to fork: %s\n", strerror(errno)); exit(1); } if (pid == 0) { close(sync_pipe[0]); struct rlimit core_limit; core_limit.rlim_cur = RLIM_INFINITY; core_limit.rlim_max = RLIM_INFINITY; if (setrlimit(RLIMIT_CORE, &core_limit) < 0) { printf("[-] Failed to setrlimit: %s\n", strerror(errno)); exit(1); } size_t size = 20 * 1024 * 1024; void *ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (ptr != MAP_FAILED) { memset(ptr, 1, size); } else { printf("[-] Failed to mmap: %s\n", strerror(errno)); exit(1); } if (write(sync_pipe[1], "x", 1) != 1) { printf("[-] Failed to write to sync_pipe: %s\n", strerror(errno)); exit(1); } *((volatile int *)0) = 0; exit(1); } else { close(sync_pipe[1]); char c; if (read(sync_pipe[0], &c, 1) == 1) { long sleep_ns = (i % 100) * 100000; struct timespec req = {0, sleep_ns}; nanosleep(&req, NULL); int ioprio = (IOPRIO_CLASS_BE << 13) | 0; syscall(SYS_ioprio_set, IOPRIO_WHO_PROCESS, pid, ioprio); } waitpid(pid, NULL, 0); close(sync_pipe[0]); unlink("core"); } } printf("[+] Phase 1 successful.\n"); printf("[+] Starting Phase 2: Pipe write method...\n"); for (int i = 0; i < 10000; i++) { int sync_pipe[2]; if (pipe(sync_pipe) < 0) { printf("[-] Failed to pipe: %s\n", strerror(errno)); exit(1); } pid_t pid = fork(); if (pid < 0) { printf("[-] Failed to fork: %s\n", strerror(errno)); exit(1); } if (pid == 0) { close(sync_pipe[0]); int pipefd[2]; if (pipe(pipefd) < 0) { printf("[-] Failed to pipe: %s\n", strerror(errno)); exit(1); } fcntl(pipefd[1], F_SETFL, O_NONBLOCK); if (write(sync_pipe[1], "x", 1) != 1) { printf("[-] Failed to write to sync_pipe: %s\n", strerror(errno)); exit(1); } char c = 'a'; while (1) { write(pipefd[1], &c, 1); } } else { close(sync_pipe[1]); char c; if (read(sync_pipe[0], &c, 1) == 1) { for (volatile int d = 0; d < (i % 1000); d++) {} int ioprio = (IOPRIO_CLASS_BE << 13) | 0; syscall(SYS_ioprio_set, IOPRIO_WHO_PROCESS, pid, ioprio); usleep(10); } kill(pid, SIGKILL); waitpid(pid, NULL, 0); close(sync_pipe[0]); } } printf("[+] Phase 2 successful.\n"); return 0; }