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

Unbounded AUX reply byte count causes heap/stack OOB write on DP read path

Summary

On AUX read path hardware reply byte count bytes (5-bit MMIO field range 0..31 sourced from DP sink on wire) used directly as bound of copy loop into caller-supplied buffer msg->buffer sized only to msg->size (max 16 commonly 1). Function never clamps bytes-1 to msg->size. At radeon_dp_auxch.c:177 bytes=AUX_SW_REPLY_GET_BYTE_COUNT(tmp) = ((tmp>>24)&0x1f) no relationship enforced to msg->size. Copy loop 185-189 for(i=0;i<bytes-1;i++) buf[i]=(tmp>>8)&0xff; at 188. buf=msg->buffer (65) caller-provided exactly msg->size bytes (drm_dp_dpcd_readb at drm_dp_helper.h:1179-1183 passes 1-byte target). If bytes-1>msg->size write overflows. Atom sibling atombios_dp.c:141-142 explicitly clamps (if(recv_bytes>recv_size) recv_bytes=recv_size) native path omits demonstrating intended pattern missed. Attacker: peripheral on DP AUX bus (USB-C DP alt-mode adapter Thunderbolt dock monitor with hostile/buggy firmware) responding to small AUX read with extra data bytes. Reachability: any DRM KMS ioctl opener triggers 1-byte DPCD reads during normal operation (drm_dp_link_probe reads 3 drm_dp_dpcd_readb reads 1 radeon_dp_link_train multiple reads). Impact: heap/stack overflow of attacker-influenced bytes past kernel buffer on 1-byte target up to 15 bytes controlled data clobbering adjacent stack/heap. LPE or kernel panic.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2146 Β· 6 files
FileTypeDescriptionSize
VERDICT.md verdict source-level analysis with path:line citations 1.6 KB ↓ raw
reachability.txt environment guest PCI/device survey proving no required HW 1.6 KB view raw
fix.diff suggested-fix git-apply-able fix (validated: applies clean) 419 B view raw
build.sh build-log documents HW requirement 550 B view raw
run.sh run-log documents HW requirement 272 B view raw
env.txt environment guest uname and environment 491 B view raw
VERDICT.md verdict source-level analysis with path:line citations
↓ download raw

DF-2146: Unbounded AUX reply byte count causes OOB write on DP read path

Verdict: NOT REPRODUCED (HW-gated) β€” source-confirmed real bug

Reachability

NOT reachable on this QEMU guest. radeon_dp_auxch_ub926() is in sys/dev/drm/radeon/radeon_dp_auxch.c, part of radeon.ko. Requires an AMD Radeon GPU with DisplayPort. No AMD GPU present on this QEMU guest.

Mechanism (source-confirmed)

radeon_dp_auxch_ub926() at radeon_dp_auxch.c:177-191: 1. Line 65: u8 *buf = msg->buffer β€” caller-supplied buffer 2. Line 71: WARN_ON(msg->size > 16) β€” buffer max 16 bytes (commonly 1 for register reads) 3. Line 177: bytes = AUX_SW_REPLY_GET_BYTE_COUNT(tmp) β€” 5-bit MMIO field, range 0..31, sourced from the DP sink on the wire (attacker-controlled if malicious DP device) 4. Line 185-188: for (i = 0; i < bytes - 1; i++) { ... buf[i] = (tmp >> 8) & 0xff; }

If bytes > msg->size + 1 (e.g. bytes=31, msg->size=1), the loop writes up to 30 bytes into a buffer sized for 1 β†’ heap/stack OOB write.

AUX_SW_REPLY_GET_BYTE_COUNT(x) is ((x >> 24) & 0x1f) (radeon_dp_auxch.c:40) β€” a hardware register field that a malicious DisplayPort sink device can set to any value 0..31.

Primitive

  • Class: heap/stack OOB write (attacker controls write count via malicious DP device)
  • Write size: up to 30 bytes past buffer end
  • Write content: MMIO register reads (partially attacker-influenced via DP AUX protocol)

Fix

fix.diff: Clamp bytes to msg->size + 1 before the copy loop:

if (bytes > msg->size + 1)
    bytes = msg->size + 1;

Fix verification

not_testable
baseline no→ patch + rebuild →patched clean

git apply --check clean

git apply --check clean

Confirmed kernel references

β€”

Detail

Exploit chain

none (HW-gated)

Evidence (decisive lines)

HW-GATED (no Radeon GPU). Source-confirmed: AUX_SW_REPLY_GET_BYTE_COUNT 5-bit (0..31) not clamped to msg->size -> OOB write up to 30B.

Verified recommended fix

HW-GATED (no Radeon GPU). Source-confirmed: AUX_SW_REPLY_GET_BYTE_COUNT 5-bit (0..31) not clamped to msg->size -> OOB write up to 30B.

Verdict

HW-GATED (no Radeon GPU). Source-confirmed: AUX_SW_REPLY_GET_BYTE_COUNT 5-bit (0..31) not clamped to msg->size -> OOB write up to 30B.