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)
PoC verification
Evidence pack
findings/poc/DF-3636 Β· 5 files| File | Type | Description | Size | |
|---|---|---|---|---|
| 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:
DRM_IOCTL_I915_GEM_CREATEan object > mappable_end/2 (256 MBβ1 GB depending on gen);DRM_IOCTL_I915_GEM_MMAP_GTT+mmap()it;- 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.
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_testableTrivial deletion; cannot be kernel-validated on this guest (no i915 device).
fix.diff.
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).
No comments yet.