# DF-1294 — ena_com sq_idx/cq_idx unvalidated → stack buffer overflow

## Finding
`ena_com_create_io_sq` at `sys/dev/virtual/amazon/ena/ena-com/ena_com.c:1156`
stores `cmd_completion.sq_idx` (a u16 from the hypervisor admin completion)
into `io_sq->idx` with no bounds check. The same defect is on the CQ path at
line 1333: `io_cq->idx = cmd_completion.cq_idx;`.

`ena_com_ind_tbl_convert_from_device` at lines 1205-1206 then indexes a
**stack-local** array with that attacker-controlled idx:
```c
u16 dev_idx_to_host_tbl[ENA_TOTAL_NUM_QUEUES] = { ... };  // 256 entries = 512 B on stack
for (i = 0; i < ENA_TOTAL_NUM_QUEUES; i++)
    dev_idx_to_host_tbl[ena_dev->io_sq_queues[i].idx] = i;   // OOB write
```
`ENA_TOTAL_NUM_QUEUES = 2 * ENA_MAX_NUM_IO_QUEUES = 256` (`ena_com.h:44-46`).
An `sq_idx` of e.g. 65535 from a malicious hypervisor writes `i` (u16) at
offset `(65535 - 256) * 2 = ~130 KB` past the stack array ⇒ stack buffer
overflow with attacker-controlled offset.

## Latency / reachability note
`ena_com_indirect_table_get` (the only caller of
`ena_com_ind_tbl_convert_from_device`, `ena_com.c:2613`) is **NOT wired** in
the current `ena.c` driver — only `ena_com_indirect_table_set` (which routes
through the bounds-checking `ena_com_ind_tbl_convert_to_device`) is wired at
`ena.c:2180`. So the OOB-write sink is currently dead at runtime. The idx
assignment itself (`io_sq->idx = cmd_completion.sq_idx` at line 1156) is
reached during normal queue creation whenever an ENA NIC is present.

## Why we did not reproduce at runtime
The audit guest has no Amazon ENA NIC (the ENA device is an AWS nitro virtual
NIC; not present in this QEMU/KVM VM). The `ena` driver is built as a module
and is not loaded (`kldstat -v` shows no `ena` entry), and is not in
X86_64_GENERIC. So neither the create_sq path nor the indirect-table-get path
runs on this guest.

## Source-level confirmation
- `ena_com.c:1156` — `io_sq->idx = cmd_completion.sq_idx;` (no bounds check vs ENA_TOTAL_NUM_QUEUES=256).
- `ena_com.c:1200` — `u16 dev_idx_to_host_tbl[ENA_TOTAL_NUM_QUEUES]` is a 512-B **stack** array.
- `ena_com.c:1205-1206` — `dev_idx_to_host_tbl[ena_dev->io_sq_queues[i].idx] = i;` — OOB if idx ≥ 256.
- `ena_com.c:1333` — `io_cq->idx = cmd_completion.cq_idx;` — same defect.
- `ena_com.h:44-46` — `ENA_MAX_NUM_IO_QUEUES 128`, `ENA_TOTAL_NUM_QUEUES (2*128)=256`.
- `ena_com.c:2593,2613` — `ena_com_indirect_table_get` calls `convert_from_device`.
- `grep ena_com_indirect_table_get sys/dev/virtual/amazon/ena/ena.c` — no caller ⇒ sink currently dead.

Bug is real; sibling finding DF-1221 reports the same defect.

## Realistic impact ceiling
Stack buffer overflow with attacker-controlled offset (idx up to 65535 ⇒ up
to ~130 KB past the stack array). The threat model is a **malicious
hypervisor** (AWS Nitro compromise) or a malicious VF that can spoof admin
completions to a guest using an ENA NIC. The idx assignment on the create_sq
path is reached during normal driver bring-up; the convert_from_device sink
is currently dead but would become live if `ena.c` is ever updated to call
`ena_com_indirect_table_get`.

## Fix
`fix.diff` adds three guards:
1. After `io_sq->idx = cmd_completion.sq_idx;` (create_io_sq): reject if `idx >= ENA_TOTAL_NUM_QUEUES`.
2. After `io_cq->idx = cmd_completion.cq_idx;` (create_io_cq): same check.
3. Defense-in-depth in `convert_from_device`: bounds-check `idx` before indexing `dev_idx_to_host_tbl`.
