# DF-5183 — Verification Verdict

**Status:** reproduced (deterministic)
**Impact:** dos (low-grade: 1 Hz poll loop per "infinite" waiter; latent
unkillable-wait contract violation)
**Confidence:** certain

## What was reproduced

On the QEMU/KVM guest (DragonFly 6.5-DEVELOPMENT #0, X86_64_GENERIC,
6 vCPU, cc 8.3), module `lwqdemo.ko` (which links the pristine
`sys/dev/drm/linux_wait.c`):

1. `tsleep((void *)&f3_word, 0, "lwqf3", (int)MAX_SCHEDULE_TIMEOUT)`
   with **no waker** returned `rv=35` (EWOULDBLOCK) after **2 ticks**
   (run.log, first `LWQ-F3:` line; reproduced on two boots). An
   "infinite" timeout truncates `(unsigned long)LONG_MAX → int −1`;
   `_callout_setup_quick()` clamps the negative expiry to the next tick
   (kern_timeout.c:971-972), so the sleep expires immediately.
   Consequence inside `wait_on_bit_timeout()`: the do-while loop
   (linux_wait.c:117-123) re-enters tsleep every tick — a 1 Hz poll
   loop for every `wait_on_bit()` caller (i915_irq.c:3341,
   i915_irq.c:3199) instead of a blocking sleep.

2. `wait_on_bit_timeout(&f3_word, 0, TASK_UNINTERRUPTIBLE,
   MAX_SCHEDULE_TIMEOUT)` on a never-cleared bit exited only when the
   harness cleared the bit 5 s later (rv=0, 396 ticks) — i.e. the
   function's exit is driven by the bit test, never by the "infinite"
   timeout bookkeeping, consistent with the polling behavior above.

The `mode`→flags half of the finding is source-certain rather than
runtime-demonstrated (kernel threads cannot receive signals, so PCATCH
inertness cannot be shown from a KLD): `tsleep(word, mode, ...)` at
linux_wait.c:118 with mode ∈ {0,1,2,3} never sets `PCATCH` (0x100,
sys/sys/param.h:324) and puts the low bits into `PWAKEUP_CPUMASK`,
which tsleep ignores apart from `td_wdomain = flags & PDOMAIN_MASK`
(kern_synch.c:448). A future caller passing `TASK_INTERRUPTIBLE`
gets an unkillable uninterruptible sleep — the opposite of the Linux
contract (wait.h/wait_bit.h export this API tree-wide).

## Reachability

Kernel-internal API used by i915 reset/handoff paths
(i915_irq.c:3199, i915_irq.c:3341 — active with
TASK_UNINTERRUPTIBLE) and exported to every drm driver via
`<linux/wait_bit.h>`. No unprivileged direct entry on the QEMU guest
(no drm device); the PoC drives the primitive from a root-loaded KLD.

## Fix

`fix.diff`: translate `mode & TASK_INTERRUPTIBLE` → `PCATCH` and clamp
`timeout >= INT_MAX || timeout == MAX_SCHEDULE_TIMEOUT` to `timo = 0`
(tsleep's "no timeout"). Mechanical, not kernel-rebuild-validated
(Low-severity logic finding).

## Relationship to known findings

DF-2181 owns the broken `time_after_eq(start_time, timeout)` expiry
test; DF-2182 owns the missing `tsleep_interlock` in this same
function. This finding is the two *other* parameter-handling defects at
the same call site (mode→flags mapping and unsigned-long→int timeout
truncation) — distinct root causes, distinct fix lines. The
reproduction also corrects the record: a `wait_on_bit()` waiter does
not literally "sleep forever" on a lost wake — it polls at 1 Hz due to
this truncation.

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