DF-3963 / trigger.c
/* * DF-3963 trigger sketch โ mv family queue-pointer registers used unmasked * ======================================================================== * hptiop_mv_outbound_read() (hptiop.c:229-250): * u_int32_t outbound_tail = BUS_SPACE_RD4_MV2(outbound_tail); // device reg * ... * bus_space_read_region_4(bar2t, bar2h, * offsetof(struct hpt_iopmu_mv, outbound_q[outbound_tail]), &p, 2); * // MMIO READ at BAR2 + 0x1040 + 8*outbound_tail โ unmasked * outbound_tail++; * if (outbound_tail == MVIOP_QUEUE_LEN) outbound_tail = 0; // wrap AFTER * BUS_SPACE_WRT4_MV2(outbound_tail, outbound_tail); * * hptiop_mv_inbound_write() (hptiop.c:252-265): * u_int32_t inbound_head = BUS_SPACE_RD4_MV2(inbound_head); // device reg * ... * bus_space_write_region_4(bar2t, bar2h, * offsetof(struct hpt_iopmu_mv, inbound_q[inbound_head]), &p, 2); * // MMIO WRITE of 8 host-chosen bytes at BAR2 + 0x40 + 8*inbound_head * // โ unmasked, device-fed offset * * MVIOP_QUEUE_LEN is 512 (hptiop.h:96); inbound_q/outbound_q are 512-entry * arrays inside the BAR2 register file (hptiop.h:97-107). A device (or * device-DMA attacker) that sets either pointer register to >= 512 steers an * OOB bus-space access: up to ~32 GB beyond BAR2 for the read, and โ more * interesting โ an 8-byte WRITE of `p` (a host physical address | flags) at * BAR2+0x40+8*head. Host RAM is not reachable through the BAR window, so the * write lands in unmapped MMIO (machine check / panic) or in a neighbouring * device's BAR if one is mapped there โ a device-fed MMIO-corruption/DoS * primitive, same trust class as the known DF-1312 but in the queue-pointer * plumbing (checklist item (a): the reply/request queues). * * Trigger on hardware: RR3020/3120-class (mv family), set the inbound_head / * outbound_tail register to e.g. 0x400 via a wedged/emulated device, then * issue any I/O or let an interrupt arrive. */ int main(void) { return 0; } /* informational sketch โ see VERDICT.md */ |