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

Firmware-controlled size_of_struct in oce_read_mac_addr drives unbounded bcopy (heap overflow into softc)

Summary

oce_read_mac_addr at oce_mbox.c:447-449: mac->size_of_struct=fwcmd->params.rsp.mac.size_of_struct (FW u16). bcopy(mac_addr,mac->mac_addr,mac->size_of_struct). mac_addr is 6 bytes in 8-byte struct inside softc. size_of_struct up to 65535 -> heap overflow into bsmbx DMA ptr/bmbx_lock/wq[]/rq[]/cq[]/eq[]. FW response trusted unconditionally at attach. Malicious/buggy OneConnect HBA. Fix: clamp to sizeof(mac_addr), copy only 6 bytes.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-1395 Β· 11 files
FileTypeDescriptionSize
oce_overflow.c trigger-source byte-exact harness replicating oce_read_mac_addr FW-length overflow 4.5 KB view raw
build.sh build-script cc -O2 -o oce_overflow oce_overflow.c 240 B view raw
run.sh run-script run harness 25 B view raw
run.log run-log decisive harness output, OVERFLOW CONFIRMED 657 B view raw
env.txt environment uname, cc version 227 B view raw
fix.diff suggested-fix clamp size_of_struct to sizeof(mac->mac_addr) 504 B view raw
fix_build.log build-log full nativekernel build with oce fix (rc=0, -Werror) 5.6 MB ↓ download
VERDICT.md verdict full analysis 4.0 KB ↓ raw
README.md readme reproduce guide 1.9 KB ↓ raw
../fix_build_combined.log build-log Combined 41-finding kernel build (rc=0, -Werror clean) 5.6 MB ↓ download
../fix_build_summary.txt build-summary Summary of the combined 41-finding kernel build 826 B view raw
README.md readme reproduce guide
↓ download raw

DF-1395 β€” oce_read_mac_addr firmware-controlled heap overflow (PoC)

Summary

oce_read_mac_addr (sys/dev/netif/oce/oce_mbox.c:447-449) copies a firmware MAC address using a firmware-controlled size_of_struct (u16, unchecked) into the 6-byte mac->mac_addr, overflowing into adjacent softc fields (bsmbx, bmbx_lock, wq[]/rq[]/cq[]/eq[]). Malicious/buggy OneConnect HBA firmware. device oce is in X86_64_GENERIC (ships in the default kernel).

Reachability

oce(4) attaches only to Emulex OneConnect 10Gb PCI HBAs. The QEMU audit guest has no such hardware, so the bug is not live-reachable here. This package proves the primitive deterministically with a byte-exact userspace harness that replicates the exact struct mac_address_format layout and the vulnerable bcopy(... size_of_struct) logic.

Build / run

./build.sh && ./run.sh      # builds & runs the harness as an unprivileged user

Expected output (bug present)

FW-controlled size_of_struct = 64 (0x40)
overflow past mac_addr[6]: YES -> into adjacent softc fields
adjacent softc canary corrupted: YES
OVERFLOW CONFIRMED: FW-controlled size_of_struct (64) bypassed the 6-byte mac_addr ...

On a fixed kernel the overflow is impossible by construction (the clamp bounds the copy to sizeof(mac->mac_addr) = 6).

Files

  • oce_overflow.c β€” byte-exact harness (struct from oce_hw.h:1051-1053).
  • build.sh / run.sh β€” exact build/run.
  • run.log β€” decisive harness output.
  • env.txt β€” guest uname / cc version.
  • fix.diff β€” git-apply-able fix (clamp copy length to sizeof(mac->mac_addr)).
  • fix_build.log β€” full untrimmed kernel build log with the fix (rc=0, -Werror).
  • VERDICT.md β€” full analysis.
  • manifest.json β€” artifact catalog.

Fix

Clamp mac->size_of_struct to sizeof(mac->mac_addr) before the bcopy (fix.diff). Validated to compile into a rebuilt X86_64_GENERIC kernel.

VERDICT.md verdict full analysis
↓ download raw

DF-1395 β€” oce_read_mac_addr firmware-controlled heap overflow

Verdict: REPRODUCED (primitive proven via source trace + byte-exact harness). Fix compiles into GENERIC.

oce_read_mac_addr copies a firmware-supplied MAC address using a firmware-controlled length with no bounds check, overflowing the 6-byte destination mac->mac_addr into adjacent softc fields. The bug is confirmed real by line-by-line source tracing and a byte-exact harness; it is not live-reachable on the QEMU guest because oce(4) attaches only to Emulex OneConnect PCI hardware (absent in QEMU). device oce IS in X86_64_GENERIC (sys/config/X86_64_GENERIC:219), so the vulnerable code ships in the default kernel; the fix was validated to compile into a rebuilt GENERIC kernel.

Mechanism (trigger β†’ primitive β†’ effect)

sys/dev/netif/oce/oce_mbox.c:446-449:

/* copy the mac addres in the output parameter */
mac->size_of_struct = fwcmd->params.rsp.mac.size_of_struct;   /* FW u16, UNCHECKED */
bcopy(&fwcmd->params.rsp.mac.mac_addr[0], &mac->mac_addr[0],
      mac->size_of_struct);                                    /* SINK: overflow */

Destination layout (sys/dev/netif/oce/oce_hw.h:1051-1053):

struct mac_address_format {
    uint16_t size_of_struct;
    uint8_t  mac_addr[6];        /* <-- 6-byte destination */
};

mac is a field embedded in POCE_SOFTC; size_of_struct is a uint16_t copied verbatim from the firmware mailbox response (max 65535). A malicious/buggy OneConnect HBA returning size_of_struct > 6 makes the bcopy write past mac_addr[6] into the following softc fields: bsmbx (DMA ptr), bmbx_lock, and the wq[]/rq[]/cq[]/eq[] ring arrays β†’ heap corruption.

Primitive

  • Class: heap overwrite, firmware-controlled length up to 65535, content firmware-controlled (the FW response bytes).
  • Effect: corruption of DMA pointers, locks, ring arrays β†’ panic or exploitable heap corruption on real OneConnect hardware.

Reachability / threat model

  • oce is device oce in X86_64_GENERIC (compiled into the default kernel) but only attaches on Emulex OneConnect 10Gb PCI HBAs. The QEMU guest has no such device, so oce_attach (and thus oce_read_mac_addr) never runs live.
  • This is a malicious/buggy firmware + malicious device threat (PCIe attach-time parse of FW response). Relevant for servers with OneConnect HBAs and for hostile-device / DMA-attack threat models. Not an unprivileged-local privesc vector on this guest (no hardware).
  • Validated the primitive deterministically with the byte-exact harness (oce_overflow.c): FW size_of_struct=64 overflows mac_addr[6] and corrupts the adjacent-region canary (modeling bsmbx/locks/rings).

Harness proof (run.log)

mac->mac_addr capacity: 6 bytes (sizeof mac_addr)
FW-controlled size_of_struct = 64 (0x40)
overflow past mac_addr[6]: YES -> into adjacent softc fields
adjacent softc canary corrupted: YES
OVERFLOW CONFIRMED: FW-controlled size_of_struct (64) bypassed the 6-byte
mac_addr and corrupted adjacent softc fields.

Fix validation

fix.diff clamps the copy length: after reading the FW value, if mac->size_of_struct > sizeof(mac->mac_addr) set it to sizeof(mac->mac_addr) before the bcopy.

  • The fix was applied to in-guest /usr/src and compiled into a rebuilt X86_64_GENERIC kernel (make -j6 nativekernel, -Werror); oce_mbox.o builds cleanly β†’ the fix is compile-valid for the default kernel.
  • Runtime re-test on this guest is not possible (no OneConnect HW), so fix_status = not_testable for runtime, with the diff verified to apply + compile into GENERIC and the harness logic confirming the clamp prevents the overflow (a clamp to sizeof(mac->mac_addr) bounds the copy to 6 bytes).

Kernel references

Fix verification

not_testable

compile+harness validated

module build rc=0

Confirmed kernel references

β€”

Detail

Exploit chain

none

Evidence (decisive lines)

β€”

Verdict

REPRODUCED (harness). oce_read_mac firmware size_of_struct no bounds vs mac_addr[6] -> overflow. oce in GENERIC, no OneConnect HBA.