⬢ DragonFlyBSD Kernel Audit
DF-3198 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-3198",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "panic",
  "confidence": "certain",
  "verdict": "devfs_rule_reset_node() calls devfs_gc() while devfs_iterate_topology() holds saved TAILQ cursors; devfs_gc frees arbitrary nodes (links to the target, empty dirs), so the walker revisits freed memory. With a rule-built chain L2->L1->null, DEVFS_RULE_RESET panicked deterministically: assertion node->link_target failed in devfs_rule_reset_node at devfs_rules.c:223 with the full stack through devfs_iterate_topology <- devfs_apply_reset_rules_caller. On non-INVARIANTS kernels the next statement is a write through the NULL link_target (low-page fault), and the stale ORPHANED/list state drives orphan-list and child-list corruption routed through freed memory.",
  "exploit_chain": "privileged (root, or jailed root via DF-3197) ioctl sequence: ADD LINK null->L1, ADD LINK L1->L2, APPLY *, RESET * -> devfs core thread frees L2 during L1s gc -> reset_node runs on freed L2 -> KKASSERT/NULL-page write; production kernels get list corruption through the freed chunk (double-unlink of orphaned nodes)",
  "evidence": [
    "panic.txt: assertion + full backtrace",
    "run.log: chain built then panic on RESET",
    "run.fixed.log: SURVIVED, links cleaned, guest up"
  ],
  "kernel_refs": [
    "sys/vfs/devfs/devfs_rules.c:222",
    "sys/vfs/devfs/devfs_rules.c:226",
    "sys/vfs/devfs/devfs_core.c:630",
    "sys/vfs/devfs/devfs_core.c:721",
    "sys/vfs/devfs/devfs_core.c:1912"
  ],
  "poc_changes": "none beyond compile fixes (limits.h include)",
  "attempts": 1,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul  2 06:02:54 UTC 2026  root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC  x86_64",
  "runtime_sec": 8,
  "guest_dirty": 1,
  "build_cmd": "cc -static -O -o uaf_reset uaf_reset.c",
  "run_cmd": "./uaf_reset",
  "code_hash": "a4b660fb090e0bffd8385f3516b7675aa12d60c3c88cd57586156a0f0f372a73",
  "notes": "trigger is privileged; combined with DF-3197 it is a jailed-root -> host-kernel-corruption path. memcorrupt bucket.",
  "recommended_fix": "two-pass reset: unlink+collect rule-created links during the walk, free (gc_links + freep + one gc_dirs sweep) only after it",
  "fix_status": "fixed",
  "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #1: Tue Sep  8 10:25:07 UTC 2026  root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC  x86_64",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "same PoC on the fixed kernel: SURVIVED, /dev/L1 and /dev/L2 removed by the reset, tree consistent, guest stayed up",
  "fix_evidence": [
    "DF-3198/run.fixed.log"
  ]
}