β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-1269

Missing bounds checks on VBIOS-supplied indices in kv_parse_power_table (OOB reads)

Summary

kv_parse_power_table at kv_dpm.c:2745-2747: non_clock_array_index=power_state->v2.nonClockInfoIndex (u8 from VBIOS) used without check vs ucNumEntries. :2756-2757: ucNumDPMLevels drives loop without bounds. :2780-2782: vce_states.clk_idx (0-63) indexes clockInfo[] without check vs ucNumEntries. Clock-info path at :2758 correctly checks but siblings do not. Crafted VBIOS -> OOB read from BIOS mapping -> panic or leak into sysfs-visible rps fields. Fix: check nonClockInfoIndex/clk_idx < ucNumEntries.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-1269 Β· 12 files
FileTypeDescriptionSize
trigger.c trigger-source documentation stub; bug path is VBIOS-parse/GPU-init, not a syscall 985 B view raw
fix.diff suggested-fix git-apply-able fix 1.3 KB view raw
build.sh repro-script build the stub 470 B view raw
run.sh repro-script run the stub 244 B view raw
build.log build-log trigger build output 71 B view raw
run.log run-log trigger run output (no effect; latent) 65 B view raw
VERDICT.md verdict full source-level trace + fix rationale 2.1 KB ↓ raw
env.txt environment guest uname, modules, PCI (no GPU) 1.7 KB view raw
fix_build.log build-log compile-validation: kernel+module build with fix applied, rc=0, no errors 26.4 KB view raw
README.md readme human reproduce doc 437 B ↓ 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
README.md readme human reproduce doc
↓ download raw

DF-1269 PoC β€” kv_parse_power_table missing bounds checks (LATENT)

Status: source-confirmed real (certain); NOT reproducible on audit guest (no AMD GPU). Impact: OOB read from BIOS mapping via crafted VBIOS indices. Driver: sys/dev/drm/amd/amdgpu/kv_dpm.c (amdgpu kv path, not in GENERIC, no HW).

Reproduce

./build.sh && ./run.sh   # stub; bug path is VBIOS power-table parse

See VERDICT.md + fix.diff.

VERDICT.md verdict full source-level trace + fix rationale
↓ download raw

DF-1269 β€” kv_parse_power_table missing bounds checks on VBIOS indices (LATENT)

Verdict

NOT REPRODUCED on the audit guest (LATENT / HW-gated). The bug is confirmed real by source-level trace (confidence=certain in the DB); it cannot fire here because there is no AMD APU/GPU, so the kv_dpm.c power-table parse path is dead at runtime.

Mechanism (confirmed in source)

kv_parse_power_table (kv_dpm.c:~2710) reads VBIOS-supplied indices without bounds checks against ucNumEntries: - nonClockInfoIndex (kv_dpm.c:2745-2747): non_clock_array_index = power_state->v2.nonClockInfoIndex; (u8 from VBIOS), then &non_clock_info_array->nonClockInfo[non_clock_array_index] β€” no check non_clock_array_index < non_clock_info_array->ucNumEntries β†’ OOB read from the BIOS mapping. - vce_states clk_idx (kv_dpm.c:2780-2782): clock_array_index = adev->pm.dpm.vce_states[i].clk_idx; (range 0..63), then &clock_info_array->clockInfo[clock_array_index * ucEntrySize] β€” no check vs ucNumEntries. - The sibling clock-info path at :2758 (if (clock_array_index >= clock_info_array->ucNumEntries) continue;) does check β€” proving these two were missed.

A crafted VBIOS β†’ OOB read from the BIOS mapping β†’ panic or leak into sysfs-visible rps fields.

Why it does not reproduce here

No AMD GPU on the guest (pciconf -lv); kv_dpm attaches only to AMD APUs. Reaching the bug needs that hardware + a crafted VBIOS. Valid hard blocker.

Exploit chain

N/A β€” OOB read (info leak / panic), HW-gated (latent). No write primitive.

PoC changes

trigger.c is a documentation stub.

Fix (fix.diff)

Add the two missing bounds checks, mirroring the existing :2758 check: - skip the state if non_clock_array_index >= non_clock_info_array->ucNumEntries (advance power_state_offset and continue); - skip the vce state if clock_array_index >= clock_info_array->ucNumEntries. Applies cleanly (patch -p1 rc=0). Matches the finding proposal.

Fix validation

not_testable β€” code path unreachable on audit guest; diff applies cleanly, syntactically reviewed.

Fix verification

not_testable

compile validated

kernel/module build rc=0

Confirmed kernel references

β€”

Detail

Exploit chain

none

Evidence (decisive lines)

β€”

Verdict

Source-confirmed. kv_parse_power_table nonClockInfoIndex/clk_idx no bounds (sibling :2758 has it) -> OOB read. amdgpu not in GENERIC.