DragonFlyBSD Kernel Audit
DF-2737 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-2737",
  "status": "untested",
  "reproduced": 0,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Info defense-in-depth finding, proven statically: the dynamic-oid teardown drain at sys/kern/kern_sysctl.c:391-398 is dead code because nothing in the kernel ever increments struct sysctl_oid.oid_running (grep over the whole tree returns only the declaration in sys/sys/sysctl.h:168 and the read/tsleep at kern_sysctl.c:391-395). CTLFLAG_DYING is consequently never set and the KASSERT at kern_sysctl.c:1386/1395 can never fire. Actual handler-vs-teardown safety rests entirely on the pcpu SLOCK-across-handler protocol (userland_sysctl:1569-1578, kernel_sysctl:1274-1276 vs _sysctl_xlock over all cpus:1641-1651), which the race hammer (12 kldload/kldunload coretemp cycles vs 4245 unprivileged sysctl -aN walks) confirmed holds on the INVARIANTS guest with no panic and a fully drained sysctloid arena. No runtime trigger exists, so no standalone exploit PoC was warranted for this Info finding; the pack records the prober and race-hammer evidence for the whole-file negative result. fix.diff (git apply --check clean) wires the counter up in sysctl_root AND makes sysctl_find_oid return ENOENT for DYING nodes so the drain cannot itself introduce the INVARIANTS panic race its comment's mechanism would otherwise enable.",
  "exploit_chain": "",
  "evidence": [
    "rg -n oid_running sys/  ->  only sys/sys/sysctl.h:168 and sys/kern/kern_sysctl.c:391,393,395: no increment/decrement anywhere",
    "findings/poc/DF-2737/race_hammer.txt: 12 coretemp load/unload cycles vs 4245 unpriv sysctl -aN walks, guest up, vmstat -m sysctloid drained",
    "findings/poc/DF-2737/run_user_prober.log: adversarial oldlenp/name2oid/oidfmt/truncation matrix, no panic on INVARIANTS kernel",
    "sys/kern/lwkt_thread.c:340: lockinit(&gd->gd_sysctllock, ..., LK_CANRECURSE) legitimizes the recursive XLOCK at kern_sysctl.c:383/241"
  ],
  "kernel_refs": [
    "sys/kern/kern_sysctl.c:391",
    "sys/kern/kern_sysctl.c:1386",
    "sys/kern/kern_sysctl.c:1569",
    "sys/kern/kern_sysctl.c:1641",
    "sys/sys/sysctl.h:168"
  ],
  "poc_changes": "n/a (prober authored fresh for this pass-2 run; no seed PoC existed)",
  "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": 210,
  "guest_dirty": 0,
  "build_cmd": "cc -O -o /tmp/prober /tmp/prober.c",
  "run_cmd": "/tmp/prober   (unprivileged user maxx)",
  "code_hash": "a5a9b4c2b7b560bb76a39f9bc2e5acb97c5d553c1474bf0c68aa90f1004b59ea",
  "notes": "Info-severity: no Phase V exploit run warranted (contract skips Low/Info). Guest left clean (temp files removed, modules unloaded, no reset needed). The pack doubles as the negative-result record for the pass-2 audit of sys/kern/kern_sysctl.c; see VERDICT.md section 'Negative results' for the seven candidate classes killed with path:line citations.",
  "recommended_fix": "Wire up oid_running in sysctl_root (atomic inc/dec + wakeup around handler invocation) and make sysctl_find_oid return ENOENT for CTLFLAG_DYING nodes instead of KASSERTing - see fix.diff",
  "fix_status": "not_testable",
  "fix_kernel_uname": "",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Info/defense-in-depth finding with no runtime trigger, so no baseline bad behavior exists to observe disappearing; a kernel rebuild cycle was not warranted. fix.diff is git-apply-able (git apply --check clean) and was code-reviewed against sysctl_root/sysctl_find_oid, including the mandatory DYING->ENOENT companion hunk without which wiring the counter would make the KASSERT at kern_sysctl.c:1386 raceable to panic.",
  "fix_evidence": ["findings/poc/DF-2737/fix.diff (git apply --check: APPLIES-CLEAN)"]
}