β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-4745

am79900_start_locked lacks the upstream 'break' after detecting a LANCE-owned TMD: the driver dequeues an mbuf and overwrites the chip-owned descriptor and TX buffer on a ring desync

Summary

When the next TMD still has LE_T1_OWN set the code sets OACTIVE and logs 'missing buffer' but falls through to ifq_dequeue+lance_put, overwriting the descriptor/buffer the LANCE still owns - NetBSD upstream has break; there (diff-verified, dropped in the 2006 FreeBSD import). Twin at am7990.c:503. Writes stay inside the 32K shared DMA region: mangled-frame TX + BUFF-error watchdog loop (interface hang/DoS), mbuf consumed and lost. pcn(4) normally wins the probe on GENERIC. One-line break fix (both files). [VERIFIED pass2: missing break line-confirmed vs NetBSD; real emulated pcnet under 29693 TX in 2 flood rounds never hit chip-owned-TMD precondition; real-HW watchdog ceiling]

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-4745 Β· 7 files
FileTypeDescriptionSize
README.md β€” 531 B ↓ raw
VERDICT.md β€” 1.9 KB ↓ raw
env.txt β€” 309 B view raw
fix.diff β€” 450 B view raw
manifest.json β€” 761 B view raw
run.log β€” 449 B view raw
verdict.json β€” 2.2 KB view raw

DF-4745 - am79900_start_locked missing break after OWN check

QEMU_EXTRA='-device pcnet,netdev=n1 -netdev user,id=n1' ./vm.sh up (lnc0 attaches natively; 16 RX/4 TX buffers). ifconfig lnc0 192.168.77.1/24 up; 8x ping -f -s 1472. Observed: 29,693 TX packets, 0 oerrors, zero 'missing buffer' lines - emulated chip never lags. Code-certain vs NetBSD upstream break; real-hardware watchdog/DoS ceiling.

Kernel: 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

VERDICT.md
↓ download raw

DF-4745 - VERDICT

status: not_reproduced | reproduced: 0 | impact: none | confidence: certain

Line-accurate confirmation + real-driver exercise, no desync on emulated hardware. am79900.c:538-544: when the next TMD still has LE_T1_OWN the code sets OACTIVE and prints 'missing buffer' but has NO break - the upstream NetBSD code breaks there (diff-verified; dropped in the 2006 FreeBSD import) - so control falls through to ifq_dequeue+lance_put, consuming the mbuf and overwriting the descriptor/buffer the LANCE still owns. On the guest, the real driver ran against real emulated hardware: QEMU pcnet (1022:2000) attaches lnc0 natively (16 RX/4 TX buffers) and two flood rounds (4 then 8 concurrent ping floods, 1472-byte frames, 29,693 output packets total) produced ZERO 'missing buffer' log lines, 0 oerrors, no watchdog - the QEMU pcnet backend completes TX so fast the chip-owned-TMD precondition never arises under load. The defect is code-certain (verifiable against upstream); impact ceiling on real hardware is a mangled-TX/watchdog interface hang (all writes stay inside the 32K shared DMA region). pcn(4) normally wins the probe on GENERIC; lnc(4) is compiled into the stock kernel (attached here without kldload).

Kernel references

Evidence

run.log (lnc0 attach lines, netstat -I lnc0 counters after floods, zero 'missing buffer'), source excerpt :538-544

add the missing 'break;' after the if_printf in both am79900.c:544 and am7990.c:503.

Fix status (batch validation)

Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.

Fix verification

not_testable
↓ fix.diffper-fix-DF-4745

Confirmed kernel references

Detail

Evidence (decisive lines)

run.log (lnc0 attach lines, netstat -I lnc0 counters after floods, zero 'missing buffer'), source excerpt :538-544

PoC changes

none (driver ran as shipped; QEMU pcnet used as the real device)

Verified recommended fix

add the missing 'break;' after the if_printf in both am79900.c:544 and am7990.c:503.

Verdict

Line-accurate confirmation + real-driver exercise, no desync on emulated hardware. am79900.c:538-544: when the next TMD still has LE_T1_OWN the code sets OACTIVE and prints 'missing buffer' but has NO break - the upstream NetBSD code breaks there (diff-verified; dropped in the 2006 FreeBSD import) - so control falls through to ifq_dequeue+lance_put, consuming the mbuf and overwriting the descriptor/buffer the LANCE still owns. On the guest, the real driver ran against real emulated hardware: QEMU pcnet (1022:2000) attaches lnc0 natively (16 RX/4 TX buffers) and two flood rounds (4 then 8 concurrent ping floods, 1472-byte frames, 29,693 output packets total) produced ZERO 'missing buffer' log lines, 0 oerrors, no watchdog - the QEMU pcnet backend completes TX so fast the chip-owned-TMD precondition never arises under load. The defect is code-certain (verifiable against upstream); impact ceiling on real hardware is a mangled-TX/watchdog interface hang (all writes stay inside the 32K shared DMA region). pcn(4) normally wins the probe on GENERIC; lnc(4) is compiled into the stock kernel (attached here without kldload).