⬢ DragonFlyBSD Kernel Audit
DF-4750 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-4750",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Reproduced live as an unprivileged user on the DragonFly 6.5-DEVELOPMENT guest: after TIOCMSET(LE|DTR|RTS), TIOCCDTR leaves TIOCMGET=0x0002 \u2014 DTR (the bit that must be cleared) stays SET while LE and RTS are wiped, because nmdmioctl() line 565 ANDs with TIOCM_DTR instead of its complement. Functional/modem-state bug only (no memory safety: sys_ioctl pre-copies the ioctl data, sys/kern/sys_generic.c:679-697). Fix (&= ~TIOCM_DTR) validated in the same patched-module A/B cycle as DF-4749: post-fix TIOCMGET=0x0005, DTR cleared and RTS preserved.",
  "exploit_chain": "",
  "evidence": "run.log decisive line: TIOCMGET after TIOCCDTR = 0x0002 -> DTR=SET <-- BUG ... RTS=clear <-- BUG; fix_run.log decisive line: TIOCMGET after TIOCCDTR = 0x0005 -> DTR=clear [correct] RTS=SET [correct]",
  "kernel_refs": [
    "sys/dev/misc/nmdm/nmdm.c:564",
    "sys/dev/misc/nmdm/nmdm.c:565",
    "sys/dev/misc/nmdm/nmdm.c:606"
  ],
  "poc_changes": "Probe written fresh; shares the nmdm_probe binary with DF-4749 (TIOCM* section exercises this path).",
  "attempts": 2,
  "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": 60,
  "guest_dirty": 1,
  "build_cmd": "cc -O -Wall -o /tmp/nmdm_probe nmdm_probe.c",
  "run_cmd": "./run.sh",
  "code_hash": "f2539dc7ce9413f4d7e8b7448d770a0c06d6e781acf2afdf20c97d34b9a1e3f8",
  "notes": "Peer-side consequence: nmdm_crossover() recomputes CTS/CAR from RTS/DTR, so the stuck DTR keeps the peers carrier up \u2014 userland hangup-via-DTR never propagates.",
  "recommended_fix": "Change nmdm.c:565 to `ourpart->modemsignals &= ~TIOCM_DTR;`",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "One-character fix applied to guest /usr/src copy, nmdm.ko rebuilt (fix_build.log), swapped via kldunload/kldload, PoC re-run (fix_run.log): TIOCMGET after TIOCCDTR = 0x0005 \u2014 DTR cleared, RTS preserved; buggy 0x0002 behavior gone.",
  "fix_evidence": "fix_run.log: TIOCMGET after TIOCCDTR = 0x0005 -> DTR=clear [correct] RTS=SET [correct]"
}