// https://syzkaller.appspot.com/bug?id=5ad3dc0db2152702bfdc671e6fad58df70304c6b #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #ifndef __NR_memfd_create #define __NR_memfd_create 319 #endif static inline int sys_memfd_create(const char *name, unsigned int flags) { return syscall(__NR_memfd_create, name, flags); } int fd; void *write_worker(void *arg) { char buf[4096]; memset(buf, 0x42, sizeof(buf)); for (int i = 0; i < 50000; i++) { if (pwrite(fd, buf, sizeof(buf), 0) < 0) { break; } } return NULL; } void *fsync_worker(void *arg) { for (int i = 0; i < 50000; i++) { if (fsync(fd) < 0) { break; } } return NULL; } int main() { setvbuf(stdout, NULL, _IONBF, 0); printf("[*] Starting reproducer...\n"); int backing_fd = sys_memfd_create("backing", 0); if (backing_fd < 0) { backing_fd = open("backing_file", O_RDWR | O_CREAT | O_TRUNC, 0644); if (backing_fd < 0) { printf("[-] Failed to open backing: %s\n", strerror(errno)); exit(1); } } if (ftruncate(backing_fd, 4096) < 0) { printf("[-] Failed to ftruncate: %s\n", strerror(errno)); exit(1); } printf("[+] Backing file created.\n"); int loop_ctl = open("/dev/loop-control", O_RDWR); if (loop_ctl < 0) { printf("[-] Failed to open loop-control: %s\n", strerror(errno)); exit(1); } int loop_num = ioctl(loop_ctl, LOOP_CTL_GET_FREE); if (loop_num < 0) { printf("[-] Failed to ioctl LOOP_CTL_GET_FREE: %s\n", strerror(errno)); exit(1); } char loop_name[64]; sprintf(loop_name, "/dev/loop%d", loop_num); int loop_fd = open(loop_name, O_RDWR); if (loop_fd < 0) { printf("[-] Failed to open loop device: %s\n", strerror(errno)); exit(1); } printf("[+] Loop device %s opened.\n", loop_name); if (ioctl(loop_fd, LOOP_SET_FD, backing_fd) < 0) { printf("[-] Failed to ioctl LOOP_SET_FD: %s\n", strerror(errno)); exit(1); } printf("[+] Loop device bound to backing file.\n"); fd = open(loop_name, O_RDWR | O_SYNC); if (fd < 0) { printf("[-] Failed to open loop device O_SYNC: %s\n", strerror(errno)); exit(1); } printf("[+] Loop device opened with O_SYNC.\n"); #define NUM_THREADS 8 pthread_t threads[NUM_THREADS]; for (int i = 0; i < NUM_THREADS; i++) { if (i % 2 == 0) { if (pthread_create(&threads[i], NULL, write_worker, NULL) != 0) { printf("[-] Failed to create write thread\n"); exit(1); } } else { if (pthread_create(&threads[i], NULL, fsync_worker, NULL) != 0) { printf("[-] Failed to create fsync thread\n"); exit(1); } } } for (int i = 0; i < NUM_THREADS; i++) { pthread_join(threads[i], NULL); } printf("[+] Threads finished.\n"); ioctl(loop_fd, LOOP_CLR_FD); close(fd); close(loop_fd); close(loop_ctl); close(backing_fd); printf("[+] Done.\n"); return 0; }