⬢ DragonFlyBSD Kernel Audit
DF-5631 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-5631",
  "status": "untested",
  "verdict": "Latent dead-code API hazard, verified by full-tree static trace: kqueue_del() (sys/platform/vkernel64/platform/kqueue.c:157-169) has zero in-tree callers (only the definition and the md_var.h:133 prototype exist), so neither hazard is reachable today. If ever called, (1) the natural close(fd)-before-kqueue_del() teardown order deterministically panics the whole vkernel: the host auto-detaches the EVFILT_READ knote on last close, kevent(EV_DELETE) returns ENOENT, and kqueue.c:166 treats it as fatal; (2) kqueue_dels kfree at kqueue.c:168 races kqueue_intrs in-flight udata dispatch at kqueue.c:193 \u2014 kqueue_intr runs concurrently on any vCPU host thread (SIGIO process-directed via F_SETOWN/O_ASYNC at kqueue.c:84-87, direct call from the kqueuesig signal handler at exception.c:144-158 and from splz() at machintr.c:154-157), with no lock shared with kqueue_del, yielding a call through freed M_DEVBUF memory. Filed as Low/hardening so the first future caller does not trip it; no PoC can exist without modifying the read-only sys/ tree.",
  "reproduced": false,
  "impact": "none",
  "confidence": "likely",
  "exploit_chain": "",
  "evidence": "findings/poc/DF-5631/VERDICT.md (line-by-line trace of both hazards + the concurrency map); rg -n kqueue_del sys/ output showing zero callers (VERDICT.md); README.md cross-checks confirming DF-5537s double-add-benign claim from the owner side (console.c:114-117 guard under tp->t_token; ttymalloc caching at sys/kern/tty.c:2841-2855)",
  "kernel_refs": [
    "sys/platform/vkernel64/platform/kqueue.c:157",
    "sys/platform/vkernel64/platform/kqueue.c:164",
    "sys/platform/vkernel64/platform/kqueue.c:166",
    "sys/platform/vkernel64/platform/kqueue.c:168",
    "sys/platform/vkernel64/platform/kqueue.c:188",
    "sys/platform/vkernel64/platform/kqueue.c:193",
    "sys/platform/vkernel64/platform/kqueue.c:84",
    "sys/platform/vkernel64/x86_64/exception.c:144",
    "sys/platform/vkernel64/x86_64/exception.c:155",
    "sys/platform/vkernel64/platform/machintr.c:154",
    "sys/platform/vkernel64/platform/console.c:116",
    "sys/platform/vkernel64/include/md_var.h:133"
  ],
  "poc_changes": "none \u2014 no PoC built: the defective API has no callers anywhere in sys/, so there is no in-tree trigger; building one would require patching the read-only sys/ tree",
  "attempts": 0,
  "guest_uname": "",
  "runtime_sec": 0,
  "guest_dirty": 0,
  "build_cmd": "",
  "run_cmd": "",
  "code_hash": "",
  "notes": "Pass-2 audit of sys/platform/vkernel64/platform/kqueue.c (196 LOC). Single shared KQueueFd lifecycle verified sound: init_kqueue (init.c:449) runs after cpu_disable_intr (init.c:443) blocks SIGIO and before init_exceptions (init.c:494) installs kqueuesig, so no unhandled-SIGIO window; KQueueFd is never closed in-tree. kqueue_intr loop verified safe: kevary[8] bounded by host kevent nevents=8, n==-1 skips dispatch and exits do-while (kqueue.c:187-195), spurious wakeups exit with n==0, concurrent multi-vCPU dispatch is safe today because the sole target vcons_hardintr (console.c:203-209) is an atomic-bit leaf. signalintr deferral verified sound: both entry paths hold a critical section, so signalintr always defers via gd_fpending+RQF_INTPEND+umtx_wakeup (machintr.c:174-177) drained at machintr.c:144-148. DF-5537 cross-check CONFIRMED from owner side: ttymalloc caches dev->si_tty under tty_token (tty.c:2841-2855) so the kqueue_console_info NULL-guard serializes under tp->t_token \u2014 single EV_ADD, benign. systimer.cs kqueue_addTimer reference is #if 0d (systimer.c:183-186) matching kqueue.cs #if 0 timer block \u2014 vktimer uses a cothread instead. init_kqueues unchecked kqueue() return (kqueue.c:83; -1 under fd exhaustion \u2192 misleading panic at kqueue.c:85) noted as hardening, not filed: boot-time, operator-caused, fails loudly and safely. SIGIO deliverability on %gs=0 cothreads is the DF-5587/DF-5607 chain and is not re-filed.",
  "recommended_fix": "Tolerate ENOENT in kqueue_del (fd already closed => knote auto-detached) instead of panicking, and fence the kfree against in-flight kqueue_intr dispatch; see findings/poc/DF-5631/fix.diff",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": false,
  "fix_patched_reproduced": false,
  "fix_verdict": "fix validation not performed: the hazard has no in-tree trigger (kqueue_del has zero callers), so no baseline misbehavior can be reproduced without patching sys/; the fix.diff ENOENT-tolerance path is nonetheless deterministic-by-construction against host kqueue semantics",
  "fix_evidence": ""
}