DF-3159 / trunc_step.c
/* * DF-3159 trigger: grow the file through ftruncate in steps so the kernel * zero-fill drains between steps, then one final ftruncate past * MSDOSFS_FILESIZE_MAX (0xFFFFFFFF). The final size 0x100010000 * (4 GiB + 64 KiB) truncates to 0x10000 in the 32-bit dirent field. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <fcntl.h> #include <unistd.h> #include <sys/stat.h> int main(int argc, char **argv) { const char *path = argv[1]; unsigned long long target = 0x100010000ULL, cur = 0, step = 64ULL<<20; int fd = open(path, O_RDWR); if (fd < 0) { perror("open"); return 2; } while (cur + step < target) { cur += step; if (ftruncate(fd, cur) < 0) { printf("ftruncate(%llu) FAILED %s\n", cur, strerror(errno)); return 1; } } printf("stepped to %llu; final ftruncate(0x%llx):\n", cur, target); fflush(stdout); if (ftruncate(fd, (off_t)target) < 0) { printf("final ftruncate FAILED errno=%d (%s)\n", errno, strerror(errno)); return 1; } struct stat st; fstat(fd, &st); printf("OK: in-memory size %jd (0x%jx) -- dirent field will store 0x%llx\n", (intmax_t)st.st_size, (uintmax_t)st.st_size, (unsigned long long)(target & 0xFFFFFFFFULL)); return 0; } |