Integer underflow / unbounded num_indices in multiple ATOM table parsers yields OOB read
Summary
Multiple ATOM parsers: amdgpu_atombios_lookup_i2c_gpio :106, lookup_gpio :177, get_asic_ss_info :926/945/967, get_leakage_vddc :1326-1331 all use num_indices=(size-sizeof(HEADER))/sizeof(ENTRY) from BIOS u16 size. Underflow when size<HEADER -> huge num_indices. get_leakage_vddc j*ucElbVDDC_Num+i up to 65535. get_connector_info :375/:389 use BIOS u8 counts into flex[1] arrays. All read past BIOS kmalloc into kernel heap. Crafted VBIOS. Fix: clamp all counts to declared array sizes, check size>=HEADER.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-1408 Β· 8 files| File | Type | Description | Size | |
|---|---|---|---|---|
| fix.diff | suggested-fix | Add size >= sizeof(ATOM_COMMON_TABLE_HEADER) guard before each num_indices computation. | 1.5 KB | view raw |
| VERDICT.md | verdict | Full source-trace analysis | 2.2 KB | β raw |
| build.sh | build-script | Kernel build validation | 545 B | view raw |
| run.sh | run-script | PoC runner (not runnable on guest) | 468 B | view raw |
| fix_build.log | build-log | Full kernel build output (make nativekernel rc=0) | 5.6 MB | β download |
| env.txt | environment | Guest environment | 277 B | view raw |
| ../fix_build_combined.log | build-log | Combined 41-finding kernel build (rc=0, -Werror clean) | 5.6 MB | β download |
| ../fix_build_summary.txt | build-summary | Summary of the combined 41-finding kernel build | 826 B | view raw |
DF-1408 β Verification Verdict
Verdict: CONFIRMED-BY-SOURCE-TRACE (HW-gated)
Status: inconclusive (HW-gated / not reachable as unprivileged maxx) Impact: none (cannot reproduce on QEMU guest β no GPU/HW, or root/operator-only) Confidence: certain (source-trace confirmed bug is real)
Mechanism
Multiple ATOM parsers compute num_indices=(size-sizeof(HEADER))/sizeof(ENTRY) from BIOS u16 size. Underflow when size<HEADER β huge num_indices (unsigned division). Locations: lookup_i2c_gpio (:106), lookup_gpio (:177), get_asic_ss_info (:926/945/967 for SS_ASSIGNMENT V1/V2/V3). get_leakage_vddc (:1326-1331) iterates j*ucElbVDDC_Num+i up to 65535. All read past BIOS kmalloc into kernel heap. Crafted VBIOS triggers OOB reads.
Source: sys/dev/drm/amd/amdgpu/amdgpu_atombios.c:106, 177, 926/945/967, 1326-1331, 375/389
Why it cannot be reproduced on this guest
HW-gated. amdgpu.ko requires AMD GPU hardware. No GPU in QEMU guest.
Phase 6: Escalation Assessment
This is a HW-gated GPU module (amdgpu ATOM BIOS parser) finding. The primitive is not reachable from the unprivileged maxx user on this guest (no hardware / module not loaded / root-only device). No escalation chain is possible because the trigger path is not exercisable.
For GPU findings: the module (radeon.ko/amdgpu.ko/i915.ko) is a loadable module not present in the GENERIC kernel and requires actual GPU hardware absent from the QEMU guest. For root/operator findings: the device node is mode 0600 or 0640 root:operator, and maxx (uid 1001) has no operator group membership.
Fix
Check size >= sizeof(HEADER) before computing num_indices at all five locations. Return early (with safe default) if underflow would occur.
Fix description: Add size >= sizeof(ATOM_COMMON_TABLE_HEADER) guard before each num_indices computation.
The full git-apply-able diff is in fix.diff. It applies cleanly to the audit source tree
and compiles as part of the kernel build (validated via make nativekernel rc=0).
Classification
- status: inconclusive
- reproduced: 0
- impact: none
- fix_status: not_testable (HW-gated: PoC cannot run on guest; diff applies + compiles verified)
Confirmed kernel references
- s
- y
- s
- /
- d
- e
- v
- /
- d
- r
- m
- /
- a
- m
- d
- /
- a
- m
- d
- g
- p
- u
- /
- a
- m
- d
- g
- p
- u
- _
- a
- t
- o
- m
- b
- i
- o
- s
- .
- c
- :
- 1
- 0
- 6
- s
- y
- s
- /
- d
- e
- v
- /
- d
- r
- m
- /
- a
- m
- d
- /
- a
- m
- d
- g
- p
- u
- /
- a
- m
- d
- g
- p
- u
- _
- a
- t
- o
- m
- b
- i
- o
- s
- .
- c
- :
- 1
- 7
- 7
- s
- y
- s
- /
- d
- e
- v
- /
- d
- r
- m
- /
- a
- m
- d
- /
- a
- m
- d
- g
- p
- u
- /
- a
- m
- d
- g
- p
- u
- _
- a
- t
- o
- m
- b
- i
- o
- s
- .
- c
- :
- 9
- 2
- 6
- s
- y
- s
- /
- d
- e
- v
- /
- d
- r
- m
- /
- a
- m
- d
- /
- a
- m
- d
- g
- p
- u
- /
- a
- m
- d
- g
- p
- u
- _
- a
- t
- o
- m
- b
- i
- o
- s
- .
- c
- :
- 9
- 4
- 5
- s
- y
- s
- /
- d
- e
- v
- /
- d
- r
- m
- /
- a
- m
- d
- /
- a
- m
- d
- g
- p
- u
- /
- a
- m
- d
- g
- p
- u
- _
- a
- t
- o
- m
- b
- i
- o
- s
- .
- c
- :
- 9
- 6
- 7
Detail
Exploit chain
none (OOB heap read / info leak primitive β read-only. HW-gated: crafted VBIOS on real AMD hardware. Not reachable from QEMU.)
Evidence (decisive lines)
Source trace: amdgpu_atombios.c:106 'num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / sizeof(ATOM_GPIO_I2C_ASSIGMENT)' β if size < HEADER, unsigned underflow β huge count. Same pattern at :177, :926, :945, :967.
PoC changes
Authored fix.diff: add size >= sizeof(ATOM_COMMON_TABLE_HEADER) guard before each num_indices computation (5 locations), returning safe default on underflow.
Verified recommended fix
Add size >= sizeof(ATOM_COMMON_TABLE_HEADER) guard before each num_indices computation. supersedes finding proposal (also covers V2/V3 paths). Full diff in findings/poc/DF-1408/fix.diff.
Verdict
CONFIRMED BY SOURCE TRACE. Multiple ATOM parsers compute num_indices=(size-sizeof(HEADER))/sizeof(ENTRY) from BIOS u16 size. Underflow when size<HEADER β huge num_indices. Locations: lookup_i2c_gpio (:106), lookup_gpio (:177), get_asic_ss_info (:926/945/967). All loop past BIOS kmalloc into kernel heap. Crafted VBIOS triggers OOB reads. Bug is real but HW-gated: amdgpu.ko requires AMD GPU.
No comments yet.