DragonFlyBSD Kernel Audit
DF-0001 / manifest.json
← back to finding ↓ download raw
{
  "finding_id": "DF-0001",
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly v6.5.0.1712.g89e6a-DEVELOPMENT #1: Mon Jun 29 14:18:01 UTC 2026     root@ephemeral-5c2002c44b6c:/usr/obj/usr/src/sys/X86_64_GENERIC  x86_64",
  "code_hash": "5f4b556b078fdf0307551530c159117e37a02dcb04eee1debc946826b8d0bcb6",
  "tested_at": "2026-07-02T00:01:06Z",
  "verdict": "REPRODUCED",
  "impact": "panic",
  "confidence": "certain",
  "reproduce": {
    "build": "./build.sh",
    "run": "./run.sh",
    "expected": "panic: kern_ftruncate(): VOP_GETATTR didn't return 0 ; kern_ftruncate() at kern_ftruncate+0x152 ; guest halts in DDB (db> ). Requires vfs.quota_enabled=1 (loader tunable, reboot) + options INVARIANTS (present in X86_64_GENERIC) + an ESTALE-capable GETATTR (loopback NFS with server-side fd-handle invalidation). On a non-INVARIANTS kernel the KASSERT is a no-op and ftruncate(2) just returns the GETATTR error."
  },
  "kernel_refs": [
    "sys/kern/vfs_syscalls.c:4036",
    "sys/kern/vfs_syscalls.c:4038",
    "sys/kern/vfs_syscalls.c:4111",
    "sys/kern/vfs_syscalls.c:4113",
    "sys/sys/systm.h:94",
    "sys/sys/systm.h:117",
    "sys/kern/vfs_quota.c:112",
    "sys/vfs/nfs/nfs_vnops.c:737",
    "sys/vfs/nfs/nfsm_subs.h:109"
  ],
  "artifacts": [
    {"path": "estale_trig.c",  "type": "trigger-source",   "desc": "THE trigger that fires the panic: open fd -> server-side stale-FH invalidation -> ftruncate -> GETATTR ESTALE -> KASSERT"},
    {"path": "trunc_panic.c",  "type": "trigger-source",   "desc": "original reviewer PoC (path truncate), sharpened to print errnos and populate the target"},
    {"path": "trunc_only.c",   "type": "diagnostic",       "desc": "errno diagnostic proving dead-server GETATTR returns cached attrs (error=0) -> KASSERT not reached (negative evidence)"},
    {"path": "build.sh",       "type": "build-script",     "desc": "ships sources to guest + cc as unprivileged user maxx"},
    {"path": "run.sh",         "type": "run-script",       "desc": "full multi-step reproducer: quota reboot + loopback NFS + ESTALE handle invalidation -> panic"},
    {"path": "VERDICT.md",     "type": "verdict",          "desc": "full mechanism walkthrough: why dead-server doesn't fire but ESTALE does, path:line at every hop"},
    {"path": "README.md",      "type": "readme",           "desc": "human-facing build/run/preconditions + file index"},
    {"path": "fix.diff",       "type": "suggested-fix",    "desc": "git-apply-able: KASSERT -> proper error-return + cleanup (vn_unlock+goto done for ftruncate); applies cleanly to sys/kern/vfs_syscalls.c"},
    {"path": "panic.txt",      "type": "panic-signature",  "desc": "serial-console panic: kern_ftruncate(): VOP_GETATTR didn't return 0 at kern_ftruncate+0x152"},
    {"path": "run.log",        "type": "run-log",          "desc": "decisive confirmation run (fresh vm.sh reset), step-by-step, full output"},
    {"path": "boot.log.full",  "type": "serial-log",       "desc": "full untrimmed serial log of the panicking boot"},
    {"path": "build.log",      "type": "build-log",        "desc": "final successful build of estale_trig on guest"},
    {"path": "env.txt",        "type": "environment",      "desc": "uname, cc, quota default, INVARIANTS check (KASSERT strings in kernel binary)"},
    {"path": "manifest.json",  "type": "manifest",         "desc": "this catalog"}
  ]
}