# DF-3634 VERDICT

**Status: inconclusive (runtime) / certain (source).**
**Impact if reachable: kernel stack info leak (8 bytes/call, unlimited).**

## Why the bug is certain from source

1. `sys/dev/drm/i915/i915_gem.c:1923` — `unsigned long addr;` is a plain
   uninitialized local.
2. `sys/dev/drm/i915/i915_gem.c:1961-1962` — the DragonFly-only
   `if (args->size == 0) goto out;` bypasses the first assignment of
   `addr` at `:1977` (`addr = round_page((vm_offset_t)p->p_vmspace->vm_taddr
   + maxtsiz + maxdsiz)`).
3. `sys/dev/drm/i915/i915_gem.c:2056-2067` — the `out:` tail performs
   `if (IS_ERR((void *)addr))` and `args->addr_ptr = (uint64_t) addr;`
   with `error == 0` on this path, i.e. success + stale stack bytes
   copied into the ioctl out-argument.
4. Nothing between (2) and (3) assigns `addr` on this path
   (`DRM_DEBUG` at :1949 only prints args/obj).
5. The ioctl is unprivileged-reachable: `DRM_IOCTL_DEF_DRV(I915_GEM_MMAP,
   i915_gem_mmap_ioctl, DRM_RENDER_ALLOW)` — `sys/dev/drm/i915/i915_drv.c:3246`;
   the only precondition is a valid GEM handle, creatable via
   `DRM_IOCTL_I915_GEM_CREATE` (also RENDER_ALLOW, `i915_drv.c:3243`).

CWE-457 (use of uninitialized variable) / CWE-909. Comparable class:
the historic DRM_INFO-leak family of uninit ioctls.

## Verification performed

- PoC written with uapi structs/ioctl numbers matched 1:1 against
  `sys/dev/drm/include/uapi/drm/i915_drm.h`
  (`DRM_I915_GEM_CREATE=0x1b`, `DRM_I915_GEM_MMAP=0x1e`,
  `DRM_COMMAND_BASE+nr`, struct layouts verified at
  i915_drm.h:638 and i915_drm.h:686).
- Built on the DragonFly audit guest: `BUILD-OK` with `cc -O2 -Wall`,
  zero warnings (build.log).
- Execution impossible on this guest: `open("/dev/dri/card0")` → ENOENT;
  guest GPU is virtio (`chip=0x11111234`), no drm klds, i915 cannot
  probe (run.log). No Intel GPU emulation exists for this QEMU setup.
- No runtime divergence attempted via i915 module load: i915 is a PCI
  driver; without an Intel VGA PCI id it never attaches and creates no
  /dev/dri node (checked `pciconf -l`).

## Exploit chain (on real hardware)

unprivileged open("/dev/dri/renderD128") → DRM_IOCTL_I915_GEM_CREATE
(handle) → loop: interleave arbitrary syscalls (to seed the thread's
kernel stack with interesting values) with DRM_IOCTL_I915_GEM_MMAP
{handle, size=0} → read `args->addr_ptr` = 8 bytes stale kernel stack.
Use for pointer disclosure / KASLR defeat; combine with any memory
corruption primitive (e.g. DF-1146 in the same driver) for full
compromise.

## Fix validation

fix.diff authored against the read-only sys/ tree (reject size==0 with
-EINVAL before the reference-counted map is attempted; also prevents
the pointless object lookup/reference churn). Not applicable to build
on this guest (no i915 device to test against), so
fix_status=not_testable; the fix makes the uninit read unreachable by
construction (early return).

## Kernel references

- sys/dev/drm/i915/i915_gem.c:1923 (declaration, uninit)
- sys/dev/drm/i915/i915_gem.c:1961-1962 (DFly early-out bypassing init)
- sys/dev/drm/i915/i915_gem.c:1977 (first assignment, skipped)
- sys/dev/drm/i915/i915_gem.c:2056-2067 (uninit use → userspace leak)
- sys/dev/drm/i915/i915_drv.c:3246 (DRM_RENDER_ALLOW registration)

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