{
  "finding_id": "DF-4749",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Reproduced live on the DragonFly 6.5-DEVELOPMENT guest: pt_prison is never assigned (kmalloc M_ZERO, no writer anywhere; sole reference is the guard at nmdm.c:211), so the nmdm prison check is inert for unjailed users, degenerates to unconditional EBUSY-on-reopen for jailed users (same-jail reopen of /dev/nmdm0A failed Device busy while the jail itself held it), and never enforces pair<->prison affinity (unprivileged host user maxx successfully opened the jail-held half). Not memory-safety: pure logic/isolation defect; impact capped Low because direction 2 needs a jail devfs that exposes nmdm. Fix (pin pt_prison + prison_hold on first open) validated by rebuilding nmdm.ko on the guest and A/B-ing: post-fix same-jail reopen succeeds and cross-prison attach returns EBUSY.",
  "exploit_chain": "",
  "evidence": "run.log (pre-fix both directions: Part A inert guard, Part B same-jail EBUSY + unpriv host attach ok); jailtest_baseline.log (raw run, holder pid verified); fix_run.log (post-fix inversion, decisive lines open#1... = 3 [ok] inside jail and holder: open(/dev/nmdm0A) FAILED: Device busy for maxx); fix_build.log (patched module build)",
  "kernel_refs": [
    "sys/dev/misc/nmdm/nmdm.c:88",
    "sys/dev/misc/nmdm/nmdm.c:126",
    "sys/dev/misc/nmdm/nmdm.c:211",
    "sys/kern/kern_prot.c:1223",
    "sys/kern/kern_jail.c:154"
  ],
  "poc_changes": "Probe written fresh (open-matrix + holder); jailed side uses legacy jail(8) syntax `jail / name 127.0.0.1 cmd` since the guest jail(8) has no -c support; devfs note: jail path=/ shares host devfs.",
  "attempts": 3,
  "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": 240,
  "guest_dirty": 1,
  "build_cmd": "cc -O -Wall -o /tmp/nmdm_probe nmdm_probe.c && cc -O -o /tmp/holder holder.c",
  "run_cmd": "./run.sh",
  "code_hash": "f2539dc7ce9413f4d7e8b7448d770a0c06d6e781acf2afdf20c97d34b9a1e3f8",
  "notes": "prison_hold in fix bounded by 128 pairs max (nmdminit: n & ~0x7f). Direction-2 reachability requires jail devfs exposing nmdm (non-default); direction-1 (same-jail reopen broken) is unconditional for jails. Baseline module restored path: guest was reset after the run.",
  "recommended_fix": "Assign pt_prison (with prison_hold) on first open of a half in nmdmopen(), restoring the FreeBSD pty-heritage prison pinning.",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff applied to guest /usr/src copy, nmdm.ko rebuilt (fix_build.log), module swapped via kldunload/kldload, PoC re-run (fix_run.log): pre-fix buggy behaviors (same-jail EBUSY on open#1; unpriv host attach succeeding) are gone \u2014 post-fix same-jail open#1/#2 succeed and cross-prison attach returns Device busy.",
  "fix_evidence": "fix_run.log lines: open#1(/dev/nmdm0A) = 3 [ok, TS_ISOPEN set] (inside jail, holder holding) and holder: open(/dev/nmdm0A) FAILED: Device busy (as maxx, jail-held half)"
}