// https://syzkaller.appspot.com/bug?id=c3860f2c815fb3dfde1ab6e7cee645a6f809a1ae #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #ifndef O_TMPFILE #define O_TMPFILE (020000000 | O_DIRECTORY) #endif int main(void) { int fd; int res; pid_t pid; printf("[*] Starting reproducer for sb_start_write hang\n"); fflush(stdout); /* Reduce hung task timeout to 15 seconds */ fd = open("/proc/sys/kernel/hung_task_timeout_secs", O_WRONLY); if (fd < 0) { printf("[-] Failed to open /proc/sys/kernel/hung_task_timeout_secs: %s\n", strerror(errno)); } else { res = write(fd, "15\n", 3); if (res < 0) { printf("[-] Failed to write to hung_task_timeout_secs: %s\n", strerror(errno)); } else { printf("[+] Reduced hung task timeout to 15 seconds.\n"); } close(fd); } fflush(stdout); fd = open("/", O_RDONLY | O_DIRECTORY); if (fd < 0) { printf("[-] Failed to open /: %s\n", strerror(errno)); exit(1); } printf("[+] open / successful.\n"); fflush(stdout); res = ioctl(fd, FIFREEZE, 0); if (res < 0) { printf("[-] Failed to ioctl FIFREEZE: %s\n", strerror(errno)); exit(1); } printf("[+] ioctl FIFREEZE successful.\n"); fflush(stdout); pid = fork(); if (pid < 0) { printf("[-] Failed to fork: %s\n", strerror(errno)); ioctl(fd, FITHAW, 0); exit(1); } if (pid == 0) { printf("[*] Child attempting to open O_TMPFILE on frozen fs...\n"); fflush(stdout); /* * Attempt to create an O_TMPFILE in the frozen root directory. * This will block in mnt_want_write -> sb_start_write. */ int tmp_fd = open("/", O_TMPFILE | O_WRONLY, 0666); if (tmp_fd < 0) { printf("[-] Child failed to open O_TMPFILE: %s\n", strerror(errno)); } else { printf("[+] Child open O_TMPFILE successful (unexpected).\n"); close(tmp_fd); } exit(0); } printf("[*] Parent waiting for hung task watchdog to trigger (sleeping 60s)...\n"); fflush(stdout); /* Sleep to allow the hung task watchdog to fire (>15s) */ sleep(60); printf("[*] Parent waking up, thawing filesystem...\n"); fflush(stdout); res = ioctl(fd, FITHAW, 0); if (res < 0) { printf("[-] Failed to ioctl FITHAW: %s\n", strerror(errno)); } else { printf("[+] ioctl FITHAW successful.\n"); } fflush(stdout); close(fd); printf("[+] Reproducer finished.\n"); return 0; }