⬢ DragonFlyBSD Kernel Audit
DF-3394 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-3394",
  "status": "not_reproduced",
  "reproduced": 0,
  "impact": "none",
  "confidence": "likely",
  "verdict": "Race confirmed at source level (unprivileged SIOCGIFMEDIA on vlan uses a raw, unpinned parent ifnet pointer across a serializer drop at if_vlan.c:951-961 while the parent free path (tapdestroy kfree, if_tap.c:495) holds nothing), but 10 minutes of multi-variant stress on a 6-CPU guest (8.5M fast + 200k cold-page-faulted queries vs ~130k parent create/config/destroy cycles) produced no observable panic or INVARIANTS trip: the freed tap_softc slab is immediately re-allocated by the churns next tap create, so the UAF reads recycled-but-valid memory silently. Filed as a real, hard-to-win UAF race; impact ceiling is an indirect call through freed kernel memory (privileged co-trigger required for the free side).",
  "exploit_chain": "",
  "evidence": [
    "VERDICT.md \u2014 line-level race analysis: if_vlan.c:951 read / :957 lock drop / :959-961 use; tapdestroy free with no exclusion (if_tap.c:472-495)",
    "race_query2.c \u2014 cold file-backed ifm_ulist stretches the in-parent-ioctl window ~1000x via copyout page faults",
    "run.log \u2014 stress numbers, zero panics across 4 runs"
  ],
  "kernel_refs": [
    "sys/net/vlan/if_vlan.c:951",
    "sys/net/vlan/if_vlan.c:959",
    "sys/net/vlan/if_vlan.c:960",
    "sys/net/vlan/if_vlan.c:965",
    "sys/net/tap/if_tap.c:495",
    "sys/net/if.c:958",
    "sys/net/if.c:2364"
  ],
  "poc_changes": "Seed sketch rewritten entirely: v1 plain SIOCGIFMEDIA hammer; v2 added cold file-backed ifm_ulist (mmap+ftruncate+MADV_DONTNEED cycling) to park the thread inside the parents if_ioctl via copyout faults; churner needed <net/ethernet.h> include for if_vlan_var.h and kldload if_tap on the guest.",
  "attempts": 4,
  "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": 660,
  "guest_dirty": 1,
  "build_cmd": "cc -O2 -o race_query race_query.c; cc -O2 -o race_query2 race_query2.c; cc -O2 -o race_churn race_churn.c",
  "run_cmd": "/tmp/race_query vlan0 & /tmp/race_query2 vlan0 & /tmp/race_churn 120",
  "code_hash": "304b33ff1e11e24ed32d1389211a8cb3966456836a15f8a28e88fff45f6c8187",
  "notes": "Guest left dirty (tap module loaded, vlan0 present); no panic occurred so no reset required before next spawn, but a reset-with-src is recommended. ifnet refcounting (if_ref/if_rele) does not exist on DragonFly; this race class is systemic wherever one ifnet caches a raw pointer to another.",
  "recommended_fix": "Serialize the parent media query on netisr0 (where vlan config/unconfig runs) or add ifnet refcount acquisition before the outcall at if_vlan.c:959.",
  "fix_status": "not_testable",
  "fix_kernel_uname": "",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff authored (netisr0-serialization comment + intent) but kernel rebuild not performed: baseline itself did not reproduce, so post-fix delta is not observable.",
  "fix_evidence": "fix.diff"
}