{
  "finding_id": "DF-2210",
  "status": "reproduced",
  "reproduced": true,
  "impact": "panic",
  "confidence": "certain",
  "privesc_candidate": false,
  "verdict": "Reproduced on the stock INVARIANTS guest with the production-handler KLD dispatch rig: the production chipsets/ata-national.c compiled verbatim into the rig (sha256 checker-verified against the audited sys/ tree) AND the running kernel own shipped handler dispatched by address (nm-local-symbol 0xffffffff80321780) both execute ata_national_setmode line 77 with ch->dma == NULL - the exact state ata-dma.c:151-154 leaves after DMA allocation fails (channel continues PIO-only). Result: Fatal trap 12 page fault while in kernel mode, fault virtual address 0x58 = offsetof(struct ata_dma, alignment), supervisor WRITE data, Stopped at ata_national_setmode+0x65: movl $0x10,0x58(%rax) - the store of the constant 16 through the NULL ch->dma, i.e. precisely cited line 77 (next store movl $0x8000,0x64(%rax) is line 78). Guest dead at db> prompt, ssh gone. Controls with ch->dma present complete the identical production path faithfully (dma defaults 2/65536 overridden to 16/32768, real kernel ata_controlcmd/ata_queue_request run via the ATA_STALL_QUEUE synchronous CONTROL completion, PCI timing writes match the production tables to the digit: piotiming[4]=0x00100010, udmatiming[2]=0x80911030, mode=PIO4/UDMA2). Reachability on real hardware is every setmode funnel: boot reinit and IOCATASMODE ioctl (ata-all.c:523-526) and acd_open (atapi-cd.c:147) all funnel into ata_pcichannel_setmode (ata-pci.c:855-866) whose first act is ctlr->setmode(dev, ATA_PIO_MAX). Impact ceiling: deterministic local kernel panic / DoS - the write is a constant-only NULL-page write at fixed offsets (page 0 is unmappable on amd64), no escalation path. Single-fix kernel (if (ch->dma) guard around the two stores, mirroring the Cyrix twin guard at ata-cyrix.c:82) makes the identical dispatch RETURN with PIO setmode completing normally and leaves all dma-present controls bit-identical to stock.",
  "exploit_chain": "None - NULL-page WRITE of fixed constants (16 at +0x58, 32768 at +0x64) through a NULL ch->dma; the first page is hard-unmappable on amd64, so the primitive is a guaranteed kernel panic (local DoS), not controllable memory corruption and not an escalation candidate.",
  "evidence": "panic.txt: go1 serial console - BEFORE dispatch ch->dma=0 marker, then Fatal trap 12, fault virtual address 0x58, supervisor write data, Stopped at ata_national_setmode+0x65: movl $0x10,0x58(%rax). panic_rig_copy.txt: identical panic from the verbatim #included copy (go3). kernel_handler_disasm.txt: stock kernel objdump attributing +0x65 to the line-77 store and +0x73 to line 78. run_control.log: dma-present controls with production timing-table values. fix_run.log: same scenarios on the patched kernel all RETURN, controls bit-identical. fixed_handler_disasm.txt: test rax,rax / je guard in the patched binary. build.baseline.log: checker sha match c694b909... proving the verbatim compile.",
  "kernel_refs": [
    "sys/dev/disk/nata/chipsets/ata-national.c:77",
    "sys/dev/disk/nata/chipsets/ata-national.c:78",
    "sys/dev/disk/nata/ata-dma.c:151",
    "sys/dev/disk/nata/ata-dma.c:153",
    "sys/dev/disk/nata/ata-pci.c:855",
    "sys/dev/disk/nata/ata-pci.c:863",
    "sys/dev/disk/nata/ata-all.c:523",
    "sys/dev/disk/nata/ata-queue.c:100",
    "sys/dev/disk/nata/chipsets/ata-cyrix.c:82",
    "sys/dev/disk/nata/atapi-cd.c:147"
  ],
  "poc_changes": "No seed PoC existed (empty pack); built from scratch. Design iteration: the first attempt defined an interposed ata_controlcmd seam, which made the RUNNING-KERNEL dispatch hang (the kernel own ata_controlcmd binds to the kernel own ata_queue_request, which tsleeps on the fabricated channel); replaced by the faithful channel-state fabrication - ATA_STALL_QUEUE state plus hw.begin_transaction returning ATA_OP_FINISHED - which lets the kernel own production ata_controlcmd and ata_queue_request run and complete synchronously (ata-queue.c:100-115).",
  "attempts": 3,
  "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": 3300,
  "guest_dirty": 0,
  "build_cmd": "cd /root/dfrig_nat && sh build.sh   (make -m /usr/src/share/mk; kldload ./dfrig_nat.ko)",
  "run_cmd": "sysctl -w kern.dfrig_nat.addr=0x$(nm /boot/kernel/kernel | awk \"/ t ata_national_setmode$/{print $1}\"); sysctl -w kern.dfrig_nat.go=2 (control); sysctl -w kern.dfrig_nat.go=1 (fatal on stock kernel)",
  "code_hash": "58b79c1b282ac06b65ff65b39ed7aa683c6bd1bf9d61e405b6cff41429507e27",
  "notes": "Hardware-gated (National Geode SC1100, PCI ID 0x0502100b); established production-handler KLD dispatch rig class (DF-252x trm, DF-249x nata). Both dispatch routes panic identically at ata-national.c:77. New team directive assessed: NOT a privesc candidate - constant-only NULL-page write, page 0 unmappable on amd64.",
  "recommended_fix": "Guard the two stores with if (ch->dma) { ch->dma->alignment = 16; ch->dma->max_iosize = 64 * DEV_BSIZE; } - the same protection the Cyrix twin carries at ata-cyrix.c:82.",
  "fix_status": "fixed",
  "fix_validated": 1,
  "fix_diff": "findings/poc/DF-2210/fix.diff",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #1: Sat Oct 17 08:46:06 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64",
  "fix_verdict": "Applied fix.diff inside the guest /usr/src, rebuilt with make -j6 nativekernel KERNCONF=X86_64_GENERIC + installkernel (fix_build.log, kernel sha256 d578088322657bb02e15787837bad2582c89869a8cf55af1f7c5208c1795a075), rebooted, rebuilt the rig from the patched source, and re-ran the exact scenarios: the dispatch that panicked the stock kernel (kernel own handler, ch->dma=NULL) now RETURNS with PIO setmode completing normally (atadev->mode=0x0c, SETXFER accepted through the real kernel ata_controlcmd, PCI timings written); the full extracted call site completes both calls including the UDMA2 pass; all dma-present controls remain bit-identical to stock (alignment 16, max_iosize 32768, same timing-table writes). Patched binary shows the guard: test rax,rax / je before both stores.",
  "fix_evidence": "fix_run.log: dfrig_nat[go1] RETURNED (no panic) with ch->dma=0, mode set, pci writes recorded - versus panic.txt on stock: fatal trap 12 vad 0x58 at ata_national_setmode+0x65. fixed_handler_disasm.txt vs kernel_handler_disasm.txt: unguarded stores vs test-and-skip."
}
