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

Leftover debug kprintf("i915_gem_fault: CHUNKING PASS") on the unprivileged per-fault partial-view path enables console/log-flood DoS

Summary

A DragonFly-port debug print (absent from the Linux original) executes once per GTT page fault whenever the faulting object exceeds half the mappable aperture and takes the partial-view branch - hundreds of thousands of console-rendered printf's from one unprivileged mmap loop. Unprivileged render-node user: GEM_CREATE an object >256MB-1GB, MMAP_GTT, mmap, touch every page -> ~262k console printf's for a 1GB object. DragonFly console printf renders serially (worse on serial console): system-wide slowdown/stall plus unbounded /var/log and dmesg-ring flooding. Local DoS only. Fix: delete the print.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-3636 Β· 5 files
FileTypeDescriptionSize
README.md β€” 2.1 KB ↓ raw
VERDICT.md β€” 1.8 KB ↓ raw
fix.diff β€” 320 B view raw
manifest.json β€” 618 B view raw
verdict.json β€” 2.1 KB view raw

DF-3636 β€” Leftover debug kprintf("i915_gem_fault: CHUNKING PASS\n") on the unprivileged partial-view fault hot path

What

sys/dev/drm/i915/i915_gem.c:2323:

2315    vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0,
2316                       PIN_MAPPABLE |
2317                       PIN_NONBLOCK |
2318                       PIN_NONFAULT);
2319    if (IS_ERR(vma)) {
2320        /* Use a partial view if it is bigger than available space */
2321        struct i915_ggtt_view view =
2322            compute_partial_view(obj, page_offset, MIN_CHUNK_PAGES);
2323        kprintf("i915_gem_fault: CHUNKING PASS\n");

This is a port-time debug print (not present in the Linux original β€” upstream 4.17 has no printk on this path) left in the production fault path for partial GTT views. It executes once per page fault whenever an object larger than half the mappable aperture (the PIN_NONBLOCK half-aperture heuristic, i915_gem.c:4853-4855) is GTT-mapped and touched.

Threat

Any unprivileged user with DRM render access can, without any authentication:

  1. DRM_IOCTL_I915_GEM_CREATE an object > mappable_end/2 (256 MB–1 GB depending on gen);
  2. DRM_IOCTL_I915_GEM_MMAP_GTT + mmap() it;
  3. touch every page in a loop.

Each 4 KiB fault prints a line to the console (and kern.msgsyslog). A 1 GB object on a 2 GB-mappable part β‰ˆ 262 144 kernel printf's, serially rendered β€” the DFly console (especially serial console) is notoriously slow at rendered printf, so this is both a system-wide slowdown and unbounded log/disk flooding (/var/log/messages, dmesg ring churn). CWE-117-adjacent (unbounded diagnostic output from untrusted input) β†’ local DoS / log-flood. Low severity (no memory-safety impact).

Verification

Source-certain (the kprintf is directly on the fault path); not runtime testable on this guest (no i915 device β€” see DF-3634/run.log). Status: untested.

Fix

Delete the kprintf (fix.diff). The other fault-path kprintfs ("i915: caught bug(...)" at :2301, :2307, :2345, :2353, :2359, :2478, :2500) fire only on genuine error conditions and are ratelimited by their nature; CHUNKING PASS is the only unconditional per-fault print.

VERDICT.md
↓ download raw

DF-3636 VERDICT

Status: untested (runtime) / certain (source). Severity Low.

Root cause

sys/dev/drm/i915/i915_gem.c:2323 β€” kprintf("i915_gem_fault: CHUNKING PASS\n"); sits unconditionally inside the partial-view branch of the GTT page-fault handler. This print has no counterpart in the upstream Linux code this file was ported from (Linux 4.17-era i915_gem_fault()); it is DragonFly-port debug residue.

Trigger path (unprivileged)

DRM_IOCTL_I915_GEM_MMAP_GTT (DRM_RENDER_ALLOW, i915_drv.c:3247) β†’ mmap() the fake offset β†’ touch pages. For any object larger than ggtt.mappable_end / 2 (i915_gem.c:4853-4855 PIN_NONBLOCK heuristic; 256 MB–1 GB typical) the first full-object pin fails with -ENOSPC at :2319, every single fault then takes the partial-view branch and prints. One printf per 4 KiB page; a 1 GB object β‰ˆ 262k printf's, serially rendered on the console. On DFly, console printf renders character-by-character (much worse on serial console) β€” this is a straightforward unauthenticated local slowdown/log-flood (console freeze for other users, /var/log flooding, dmesg ring churn).

Why not reproduced

Guest is virtio-only: no /dev/dri, no i915 attachment possible (evidence in ../DF-3634/run.log and env.txt). The print is directly on the fault path in source; no race or state needed.

Impact ceiling

Local DoS (log flood / console stall) β€” Low. No memory-safety impact.

Fix

fix.diff removes the kprintf. No behavioral change otherwise.

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.

Fix verification

not_testable
baseline no→ patch + rebuild →patched clean

Trivial deletion; cannot be kernel-validated on this guest (no i915 device).

fix.diff.
↓ fix.diffper-fix-DF-3636

Confirmed kernel references

Detail

Exploit chain

open render node -> GEM_CREATE(>=256MB-1GB) -> MMAP_GTT + mmap + touch all pages -> one console printf per 4K fault -> console/log flooding, system-wide slowdown.

Evidence (decisive lines)

VERDICT.md; fix.diff (removal). Decisive line: i915_gem.c:2323 inside the IS_ERR(vma) partial-view branch taken per-fault for oversized objects.

PoC changes

No runnable PoC (no i915 device on audit guest); trigger documented in README.md.

Verified recommended fix

Remove the kprintf at i915_gem.c:2323 (fix.diff).

Verdict

Source-certain debug-print DoS, not runtime-testable on this guest (no i915 device). kprintf("i915_gem_fault: CHUNKING PASS\n") at sys/dev/drm/i915/i915_gem.c:2323 executes once per GTT page fault on the partial-view path (object > mappable aperture /2), i.e. up to hundreds of thousands of console-rendered printf's from one unprivileged DRM_RENDER_ALLOW mmap loop (MMAP_GTT registered at i915_drv.c:3247). DragonFly-port debug residue absent from the Linux original. Local console stall / log-flood DoS; no memory-safety impact. Fix: delete the print (fix.diff).