# DF-4621 — amdgpu_dm debugfs: OR-combined `valid_input` accepts invalid lane_count → stack OOB write in `dp_phy_settings_write` (LATENT: file not compiled)

## What
`dp_link_settings_write()` validates the two user parameters with a single
OR-combined flag (sys/dev/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c:195-221):

```c
	switch (param[0]) {          /* lane_count */
	case LANE_COUNT_ONE: ... valid_input = true; ...
	switch (param[1]) {          /* link_rate */
	case LINK_RATE_LOW: ... valid_input = true; ...   /* same flag! */
	if (!valid_input) { ... return; }
```

`echo "5 a" > link_settings` (or `echo ffffffff a`) passes with an **invalid
lane_count** because the link_rate matched. The value is then stored
**unvalidated** into `link->preferred_link_setting` by
`dc_link_set_preferred_link_settings()` (dc/core/dc.c:484), and consumed:

1. **dp_phy_settings_write (:386-410)** — when `test_pattern_enabled`,
   `link_lane_settings.link_settings.lane_count =
   link->preferred_link_setting.lane_count`, then
   `for (r = 0; r < lane_count; r++) link_lane_settings.lane_settings[r] = …`
   writes **past `lane_settings[LANE_COUNT_DP_MAX = 4]`**
   (include/link_service_types.h:71-75; LANE_COUNT_DP_MAX = LANE_COUNT_FOUR,
   dc/dc_dp_types.h:37). lane_count=5 → 12-byte stack overrun;
   lane_count=0xffffffff → unbounded linear stack smash (values constrained
   to enum triples 0..3 per 4-byte slot). `link_lane_settings` is a local —
   stack OOB write (CWE-787).
2. **decide_link_settings()** (dc/core/dc_link_dp.c:1517-1525, *live* code)
   returns `*link_setting = link->preferred_link_setting` verbatim → invalid
   lane_count propagates into link training (`lt_settings.lane_settings[]`
   walks, DPCD lane writes).

## Liveness (verified this run — honest status)
The file is **doubly dead** in DragonFly: it is absent from
`sys/dev/drm/amdgpu/Makefile` SRCS (lines 195-201 list amdgpu_dm.c,
amdgpu_dm_irq.c, amdgpu_dm_mst_types.c, **amdgpu_dm_color.c**, services,
helpers, pp_smu — not this file), and its only two callers are compiled under
`#if defined(CONFIG_DEBUG_FS)` (amdgpu_dm.c:478-479 `dtn_debugfs_init`,
:4119-4120 `connector_debugfs_init`), which is not defined (sys/dev/drm/kconfig.h).
So today this is an **enable-day hazard** (turning on debugfs builds without
also fixing validation), consistent with DF-1764/DF-1765/DF-4554 precedent.
The guest also has no AMD GPU (`pciconf`: no AMD devices).

## What runs today
`dp_link_logic_demo.c` transcribes the validation logic (:195-221) and the
consumer loop (:394-410) 1:1 and runs on the guest — gcc itself flags the OOB
iteration (`warning: iteration 4 invokes undefined behavior`):

```
input: lane_count=5 (invalid), link_rate=0xa (valid)
ACCEPTED by the single valid_input flag (amdgpu_dm_debugfs.c:195-221)
stored preferred_link_setting.lane_count = 5 (dc.c:484, unvalidated)
loop iteration r=4: OOB write at &lane_settings[4] -- past lane_settings[LANE_COUNT_DP_MAX-1=3]
```
(demo_run.log; a transcription logic-proof, NOT a kernel run — see VERDICT.md)

## Fix
`fix.diff` splits the flag into `valid_lane_count` / `valid_link_rate` and
requires both (`if (!valid_lane_count || !valid_link_rate)`).
