# DF-3682 — VERDICT

**Finding:** divide-by-zero in `drm_gtf_mode_complex()` (`sys/dev/drm/drm_modes.c:484-485`)
via unvalidated secondary-GTF parameters taken from a crafted EDID
(`sys/dev/drm/drm_edid.c:2188-2193`, parameters decoded by
`drm_gtf2_m/2c/k/2j()` at `drm_edid.c:2026-2055`).

**Classification:** `not_reproduced` (kernel-level), `reproduced=0`,
`impact=panic`, `confidence=certain` for the arithmetic fault and the
reachability trace.

## Was it reproduced?

* **In-kernel trigger: NO — impossible on this guest.** The QEMU guest is
  virtio-only: no `/dev/dri`, no `drm` kld, `/boot/modules` absent, and this
  tree has no virtio-gpu driver, so no DRM connector ever calls
  `drm_get_edid()`/`drm_add_edid_modes()`. The physical attack vector
  (malicious monitor / DP dongle / KVM feeding DDC) does not exist in the VM.
* **The fault itself: YES, deterministically, on the verbatim kernel code.**
  `gtf_body.inc` is a *mechanical* (python `str.index` + brace-matching, no
  hand-retyping) byte-for-byte extraction of `drm_gtf_mode_complex()` from
  `sys/dev/drm/drm_modes.c` at git `6cc80ee9`. The guest's
  `/usr/src/sys/dev/drm/drm_modes.c` is md5-identical
  (`ce51a6174062d43b24b7296cc0b3bc1e`). Compiled with the guest cc at -O2
  and fed *only* values decoded from the crafted EDID bytes
  (`evil_edid.bin`: range descriptor `r[10]=0x02, r[12]=1, r[13]=200,
  r[14]=r[15]=0, r[16]=128, r[17]=200`, std timing `{208, 0x00}`), the
  function takes an integer-divide trap: **exit 136 (SIGFPE), 3/3 runs**.
  In kernel context the identical instruction sequence raises #DE →
  DragonFly `trap()` → **panic**.

## Why the arithmetic is airtight

* `GTF_M = 0` (r[15]=r[14]=0) → `GTF_M_PRIME = K*0/256 = 0`.
* `GTF_2C = GTF_2J = 200` → `GTF_C_PRIME = ((200-200)*128/256 + 200)/2 = 100`.
* `ideal_duty_cycle = 100*1000 - 0 = 100000`.
* Divisor `100000 - ideal_duty_cycle == 0` → #DE. No overflow trickery
  needed; every intermediate is small and positive.

## Reachability trace (why the crafted EDID reaches the call)

1. `drm_do_get_edid` accepts the block: header valid, checksum valid
   (gen_edid.py enforces `sum(edid) & 0xFF == 0`), version 1 rev 4.
2. `drm_add_edid_modes` (drm_edid.c:4729) → `add_detailed_modes` first:
   DTD1 is the range descriptor with `pixel_clock = r[0..1] = 0`, so
   `do_detailed_mode` (2818: `if (timing->pixel_clock)`) adds nothing —
   the probed-mode dedup list in `drm_mode_std` (2142) stays empty.
3. `add_standard_modes` (4770) → `drm_mode_std` on std timing[0]
   `{208, 0x00}`: `bad_std_timing` no; hsize = 208*8+248 = 1912;
   aspect 00 + rev≥3 → vsize = 1912*10/16 = 1195; vrefresh 60.
4. `standard_timing_level` (2061): rev 4 ≥ 2; `features & DEFAULT_GTF`
   is clear (byte 0x1A = 0), so CVT not chosen; `drm_gtf2_hbreak()` = 2 ≠ 0
   (DTD1 r[3]=0xFD, r[10]=0x02, r[12]=1) → **LEVEL_GTF2**.
5. `drm_monitor_supports_rb` false (r[15]=0 → is_rb bit clear);
   1912x1195@60 not in DMT → falls into `case LEVEL_GTF2` (2177).
6. `drm_gtf_mode(1912,1195,60)` OK; `drm_mode_hsync(mode) ≈ 75 kHz > 2`
   (2186) → `drm_gtf_mode_complex(..., M=0, 2C=200, K=128, 2J=200)` (2188)
   → **panic at drm_modes.c:484-485**.

## Exploit chain

Not an escalation primitive: deterministic DoS/panic (sink-driven, the
DF-1165 physical threat model — a $5 DP dongle, KVM, dock, or a VM host
feeding DDC). No user→root route exists for a divide error.

## Fix validation

* `fix.diff` guards the divisor (`ideal_duty_cycle <= 0 || >= 100000` →
  destroy mode, return NULL; both call sites — `drm_mode_std`
  (drm_edid.c:2194 → returns NULL → caller 2720 checks) and the exported
  API — tolerate NULL).
* Harness-level validation executed on the guest: `gtf_fix_test.c` uses the
  same verbatim body with the guard applied → **no trap, returns NULL,
  exit 0** (`run.log`, "fix test" section).
* A full fixed-kernel build could not be meaningfully validated on this
  guest because the baseline kernel trigger itself is untestable there
  (no DRM device) → `fix_status: not_testable` at kernel level; the guard's
  effect is proven at the extracted-function level.

## Upstream-shared status

The identical formula (same unguarded division, same unvalidated GTF2
parameters) exists in upstream Linux v5.2 and is **still present in v6.6**
(`drivers/gpu/drm/drm_modes.c` — verified against
raw.githubusercontent.com/torvalds/linux). No CVE known to exist for it.
This tree's `drm_edid.c`/`drm_modes.c` are upstream-verbatim in this region
(full-file diff against v5.2 shows only DFly porting shims).

## Artifacts/evidence

* `run.log` — decisive: baseline exit 136, 3/3, fix test exit 0.
* `build.log` — full untrimmed compiler output.
* `evil_edid.bin` + `gen_edid.py` — the malicious sink payload.
* `env.txt` — guest uname, /dev/dri absence, md5 source-identity proof.

## 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.
