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

audio_regs[] defines 6 entries while res_cap.num_audio=7 β€” the audio_regs[6] global-out-of-bounds fixed upstream in 44035ec2fde1 (KASAN, Cc:stable) is latent in this tree behind resource_construct's pipe_count cap

Summary

create_audio passes &audio_regs[inst] unchecked with num_audio=7 but only 6 entries exist - the exact KASAN-proven global OOB fixed upstream by 44035ec2fde1 (missing from this v4.19-era copy). Currently unreachable because resource_construct caps the audio loop at pipe_count<=6; becomes a live boot-time global OOB read the moment dc_resource.c is synced to the modern loop. Filed so the stable fix is not lost at the next DC sync. Upstream-verbatim one-line fix.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-4449 Β· 4 files
FileTypeDescriptionSize
VERDICT.md β€” 2.3 KB ↓ raw
fix.diff β€” 362 B view raw
manifest.json β€” 732 B view raw
verdict.json β€” 2.1 KB view raw
VERDICT.md
↓ download raw

DF-4449 β€” dce120 audio_regs[] has 6 entries but res_cap.num_audio = 7 (latent OOB; upstream fix 44035ec2fde1 missing)

File: sys/dev/drm/amd/display/dc/dce120/dce120_resource.c Severity: Info (latent hardening / upstream-divergence tracking) Β· CWE: CWE-129

Facts

  • audio_regs[] defines entries 0..5 only (dce120_resource.c:322-329).
  • res_cap.num_audio = 7 (:438-444).
  • create_audio(ctx, inst) passes &audio_regs[inst] straight into dce_audio_create (:605-610), which stores the pointer as the endpoint's register table.

Upstream history (the reason this matters)

Upstream Linux hit exactly this mismatch and fixed it in commit 44035ec2fde1 "drm/amd/dc/dce120: Fix audio register mapping, stop triggering KASAN" (Lyude Paul, 2022-11-23, Cc: stable):

BUG: KASAN: global-out-of-bounds in read_indirect_azalia_reg "on my dce120 GPU there are supposedly 7 sets of audio registers. But we only define a register mapping for 6 sets."

The upstream fix adds audio_regs(6) (verified present in v6.6; absent in v4.19..v5.10 β€” the bug became reachable upstream when resource.c dropped the pipe_count cap on the audio-creation loop).

Why DF is latent (not reachable today)

The DF resource_construct caps the audio-creation loop at pipe count:

pipe_count is 6 (or fewer with Vega20 harvesting), so create_audio is only ever called with inst 0..5 β€” audio_regs[6] is never formed in this tree. No runtime OOB today. The mismatch becomes a live global-out-of-bounds (KASAN-proven class) the moment dc_resource.c is synced to the modern upstream loop (i < num_audio uncapped), which is precisely how upstream got bitten.

Apply the upstream fix verbatim (one line, also removes the mismatch even while latent):

    audio_regs(4),
-   audio_regs(5)
+   audio_regs(5),
+   audio_regs(6)
 };

Fix status (batch validation)

Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.

Fix verification

not_testable
baseline no→ patch + rebuild →patched clean

One-line initializer fix matching upstream 44035ec2fde1; not buildable on the audit guest (no AMD GPU).

findings/poc/DF-4449/fix.diff
↓ fix.diffper-fix-DF-4449

Confirmed kernel references

Detail

Evidence (decisive lines)

findings/poc/DF-4449/VERDICT.md; array at dce120_resource.c:322-329 (6 entries), num_audio=7 at :440, consumer at :605-610, guard at dc_resource.c:232; upstream commit 44035ec2fde1 quoted in VERDICT.md

PoC changes

n/a

Verified recommended fix

Add audio_regs(6) to the audio_regs[] initializer β€” upstream commit 44035ec2fde1 verbatim (fix.diff).

Verdict

audio_regs[] (dce120_resource.c:322-329) defines 6 entries while res_cap.num_audio=7 (:440) and create_audio passes &audio_regs[inst] unchecked (:605-610). Upstream hit this exact mismatch and fixed it in commit 44035ec2fde1 (2022, Cc: stable) after a KASAN global-out-of-bounds in read_indirect_azalia_reg; the DF copy predates that fix. In the current DF tree the OOB is unreachable because resource_construct caps the audio loop at pipe_count (dc_resource.c:232, i < pipe_count && i < num_audio), so inst never exceeds 5 β€” latent hardening divergence: syncing dc_resource.c to the modern upstream loop resurrects the OOB. One-line upstream fix provided (add audio_regs(6)).