# DF-4980 VERDICT

**Status: untested · Impact: none (on DragonFly) · Confidence: likely**
(certainty of the *code defect* is high — the line-by-line chain is proven
below; "likely" reflects that the exploitable manifestation requires
Linux-allocator semantics or DF kernel-map exhaustion).

## The defect (proven from source)

`amdgpu_atomfirmware_allocate_fb_scratch()` sizes a kernel allocation from an
untrusted VBIOS field and returns `-ENOMEM` on failure
(`sys/dev/drm/amd/amdgpu/amdgpu_atomfirmware.c:99,106-108`); the sole caller
ignores the return (`sys/dev/drm/amd/amdgpu/amdgpu_atombios.c:2046`), and two
consumers use `atom_context->scratch` without any NULL guard
(`sys/dev/drm/amd/amdgpu/atombios_dp.c:74-76` — write via `copy_swap` to
`scratch + 1`; `sys/dev/drm/amd/amdgpu/atombios_i2c.c:54,104` — read). The
legacy twin has the identical shape (`amdgpu_atombios.c:1781-1822`,
ignored at `:2049`) and is the reachable instance on classic ASICs
(dce8/10/11 use atombios_dp/atombios_i2c by default).

## Why the impact ceiling on DragonFly is "none"

1. `kzalloc(size, GFP_KERNEL)` → `kmalloc(size, M_DRM, M_WAITOK|M_CACHEALIGN|M_ZERO)`
   (`sys/dev/drm/include/linux/slab.h:35`,
   `sys/dev/drm/include/linux/gfp.h:40`). DF `M_WAITOK` without `M_NULLOK`
   never yields NULL — failure panics inside the allocator
   (`sys/kern/kern_slaballoc.c:1721-1727`). So `if (!ctx->scratch)` at
   `amdgpu_atomfirmware.c:107` is dead code on DF; the NULL+4 write chain
   (real on Linux) cannot execute here.
2. The atom-interpreter FB paths are guarded by `scratch_size_bytes`
   (`sys/dev/drm/amd/amdgpu/atom.c:273-278,529-533`), so no interpreter path
   derefs the buffer unguarded.
3. On the atomfw (Vega10+) path the unguarded dp/i2c consumers are not wired
   in this tree (no dce12 classic CRTC file exists; Vega10 classic falls back
   to dce_virtual which creates no DP/hw-I2C connectors; DC uses its own AUX).
   The reachable instance is the *legacy* twin on dce8/10/11 ASICs.
4. Residual DF exposure: crafted VBIOS `used_by_driver_in_kb = 0xFFFF` forces
   a 64 MB `M_WAITOK` allocation at attach — succeeds on a healthy system,
   panics via `kmem_slab_alloc` only under kernel-map exhaustion, or blocks
   indefinitely under memory pressure. Defense-in-depth fix warranted, no
   demonstrated unprivileged trigger.

## Reproduction

Not applicable: the DF verification guest has no AMD GPU (`amdgpu` never
attaches), and the defective branch is provably dead on DF (point 1). A Linux
reproduction would be: classic ASIC (e.g. polaris), fail the kzalloc (fault
injection / memory pressure), hotplug a DP monitor → panic at
`amdgpu_atombios_copy_swap` writing to (NULL+4).

## Fix validation

`fix_status: not_testable` — fix.diff clamps the untrusted size to the
driver's own 20 KB default and propagates the error from both branches of
`amdgpu_atombios_init()`. No kernel-build validation was performed (Info
finding, no guest amdgpu device; the change is error-plumbing only and cannot
be exercised on the guest).

## Cross-references

- DF-2027 (pass 1, same file): all table parsers deref unvalidated
  `bios + data_offset` — the *offset* OOB class. This finding is the
  *ignored-error / untrusted-size* class, distinct and not a re-report.
- DF-4884/DF-4885: amdgpu_bios double-free + off-by-one (context).
- Upstream: file byte-identical to Linux v5.0; master still ignores the
  return (amdgpu_atombios.c:1935 as of 2026-09-25).

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