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

set_dp_phy_pattern_80bit_custom() ignores param->custom_pattern_size and unconditionally reads pattern[0..9] (latent OOB read for future callers)

Summary

The function reads exactly 10 bytes from custom_pattern while the parameter struct carries a size field it never checks. Every in-tree caller currently passes a fixed 10-byte buffer, so nothing reads OOB today. Hardening: any future caller honoring the size field with a shorter buffer gets a kernel OOB read whose contents are programmed into the DPHY test registers. Honor-the-size fix.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-4384 Β· 2 files
FileTypeDescriptionSize
README.md β€” 1.5 KB ↓ raw
VERDICT.md β€” 1.4 KB ↓ raw

DF-4384 (Info) - set_dp_phy_pattern_80bit_custom() ignores

param->custom_pattern_size

What

dcn10_link_encoder.c:set_dp_phy_pattern_80bit_custom() (sys/dev/drm/amd/display/dc/dcn10/dcn10_link_encoder.c:292-335) reads pattern[0]..pattern[9] unconditionally. The parameter struct carries an explicit size field that the function never consults:

struct encoder_set_dp_phy_pattern_param {
        ...
        const uint8_t *custom_pattern;      /* inc/hw/stream_encoder.h:75 */
        uint32_t custom_pattern_size;       /* inc/hw/stream_encoder.h:76 */
};

All in-tree callers currently pass a fixed 10-byte buffer (dc_link_dp.c:1799/1871-1876/1912-1914 reads exactly sizeof(test_80_bit_pattern)==10 from DPCD; amdgpu_dm_debugfs.c:607-615/654-666 copies 10 param bytes and passes 10). So there is NO out-of-bounds read in this tree today - this is a latent API-contract hazard (CWE-125) for any future caller that passes a shorter buffer with custom_pattern_size < 10 (the field exists precisely to allow that).

Guest verification

Not testable: the QEMU guest has no AMD DCN10 display hardware, so the DC link-encoder path never executes. Static analysis only (per the pass-1 dce_link_encoder checklist the identical dce110 function was reviewed clean).

Suggested fix

Honor the size: if (param->custom_pattern_size < 10) return; / or BREAK_TO_DEBUGGER()/clamp / inside dcn10_link_encoder_dp_set_phy_pattern()'s DP_TEST_PATTERN_80BIT_CUSTOM case (dcn10_link_encoder.c:1099-1102).

VERDICT.md
↓ download raw

VERDICT - DF-4384 (Info, not tested live - no AMD hardware on guest)

Class: latent API hazard / hardening (CWE-125 for future callers). Severity: Info. Confidence: certain (code-provable), impact none today.

  • Function: dcn10_link_encoder.c:292-335 (called from dcn10_link_encoder_dp_set_phy_pattern, dcn10_link_encoder.c:1099-1102).
  • custom_pattern_size exists (stream_encoder.h:75-76) and is ignored.
  • Both kernel-side call chains pass fixed 10-byte buffers:
  • dp_test_send_phy_test_pattern(): core_link_read_dpcd of exactly DP_TEST_80BIT_CUSTOM_PATTERN_7_0..79_72 (10 bytes) into a local array (dc_link_dp.c:1871-1876, 1912-1914);
  • amdgpu_dm debugfs test_pattern write: copies 10 bytes from the user token into custom_pattern[10] and passes 10 (amdgpu_dm_debugfs.c:654-666).
  • Guest has no AMD GPU (QEMU std VGA); the path cannot execute there.

Not a vulnerability in this tree; filed as Info so the contract violation is on record (the same pattern exists in dce_link_encoder.c:327).

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.

(No fix.diff for this item: documented recommendation only - see Fix above.)

Fix verification

not_testable
baseline no→ patch + rebuild →patched clean

n/a (Info-level latent hazard; no runtime test possible on this guest)

n/a
per-fix-DF-4384

Confirmed kernel references

Detail

Evidence (decisive lines)

VERDICT.md (call-chain citations)

PoC changes

n/a (static finding)

Verified recommended fix

validate custom_pattern_size >= 10 in dp_set_phy_pattern before calling set_dp_phy_pattern_80bit_custom

Verdict

Latent OOB-read hazard: set_dp_phy_pattern_80bit_custom() ignores param->custom_pattern_size and always reads pattern[0..9]. Every in-tree caller passes a fixed 10-byte buffer, so nothing is readable out of bounds today; Info/hardening only. Not live-testable: guest has no AMD DCN10 hardware.