# 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`:
```c
/* 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`):
```c
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

- `sys/dev/netif/oce/oce_mbox.c:447-449` (sink: unchecked FW length → bcopy)
- `sys/dev/netif/oce/oce_hw.h:1051-1053` (`struct mac_address_format`, 6-byte
  destination)
- `sys/config/X86_64_GENERIC:219` (`device oce`)
