# DF-3687 — Signed-compare bypass in smu7_odn_edit_dpm_table: negative sysfs level passes the bounds check and wraps to a u32 wild write index

**File:** `sys/dev/drm/amd/powerplay/hwmgr/smu7_hwmgr.c` (pass 2, GLM 5.3 re-audit)
**Severity:** Low | **CVSS:** CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:N/I:H/A:H | **CWE:** CWE-197 Numeric Truncation Error; CWE-787 Out-of-bounds Write | **Confidence:** certain (source)

## What this is

Source-certain wild-write primitive gated behind root + non-default module config; runtime-inconclusive on this guest (no AMD GPU). amdgpu_set_pp_od_clk_voltage (amdgpu_pm.c:543-611) parses 's <level> <clk> <mV>' triples with kstrtol, so the level may be any signed long including negatives. smu7_odn_edit_dpm_table's guard 'input[i] >= podn_dpm_table_in_backend->num_of_pl' (:4855) compares a 64-bit signed long against uint32_t num_of_pl -> the u32 converts to long -> SIGNED compare -> -1 passes. The value is then truncated into 'uint32_t input_level' (:4859) and used as the array index at :4864-4868 into entries[8] of struct phm_odn_clock_levels (hardwaremanager.h:384-396): any u32 offset is selectable (e.g. -1 -> 0xFFFFFFFF -> +51,539,607,540 bytes) and the written values (clock/vddc/vddgfx) are range-checked but attacker-chosen within the golden OD ranges. Gating: root-only sysfs (0644) AND hwmgr->od_enabled, which requires the ppfeaturemask module param to set PP_OVERDRIVE_MASK (0x4000) - the default 0xfffd3fff clears that bit, so this is off by default. Same scoring philosophy as DF-1169 (root-only). Harness reproduces the C conversion semantics and the resulting byte offset on the guest toolchain.

## Reproduce (harness on the audit QEMU guest)

```
scp -F dfbsd-qemu/config odn_negative_level.c dfbsd-maxx:/tmp/DF-3687/
ssh -F dfbsd-qemu/config dfbsd-maxx 'cd /tmp/DF-3687 && cc -Wall -O0 -o t odn_negative_level.c && ./t'
```

Expected: the run prints the confirmed-primitive line (`RESULT: ... CONFIRMED ...`).
See `run.log` (and `run.2.log` where present) for the decisive captured output,
`build.log` for the guest toolchain transcript, `env.txt` for the guest environment
(virtio-only, **no AMD GPU** — `pciconf -l` shows only 0x1237/0x1111 QEMU devices;
`drm.ko`/`amdgpu.ko` exist in /boot/kernel but are not loaded and have no hardware
to bind), which is why the in-kernel trigger itself is inconclusive on this guest.

## Fix

`fix.diff` (authored against the read-only sys/ tree; never applied there).
