Signed table_id bounds check allows negative-index OOB on smu_tables.entry[]
Summary
vega12_copy_table_from_smc (vega12_smumgr.c:41) and _to_smc (79) declare int16_t table_id but validate only "table_id < TABLE_COUNT(10)" at 46/84. Negative table_id (e.g. -1) satisfies -1<10 so passes; used as array index entry[table_id] at 48-68 and 86-108 with memcpy length entry[table_id].size at 68/91. entry[] is fixed array TABLE_COUNT=10 (vega12_smumgr.h:39); negative index reads adjacent struct memory as smu_table_entry yielding attacker-influenced (table,size,mc_addr) for memcpy. vega12_smc_table_manager (354) declares uint16_t table_id narrowing to int16_t at 360/362 so 0x8000-0xFFFF reinterprets as [-32768,-1]. NOT currently reachable: only callers pass compile-time constants TABLE_PPTABLE=0 (vega12_hwmgr.c:748) and TABLE_WATERMARKS=1 (:2112); no ioctl/debugfs forwards user-controlled table_id (smumgr.c:209-214 -> vtable). Latent API-contract trap: any future change routing user/firmware 16-bit selector through smum_smc_table_manager -> controllable kernel OOB read/write with attacker-chosen source/dest pointer+length = arbitrary kernel memory corruption. Requires Vega12-class AMD GPU. AV:L/AC:H/PR:L, I:N/A:L.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2021 Β· 7 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | readme | original PoC README | 909 B | β raw |
| VERDICT.md | verdict | full source-trace verdict | 1.4 KB | β raw |
| build.sh | build-script | build/verify instructions | 438 B | view raw |
| env.txt | environment | guest environment (no matching HW) | 814 B | view raw |
| fix.diff | suggested-fix | git-apply-able fix, verified to compile -Werror | 1.2 KB | view raw |
| fix_build.log | build-log | Phase 8 module build evidence (-Werror rc=0) | 1.5 KB | view raw |
| run.sh | run-script | run instructions (HW-gated) | 323 B | view raw |
DF-2021 PoC β Signed table_id negative-index OOB (speculative / latent)
Status
NOT currently reachable from any in-tree caller. The only callers of
smum_smc_table_manager pass compile-time constants (TABLE_PPTABLE=0,
TABLE_WATERMARKS=1). No ioctl/debugfs forwards a user-controlled table_id.
Latent primitive
If a future code path routes a user- or firmware-controlled 16-bit table
selector through vega12_smc_table_manager(hwmgr, buf, 0xFFFF, true):
table_id = 0xFFFFnarrows toint16_t -1(-1 < TABLE_COUNT=10)passes the guardentry[-1]is read from adjacent kernel heap memory- The
.sizefield controls amemcpylength - The
.tablepointer controls source/destination
Result: controllable kernel OOB read (rw=true) or OOB write (rw=false) with attacker-chosen pointer and length.
Filed as speculative precisely because no forwarding path exists today.
VERDICT -- DF-2021 (Low)
Verdict: REPRODUCED (source-only, latent)
Impact: latent signed-index OOB on entry[] (CWE-129); not currently reachable (only const callers); HW-gated (needs Vega12 AMD GPU), source-confirmed
Confidence: speculative
Mechanism (source-traced)
vega12_copy_table_from_smc (vega12_smumgr.c:41) and _to_smc (:79) declare int16_t table_id but validate only 'table_id < TABLE_COUNT(10)' at :46/:84. A negative table_id (e.g. -1) satisfies -1<10 and is used as an array index entry[table_id] at :48-68/:86-108 with memcpy length entry[table_id].size. NOT currently reachable: the only callers pass compile-time constants (TABLE_PPTABLE=0, TABLE_WATERMARKS=1). Latent API-contract trap.
Why not runtime-reproduced
The guest (DragonFlyBSD 6.5-DEVELOPMENT #0 master DEV, KVM) has NO matching
hardware: pciconf shows no mfi/tws/iir RAID controller and no amdgpu/DRM GPU;
the driver therefore cannot attach and the vulnerable path is not runtime-
triggerable here. The defect was confirmed at the source level by tracing
the cited path:line against sys/, and the proposed fix was applied and the
affected module (amdgpu) built clean with -Werror (see fix_build.log).
Fix
vega12_smumgr.c:46 and :84: change the bound to 'table_id >= 0 && table_id < TABLE_COUNT' so negative int16_t values are rejected.
The standalone, git-apply-able diff is fix.diff.
Fix verification
not_testableVALIDATED build.
VALIDATED build.
Confirmed kernel references
- s
- y
- s
- /
- d
- e
- v
- /
- d
- r
- m
- /
- a
- m
- d
- /
- p
- o
- w
- e
- r
- p
- l
- a
- y
- /
- s
- m
- u
- m
- g
- r
- /
- v
- e
- g
- a
- 1
- 2
- _
- s
- m
- u
- m
- g
- r
- .
- c
- :
- 4
- 6
Detail
Exploit chain
none (HW-gated).
Evidence (decisive lines)
HW-GATED (no AMD GPU). Source-CONFIRMED latent. vega12_copy_table_from_smc validates table_id<TABLE_COUNT(10) but no lower bound. Negative table_id passes check, indexes entry[-1]. Currently unreachab
Verified recommended fix
Add table_id >= 0 && table_id < TABLE_COUNT at :46 and :84.
Verdict
HW-GATED (no AMD GPU). Source-CONFIRMED latent. vega12_copy_table_from_smc validates table_id<TABLE_COUNT(10) but no lower bound. Negative table_id passes check, indexes entry[-1]. Currently unreachable (only const callers).
No comments yet.