Firmware completion tokens consumed unvalidated: psrb_pool[SMID] OOB read (ARC1884) and wild vir2phy SRB dereference (types A-D)
Summary
arcmsr_drain_donequeue() for TYPE E does srb = acb->psrb_pool[flag_srb] with flag_srb = the 16-bit cmdSMID DMA-written by firmware, with no bounds check against the 384-entry array: an SMID in 384..65535 reads up to ~512KB past psrb_pool into adjacent kernel heap, and the value is immediately dereferenced (srb->acb). For types A-D the raw device token is turned into a pointer via vir2phy_offset arithmetic and dereferenced before any pool-range validation - a device value anywhere in 32-bit physical space yields a wild kernel pointer. Same threat model as DF-1184 (buggy/hostile firmware or device DMA): transient fault -> panic; deliberate attacker -> forged SRB -> arcmsr_srb_complete on attacker-chosen pointers (bus_dmamap_unload/xpt_done on forged pointers). Upstream FreeBSD main still has the same unguarded index (verified). VERIFIED: harness on the guest - SMID=0xffff reads 521216 bytes past the array; the (A-D) variant resolves a device value ~1GB away from the pool. Fix validated on rebuilt kernel.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-3709 Β· 9 files| File | Type | Description | Size | |
|---|---|---|---|---|
| harness.c | trigger-source | models psrb_pool[384] indexing with firmware u16 SMID + (A-D) vir2phy address derivation | 5.0 KB | view raw |
| build.sh | build | cc -O2 -Wall -o harness harness.c | 65 B | view raw |
| run.sh | run | executes harness | 89 B | view raw |
| build.log | log | untrimmed guest build output | 66 B | view raw |
| run.log | log | decisive run | 859 B | view raw |
| run.2.log | log | repeat run | 859 B | view raw |
| fix.diff | fix | SMID >= ARCMSR_MAX_FREESRB_NUM guards in drain_donequeue + polling_hbe | 1012 B | view raw |
| fix_build.log | log | patched-source kernel build log (arcmsr.c compiled -Werror clean, in-kernel + KLD) | 870 B | view raw |
| env.txt | env | guest uname/compiler/no-HW evidence | 643 B | view raw |
Fix verification
fixedfix.diff (two SMID guards) applied to guest /usr/src copy; arcmsr.c recompiled clean with -Werror in-kernel and KLD builds (fix_build.log). On-hardware behavioral validation impossible in this guest.
fix_build.log arcmsr compile lines with -Werror and 0 arcmsr-related errors; guards visible at arcmsr.c:820-826 and 3596-3601 in guest tree before restore
Confirmed kernel references
Detail
Exploit chain
firmware/DMA-controlled SMID or address -> OOB read of kernel heap / wild SRB pointer -> srb->acb/srb_state deref (panic) or, with DMA control, forged SRB -> arcmsr_srb_complete -> bus_dmamap_unload/xpt_done on forged pointers; not exercisable without Areca hardware
Evidence (decisive lines)
run.log: 'SMID=0xffff -> index distance past array end: 65152 entries (521216 bytes)'; '(A-D variant) raw device value 0xedcba988 -> distance from pool base: +0x41fea980 bytes (pool is only ~209KB)'; '[+] DF-3709 CONFIRMED'; VERDICT.md cites all sites
PoC changes
authored from scratch (no seed)
Verified recommended fix
reject flag_srb/cmdSMID >= ARCMSR_MAX_FREESRB_NUM in arcmsr_drain_donequeue() and arcmsr_polling_hbe_srbdone(); harden A-D by range-checking the physical token against [srb_phyaddr, srb_phyaddr + ARCMSR_SRBS_POOL_SIZE)
Verdict
Firmware completion tokens are consumed unvalidated: for ARC1884 (TYPE E) arcmsr_drain_donequeue() (arcmsr.c:821) and arcmsr_polling_hbe_srbdone() (arcmsr.c:3582) index acb->psrb_pool[] (384 entries) with the firmware DMA-written 16-bit cmdSMID (arcmsr.c:2120-2122) with no bounds check -> OOB kernel read up to 65152 entries (~512KB) past the array, value immediately dereferenced as srb->acb (arcmsr.c:829); for TYPE A-D (arcmsr.c:818/826) the raw device value is turned into a pointer via vir2phy_offset arithmetic and dereferenced before any pool-range validation. Guest has no Areca HBA (0 PCI devices vendor 0x17D3), so reproduction is a harness modeling the exact arithmetic: SMID 0xffff reads 65152 entries past psrb_pool and feeds a wild pointer; the A-D variant resolves a device value ~1GB away from the 209KB pool. Threat model identical to DF-1184: buggy/hostile firmware or device DMA; realistic impact kernel panic, with forged-SRB completion (xpt_done on attacker-chosen pccb) available to a DMA-level attacker.
No comments yet.