⬢ DragonFlyBSD Kernel Audit
DF-5120 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-5120",
  "status": "untested",
  "verdict": "Mechanism code-certain: vtrnd_harvest() calls virtqueue_poll() (virtio_random.c:215), which is an unbounded busy-wait (virtqueue.c:578-579), from the periodic 5s softclock callout (virtio_random.c:142,229). If the host entropy backend never advances the used ring (stalling EGD chardev, wedged vhost backend, out-of-band device reset), the softclock thread spins forever - permanent guest hang, no panic, no watchdog. Not reproduced: the audit guest has no virtio-rng device (vm.sh attaches only virtio-blk/virtio-net) and the trigger is host-side fault injection, outside the guest-attacker model; filed as Low hardening/robustness.",
  "reproduced": false,
  "impact": "none",
  "confidence": "likely",
  "exploit_chain": "",
  "evidence": "README.md (mechanism + trigger model); VERDICT.md (source trace virtio_random.c:142,205-215,229 and virtqueue.c:572-580; negative results incl. callout_terminate sync semantics kern_timeout.c:1041-1075 killing the detach-UAF hypothesis); fix.diff (bounded ~10ms wait, degrades to no-harvest via the existing virtqueue_empty() gate); guest dmesg shows no vtrnd (only vtnet0/vtblk0)",
  "kernel_refs": [
    "sys/dev/virtual/virtio/random/virtio_random.c:215",
    "sys/dev/virtual/virtio/random/virtio_random.c:142",
    "sys/dev/virtual/virtio/random/virtio_random.c:229",
    "sys/dev/virtual/virtio/virtio/virtqueue.c:578"
  ],
  "poc_changes": "No runnable PoC authored: trigger is host-side (stalled entropy backend), not guest-local; the audit guest lacks a virtio-rng device entirely.",
  "attempts": 0,
  "guest_uname": "DragonFly dfbsd 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": 0,
  "guest_dirty": 0,
  "build_cmd": "",
  "run_cmd": "",
  "code_hash": "",
  "notes": "Guest untouched (read-only probes). Virtio threat model treats the host as trusted - not guest-attacker-reachable; severity Low. Related negative results in VERDICT.md cover the OOB/size hunt item (sglist 1x4 bytes bounded, used-ring length ignored via NULL len), attach unwind, callout/detach UAF (killed by synchronous callout_terminate), entropy source indexing (all masked to 256-entry arrays), and module state. Side observation for a future kern_nrandom.c audit: add_buffer_randomness_src() mis-splits buffers >256 bytes (passes full remaining length while advancing by 256), unreachable from vtrnd (always 4 bytes).",
  "recommended_fix": "Bound the poll in vtrnd_harvest() (~10ms via virtqueue_pending()+DELAY loop); on timeout return with the descriptor still queued so the existing virtqueue_empty() gate permanently disables harvest instead of hanging softclock",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": false,
  "fix_patched_reproduced": false,
  "fix_verdict": "Fix kernel not built/run: the finding is unverified Low severity, the guest has no virtio-rng device, and the fault under test is host-side; the diff is minimal and confined to virtio_random.c (uses DELAY already declared in sys/systm.h).",
  "fix_evidence": "fix.diff"
}