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

Firmware-controlled NIC_CREATE_WQ response db_offset used unvalidated as MMIO write offset on every TX doorbell

Summary

oce_mbox_create_wq stores the 32-bit db_offset straight from the firmware response into wq->db_offset for V2 commands; the TX hot path then issues OCE_WRITE_REG32 at that offset - bus_space_write_4 on x86 performs no range check, so hostile/broken firmware can aim repeated semi-controlled 4-byte MMIO writes anywhere within [BAR_vaddr, BAR+4GiB). Strictly weaker than DF-1395 (no heap overflow); same firmware trust boundary. Hardware-gated (no OCE device model in QEMU). Validate-against-PD_TXULP_DB fix.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-4130 Β· 3 files
FileTypeDescriptionSize
README.md β€” 2.7 KB ↓ raw
verdict.json β€” 2.1 KB view raw
hw_absent.log β€” 64 B view raw

DF-4130 β€” firmware-controlled NIC_CREATE_WQ db_offset used verbatim as MMIO write offset

File: sys/dev/netif/oce/oce_mbox.c:1710-1711 (sink store), oce_if.c:949 (use) Pass 2 (GLM 5.3), 2026-09-18. Hardware-gated (Emulex OCE/BE3/Lancer NIC); source-level certainty β€” no such device exists in the audit QEMU guest (hw_absent.log), so this is a code-path audit verdict, not a live repro.

THE BUG oce_mbox_create_wq() copies a 32-bit doorbell offset straight out of the firmware response into driver state when the command is V2 (Lancer/Skyhawk):

    if (version == OCE_MBX_VER_V2)
            wq->db_offset = LE_32(fwcmd->params.rsp.db_offset);
                                               /* oce_mbox.c:1710-1711 */

and the TX hot path then uses it unvalidated as a bus_space offset:

    OCE_WRITE_REG32(sc, db, wq->db_offset, reg_value);
                                               /* oce_if.c:949 */
    => bus_space_write_4(sc->db_btag, sc->db_bhandle, wq->db_offset,
                         (num_wqes << 16) | wq->wq_id)

On x86 DragonFly, bus_space_write_4 is direct pointer arithmetic on
the BAR mapping (sys/bus/pci/x86_64/...): a firmware-chosen 32-bit
offset is not range-checked, so a malicious/broken firmware image can
direct every TX doorbell write anywhere within [BAR_vaddr,
BAR_vaddr + 4 GiB) of kernel virtual space β€” value semi-controlled
((num_wqes<<16)|wq_id, num_wqes up to the WQ ring depth).

THREAT MODEL / IMPACT Same trust boundary as the known DF-1395/DF-1396 (firmware-fed response fields driving kernel writes/walks): attacker = compromised or hostile NIC firmware (or a firmware bug). Strictly weaker than DF-1395 (no kernel heap overflow) but stronger than none: repeated 4-byte semi-controlled MMIO writes at a fw-chosen kernel-relative offset on the per-packet TX path. Ceiling: memory corruption / DoS in the host kernel via the device's own register aperture. Severity Low (requires OCE hardware + malicious firmware).

FIX Validate the response against the expected static doorbell: if (fwcmd->params.rsp.db_offset != PD_TXULP_DB / expected /) device_printf(...); rc = EINVAL; goto error; or clamp to the driver-known doorbell register range before first use in oce_start_locked.

VERDICT not_reproduced on this guest β€” no Emulex OCE device is attachable in QEMU (no public device model; pciconf shows none, hw_absent.log). Source data-flow is certain; exploit demonstration impossible without the hardware. (Status vocabulary per persist_poc.py.)

Fix verification

not_testable
baseline no→ patch + rebuild →patched clean

fix not runtime-testable: the affected code path requires an Emulex OCE NIC which the QEMU guest cannot provide

hw_absent.log
per-fix-DF-4130

Confirmed kernel references

Detail

Evidence (decisive lines)

hw_absent.log (no Emulex PCI device, no /dev/oce*, no if_oce.ko on the audit guest); source cites in README.md

PoC changes

no seed; source-trace only (hardware-gated class, consistent with DF-1395/DF-1396 handling)

Verified recommended fix

validate rsp.db_offset against the driver-known doorbell register (PD_TXULP_DB) or clamp to the BAR range before first TX doorbell use

Verdict

Source-certain data flow: the firmware response field rsp.db_offset (NIC_CREATE_WQ V2) is stored unvalidated into wq->db_offset (oce_mbox.c:1710-1711) and used verbatim as the bus_space offset of a 32-bit MMIO write on every TX doorbell (oce_if.c:949); x86 bus_space_write_4 does no range check, so hostile firmware can aim semi-controlled 4-byte writes at kernel memory relative to the BAR map. Cannot be exercised on the audit guest: QEMU has no Emulex OCE device model and none is attached (hw_absent.log) β€” hardware-gated finding, filed for upstream robustness hardening.