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)
PoC verification
Evidence pack
findings/poc/DF-2146 Β· 6 files| File | Type | Description | Size | |
|---|---|---|---|---|
| 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 |
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_testablegit 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.
No comments yet.