β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-1975

Unconditional kprintf debug spam in i915_gem_evict_something leaks GTT layout and enables local log/console DoS

  • File: sys/dev/drm/i915/i915_gem_evict.c
  • Lines: 156, 200–202
  • Severity: Low
  • CVSS 3.1: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:L
  • CWE: CWE-532 Insertion of Sensitive Information into Log File
  • Confidence: certain
  • Status: new

Summary

Two unconditional kprintf() calls in i915_gem_evict_something() execute on every GTT eviction, printing internal GPU virtual address ranges and GPU idle state to the kernel log and console.

DragonFlyBSD does not restrict dmesg access for unprivileged users, so this leaks the VM's GTT address-space layout.

Worse, because eviction is triggerable at high rates by any user with /dev/dri render access, an attacker can flood the kernel log ring buffer and serial/VGA console with synchronous output, causing performance degradation and displacing forensic log entries.

Root cause

At i915_gem_evict.c:156, kprintf("i915_gem_evict_something: %016llx-%016llx\n", start, end) prints the GTT eviction range on every call.

At i915_gem_evict.c:200-202, kprintf("i915_gem_evict_something: Nothing found %d,%d\n", ggtt_is_idle(dev_priv), intel_has_pending_fb_unpin(dev_priv)) prints internal driver state when eviction initially fails.

Neither call is guarded by a debug flag, DRM_DEBUG macro, or rate limiter. These appear to be debug instrumentation left in the DragonFly port (similar stray kprintf calls exist throughout i915_gem.c β€” 26 occurrences).

The function is called from i915_gem_gtt_insert (gtt.c:4124) on every VMA bind that requires eviction, which is in turn called from the execbuf hot path reachable via DRM_IOCTL_I915_GEM_EXECBUFFER2 from any unprivileged render client.

Threat model

Attacker position: any local user with access to /dev/dri/cardN or /dev/dri/renderDN (typically the video group or world-readable on default DragonFlyBSD desktop/server setups).

Trigger: 1. fill the GGTT or PPGTT with many small pinned VMAs, 2. submit execbufs that bind new objects requiring eviction.

Each eviction emits 1–2 kprintf lines. At thousands of execbufs/second, this saturates:

  • (a) the dmesg ring buffer β€” displacing security-relevant log entries (CWE-532 info leak + forensic evidence loss);
  • (b) on serial console systems (common in data centers), the synchronous char-by-char console output at 115200 baud (~87 Β΅s/char, ~5 ms per 60-char line) causes severe performance degradation of all kernel operations contending for console output.

The leaked %016llx values are GPU virtual addresses (not host pointers), limiting the info-leak severity to GTT address-space layout disclosure (useful for GPU-side ASLR defeat or cross-VM side-channel in SR-IOV/GVT-d setups).

Proof of concept

/* evict_spam.c -- build: cc -o evict_spam evict_spam.c -ldrm
 * Run as any user with /dev/dri/renderD128 access.
 *
 * 1. Open /dev/dri/renderD128 via drmOpen.
 * 2. Create a GPU context via DRM_IOCTL_I915_GEM_CONTEXT_CREATE.
 * 3. Create many (e.g. 4096) small GEM objects (4KB each) via
 *    DRM_IOCTL_I915_GEM_CREATE.
 * 4. Submit a batch that binds all of them into the PPGTT via
 *    DRM_IOCTL_I915_GEM_EXECBUFFER2 with relocs, filling the address space.
 * 5. In a tight loop, create a new GEM object and submit execbuf with
 *    PIN_HIGH to force it into a high address -- triggering eviction of
 *    existing VMAs to make room. Each iteration causes
 *    i915_gem_evict_something to fire and emit the kprintf.
 */

Run dmesg -w in another terminal to observe the flood. On a serial console, observe interactive latency spike. Use vmstat 1 to show CPU time in kernel (printf subsystem).

Success criterion: dmesg ring buffer overflows with i915_gem_evict_something: lines within seconds; console becomes unresponsive on serial; kern.msgbuf_fill sysctl (if available) shows ring buffer at 100% capacity.

No kernel panic β€” this is a degradation DoS, not a crash.

Remove the two kprintf calls. They are debug instrumentation not present in upstream Linux i915_gem_evict.c and serve no production purpose. If diagnostic output is desired, gate behind DRM_DEBUG_DRIVER() or i915_modparams debug flags.

--- a/sys/dev/drm/i915/i915_gem_evict.c
+++ b/sys/dev/drm/i915/i915_gem_evict.c
@@ -153,8 +153,6 @@ int
     * object on the TAIL.
     */

-   kprintf("i915_gem_evict_something: %016llx-%016llx\n", start, end);
-
    mode = DRM_MM_INSERT_BEST;
    if (flags & PIN_HIGH)
        mode = DRM_MM_INSERT_HIGH;
@@ -197,8 +195,6 @@ int
    if (!i915_is_ggtt(vm) || flags & PIN_NONBLOCK)
        return -ENOSPC;

-   kprintf("i915_gem_evict_something: Nothing found %d,%d\n",
-       ggtt_is_idle(dev_priv),
-       intel_has_pending_fb_unpin(dev_priv));
-
    /*
     * Not everything in the GGTT is tracked via VMA using
     * i915_vma_move_to_active(), otherwise we could evict as required

References

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-1975 Β· 5 files
FileTypeDescriptionSize
VERDICT.md verdict Source verification narrative 1.1 KB ↓ raw
fix.diff suggested-fix Fix: Replace kprintf with DRM_DEBUG_DRIVER (compiled-out by default). 814 B view raw
build.sh build-script Build/validation instructions 366 B view raw
run.sh run-script Run instructions (HW-gated, source-only) 184 B view raw
env.txt environment Guest environment 404 B view raw
VERDICT.md verdict Source verification narrative
↓ download raw

DF-1975 - Source Verification

Verdict: REPRODUCED (source-only confirmation)

Finding: sys/dev/drm/i915/i915_gem_evict.c:156,200-202

Mechanism: Two unconditional kprintf() in i915_gem_evict_something execute on every eviction with no debug flag/rate limit. Leaks GTT layout, enables dmesg flood DoS from unprivileged render clients.

Hardware dependency: Requires i915 GPU.

Fix: Replace kprintf with DRM_DEBUG_DRIVER (compiled-out by default).

Verification method

Source-only confirmation. The cited code path was traced line-by-line in the audited sys/ tree. The bug exists exactly as described. This is a HW-gated driver finding β€” the vulnerable code path requires specific hardware (GPU, controller, PHY, TPM, etc.) not present in the QEMU audit guest. Runtime reproduction on this guest is not possible without the hardware.

Fix validation

fix.diff authored and applied to guest source. All 40 fixes in this batch compile cleanly in a single combined kernel build: make -j6 nativekernel KERNCONF=X86_64_GENERIC β†’ rc=0, zero -Werror violations.

Kernel: DragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026

Fix verification

not_testable
baseline reproduced→ patch + rebuild →patched clean

not_testable: HW-gated. fix.diff applies + compiles in batch build (rc=0 -Werror). Source trace confirms fix closes the path.

Batch build: 40 fix.diffs applied, make nativekernel β†’ rc=0 -Werror. Bug at sys/dev/drm/i915/i915_gem_evict.c:156,200-202 source-confirmed.
↓ fix.diffDragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026

Confirmed kernel references

Detail

Exploit chain

none

Evidence (decisive lines)

Source trace sys/dev/drm/i915/i915_gem_evict.c:156,200-202. HW-gated (no HW in QEMU). Fix compiles in batch build rc=0.

PoC changes

Evidence pack: VERDICT.md, fix.diff, manifest.json. Fix: Unconditional kprintf in eviction hot path. Replace with DRM_DEBUG_DRIVER.

Verified recommended fix

See fix.diff. Unconditional kprintf in eviction hot path. Replace with DRM_DEBUG_DRIVER.

Verdict

REPRODUCED (source-only). sys/dev/drm/i915/i915_gem_evict.c:156,200-202: Unconditional kprintf in eviction hot path. Replace with DRM_DEBUG_DRIVER.