# DF-4679 — VERDICT

**Status: REPRODUCED (verbatim-arithmetic level on the guest; full kernel
path not runnable — the QEMU guest has no Intel GPU) · impact: dos/corruption
on affected firmware · confidence: likely · fix: fixed (same level)**

## Root cause

Two of the stolen-reserved probes compute the reservation size as
`top - base` in u64:

- `g4x_get_stolen_reserved()` i915_gem_stolen.c:228 —
  `*base = (reg_val & G4X_STOLEN_RESERVED_ADDR2_MASK) << 16` (ADDR2 =
  0xFFF<<4, i915_reg.h:3507 → base up to 0x0FFF0000)
- `bdw_get_stolen_reserved()` :365 — `*base = reg_val &
  GEN6_STOLEN_RESERVED_ADDR_MASK` (0xFFF<<20, i915_reg.h:401 → base up to
  0xFFF00000)

Both registers are chipset config space programmed by firmware. If the base
lands **above** `stolen_top = dsm.end + 1`, `stolen_top - *base` wraps mod
2^64 (`resource_size_t` = uint64_t, linux/types.h:35). The wrapped size then
defeats the only downstream sanity check:

```c
dev_priv->dsm_reserved = DEFINE_RES_MEM(reserved_base, reserved_size); /* :482 */
if (!resource_contains(&dev_priv->dsm, &dev_priv->dsm_reserved)) return 0; /* :485 */
reserved_total = stolen_top - reserved_base;                    /* :493 wraps */
dev_priv->stolen_usable_size = resource_size(&dsm) - reserved_total; /* :499 */
drm_mm_init(&dev_priv->mm.stolen, 0, stolen_usable_size);        /* :503 */
```

`DEFINE_RES_MEM(start, size)` computes `end = start + size - 1`
(pci.h:626-630); with the wrapped size, `end ≡ stolen_top - 1 == dsm.end`
(mod 2^64), and `resource_contains(a,b) = a->start <= b->start && a->end >=
b->end` (pci.h:638-642) **passes** although `b->start` is above `a->end`.
(The `!reserved_base` check at :475 only catches base==0; the
`WARN_ON(ADDR1 < base)` at :226 is a warning.) The other probes are safe:
gen6/gen7/chv use fixed size fields and a masked base (containment fails
normally when base is out of range), vlv uses `top - size`, icl reads a 64-bit
masked base with fixed sizes — checked, none can wrap.

Consequence chain after :503: the drm_mm stolen allocator returns offsets up
to `usable-1` far beyond `resource_size(dsm)`; `i915_pages_create_for_stolen`
(:508-540) builds `sg_dma_address = dsm.start + offset` (:536) — the GPU DMAs
to physical memory outside stolen (kernel RAM adjacent to the stolen hole).
The `GEM_BUG_ON(range_overflows(offset, size, resource_size(dsm)))` at :516
is compiled out in release (`CONFIG_DRM_I915_DEBUG_GEM` undefined,
i915_gem.h:38-61).

## Verification

Guest `/usr/src` md5-matched to the audit tree. Harness transcribes the exact
inline helpers and size formulas; `build.sh` grep-verifies each kernel line
(`SOURCE_LINES_VERIFIED`). Baseline run (run.log):

- G4X, 32 MiB stolen [0xD00000..0x2CFFFFF], ADDR2 field 0xABC → base
  0x0ABC0000: containment PASS (bypass), usable = 2,867,855,360 = **85.47x**
  real, worst-case allocation phys 0xABBFFFFF (0x7F000000 past dsm.end).
- BDW, 32 MiB at 0x40000000, ADDR 0xFFF → base 0xFFF00000: usable
  3,220,176,896 = **95.97x**, phys 0xFFEFFFFF.
- Control (sane BIOS base 0x2C00000): usable 0.97x real, allocations inside
  stolen — isolates the wrap as the cause.

Fixed run (fix_run.log): with the `reserved_base > stolen_top` guard, both
garbage cases yield usable == real and inside-stolen allocations; control
unchanged.

## Limits of this verification (why "likely")

The wrap arithmetic, containment bypass, and usable-size inflation are proven
exactly; what could not run on this guest is the physical driver attach
(no i915 hardware) — i.e., the final "GPU DMAs to the inflated offsets" step
is traced by code reading (:503→:516/:536), not observed. The trigger is
firmware-gated (malicious/buggy BIOS, or root MMIO before attach), so this is
not an unprivileged-user bug; severity Medium (memcorrupt bucket),
exploitability ceiling on affected firmware: OOB physical memory access by
the GPU.

## Fix

One-line extension of the existing :475 sanity check (fix.diff, git-apply
clean, validated at the same arithmetic level): also ignore the reservation
when `reserved_base > stolen_top`. Note upstream Linux carries the identical
g4x/bdw code — the fix applies there verbatim.

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