# DF-5834 VERDICT

**Status: reproduced** (behavioral inversion of a finite timeout into an
unbounded sleep) — **impact: none** (Info-grade: root-gated on the default
install; hang is confined to the calling thread; PCATCH/kill -9 recovers).
**The originally-suspected global tty DoS amplification was tested and
refuted** — details below.

## Root cause (path:line)

1. `sys/kern/kern_clock.c:1672` — `PPS_IOC_FETCH` enters the timeout path for
   any nonzero timeout: `if (fapi->timeout.tv_sec != 0 || fapi->timeout.tv_nsec != 0)`.
2. `sys/kern/kern_clock.c:1616-1618` — `to = INT_MAX; if (timeout->tv_sec > -1)
   to = tstohz_low(timeout);` For `{tv_sec:0, tv_nsec:1}` the condition is
   true (0 > -1), so `to = tstohz_low({0,1})`.
3. `sys/kern/kern_clock.c:1272` — `tstohz_low`: `ticks = (int)(sec * hz +
   (u_long)ts->tv_nsec / nstick)` = `(int)(0 + 1/10000000)` = **0**.
4. `sys/kern/kern_clock.c:1626` — `tsleep(pps, PCATCH, "ppsfch", 0)`.
5. `sys/kern/kern_synch.c:691` — `if (timo)` guards the timeout callout, so
   `timo == 0` means "no timeout": the thread sleeps until `wakeup(pps)`
   (a PPS edge — none on an idle serial line) or a signal (PCATCH).
   `EWOULDBLOCK` never occurs, so the `tv_sec < 0 → continue` retry at
   kern_clock.c:1628-1630 is dead for this input; the caller hangs.

PPS API semantics: `{0, 1 ns}` is a perfectly normalized *finite* timeout that
must return `ETIMEDOUT` (no event) essentially immediately.

## How it was reproduced (guest: DragonFly 6.5-DEVELOPMENT X86_64_GENERIC, hz=100)

Single-process fork rig (`ppslockdemo.c`): one fd on /dev/ttyd0 (sio0, the
serial console; ppscap=0x1133 = CAPTUREASSERT|CAPTURECLEAR|TSFMT|CANWAIT, so
`pps_ioctl` is definitively reached via sio.c:2165).

- **Control** (`ppslockdemo 0`): FETCH timeout `{0,0}` skips the timeout path
  (kern_clock.c:1672 false), returns instantly; parent `PPS_IOC_GETCAP`
  elapsed **0.000 s**. ✔
- **8 s finite wedge** (`ppslockdemo 8`): child issued `PPS_IOC_FETCH` with
  `{8,0}`; mid-wedge `ps` shows the child in state S4, **wchan `ppsfch`**;
  child's FETCH returned -1/ETIMEDOUT at t≈8 s. ✔
- **Sub-tick finite hang** (`ppslockdemo inf`): child issued FETCH with
  `{0 s, 1 ns}` — a FINITE 1-nanosecond request. At t=12 s the child was
  still asleep in wchan **`ppsfch`** with no timeout armed; only `kill -9`
  reaped it. **This is the reproduced defect.** ✔

## Amplification theory refuted (negative result, kept as evidence)

`sioioctl()` holds the global `tty_token` (taken at sio.c:294) across the
`pps_ioctl()` call in its `default:` case (sio.c:2165-2171), so an unbounded
sleep there *looked* like a system-wide tty DoS. Refuted on two independent
grounds:

- Source: `lwkt_switch()` releases all tokens of a blocking thread —
  `sys/kern/lwkt_thread.c:636-643` (`lwkt_relalltokens(td)`), the documented
  DragonFly token discipline (tokens protect running critical sections, they
  are not held across blocking).
- Live: during the 8 s wedge (child asleep in `ppsfch` "holding" the token by
  lexical scope), the parent's `PPS_IOC_GETCAP` — which must acquire
  `tty_token` through the same `sioioctl()` entry — completed in **0.000 s**
  (run.log, "WEDGE 8s" section). No other tty on the system wedges.

## Fix

`fix.diff` — after `to = tstohz_low(timeout)`, clamp `to == 0 → 1` so any
finite timeout still arms a timeout; `tv_sec < 0` keeps INT_MAX (intentional
blocking fetch). Authored from line-accurate root cause; kernel rebuild +
patched retest not performed for this Info-grade finding
(`fix_status: not_tested`).

## Attempts / iteration

3 rig runs that count (control, 8 s wedge, inf) after one rig fix: the first
`inf` invocation parsed `atoi("inf") == 0` and silently ran the control; fixed
to explicit string-compare (see `poc_changes` in verdict.json). No guest
dirty state remains (all test binaries and outputs removed; guest still up).

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