// https://syzkaller.appspot.com/bug?id=200bb9760ce13c0860408206552a9cafd4b5eb0f #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef SYS_memfd_create #if defined(__x86_64__) #define SYS_memfd_create 319 #elif defined(__i386__) #define SYS_memfd_create 356 #elif defined(__aarch64__) #define SYS_memfd_create 279 #elif defined(__arm__) #define SYS_memfd_create 385 #else #define SYS_memfd_create 319 #endif #endif int make_fat12() { int fd = syscall(SYS_memfd_create, "fat_img", 0); if (fd < 0) { printf("[-] memfd_create failed: %s\n", strerror(errno)); exit(1); } uint8_t boot[512] = {0}; boot[0] = 0xeb; boot[1] = 0x3c; boot[2] = 0x90; memcpy(&boot[3], "MSDOS5.0", 8); boot[11] = 0x00; boot[12] = 0x02; // 512 bytes per sector boot[13] = 1; // 1 sector per cluster boot[14] = 1; boot[15] = 0; // 1 reserved sector boot[16] = 1; // 1 FAT boot[17] = 0x00; boot[18] = 0x02; // 512 root dir entries boot[19] = 0x00; boot[20] = 0x04; // 1024 total sectors boot[21] = 0xf8; // media boot[22] = 4; boot[23] = 0; // 4 sectors per FAT boot[24] = 0x20; boot[25] = 0x00; // 32 sectors per track boot[26] = 0x40; boot[27] = 0x00; // 64 heads boot[36] = 0x80; // drive number boot[38] = 0x29; // extended boot signature boot[39] = 0x12; boot[40] = 0x34; boot[41] = 0x56; boot[42] = 0x78; // volume ID memcpy(&boot[43], "NO NAME ", 11); memcpy(&boot[54], "FAT12 ", 8); boot[510] = 0x55; boot[511] = 0xaa; if (write(fd, boot, 512) != 512) { printf("[-] write boot failed: %s\n", strerror(errno)); exit(1); } uint8_t fat[2048] = {0}; fat[0] = 0xf8; fat[1] = 0xff; fat[2] = 0xff; // FAT12 media and EOF markers if (write(fd, fat, 2048) != 2048) { printf("[-] write fat failed: %s\n", strerror(errno)); exit(1); } uint8_t root[16384] = {0}; if (write(fd, root, 16384) != 16384) { printf("[-] write root failed: %s\n", strerror(errno)); exit(1); } if (ftruncate(fd, 1024 * 512) < 0) { printf("[-] ftruncate failed: %s\n", strerror(errno)); exit(1); } printf("[+] make_fat12 successful.\n"); return fd; } int get_free_loop(char *loop_dev) { int ctl = open("/dev/loop-control", O_RDWR); if (ctl >= 0) { int devnr = ioctl(ctl, LOOP_CTL_GET_FREE); close(ctl); if (devnr >= 0) { sprintf(loop_dev, "/dev/loop%d", devnr); return devnr; } } for (int i = 0; i < 8; i++) { sprintf(loop_dev, "/dev/loop%d", i); int fd = open(loop_dev, O_RDWR); if (fd >= 0) { struct loop_info64 info; if (ioctl(fd, LOOP_GET_STATUS64, &info) < 0) { close(fd); return i; } close(fd); } } return -1; } struct thread_data { char filename[64]; void *buf; }; void *worker_write(void *arg) { struct thread_data *td = arg; int fd = open(td->filename, O_WRONLY); if (fd < 0) { printf("[-] open file for write failed: %s\n", strerror(errno)); return NULL; } while (1) { lseek(fd, 0, SEEK_SET); write(fd, td->buf, 4096); } return NULL; } void *worker_sync(void *arg) { struct thread_data *td = arg; int fd = open(td->filename, O_RDONLY); if (fd < 0) { printf("[-] open file for sync failed: %s\n", strerror(errno)); return NULL; } while (1) { fsync(fd); } return NULL; } int main() { setvbuf(stdout, NULL, _IONBF, 0); int file_fd = make_fat12(); char loop_dev[64]; if (get_free_loop(loop_dev) < 0) { printf("[-] Failed to find free loop device\n"); exit(1); } int loop_fd = open(loop_dev, O_RDWR); if (loop_fd < 0) { printf("[-] open loop_dev failed: %s\n", strerror(errno)); exit(1); } if (ioctl(loop_fd, LOOP_SET_FD, file_fd) < 0) { printf("[-] ioctl LOOP_SET_FD failed: %s\n", strerror(errno)); exit(1); } printf("[+] Loop device setup successful.\n"); close(loop_fd); if (mkdir("./mnt_dir", 0777) < 0 && errno != EEXIST) { printf("[-] mkdir ./mnt_dir failed: %s\n", strerror(errno)); exit(1); } int retries = 50; while (mount(loop_dev, "./mnt_dir", "vfat", 0, "flush") < 0) { if (--retries == 0) { printf("[-] mount failed: %s\n", strerror(errno)); exit(1); } usleep(100000); } printf("[+] Mount successful.\n"); pthread_t th_w[4], th_s[4]; struct thread_data td[4]; for (int i = 0; i < 4; i++) { sprintf(td[i].filename, "./mnt_dir/file%d", i); int fd = open(td[i].filename, O_WRONLY | O_CREAT, 0666); if (fd >= 0) close(fd); td[i].buf = mmap(NULL, 4096, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (td[i].buf == MAP_FAILED) { printf("[-] mmap failed: %s\n", strerror(errno)); exit(1); } pthread_create(&th_w[i], NULL, worker_write, &td[i]); pthread_create(&th_s[i], NULL, worker_sync, &td[i]); } sleep(5); return 0; }