# DF-5842 — select(2)/pselect(2)/ppoll(2) accept invalid timeouts unvalidated; long timers collapse

## What

`sys/kern/sys_generic.c` copies the user timeout into the kernel and passes
it straight into `kern_kevent()` with **no range or normalization check**:

- `sys_select()`  `:807-815` — timeval, no check
- `sys_pselect()` `:842-849` — timespec, no check
- `sys_ppoll()`   `:1271-1278` — timespec, no check

(`sys_poll()`'s computed `{timeout/1000, (timeout%1000)*1e6}` is always
valid, so only the timeout-pointer syscalls are affected.)

Inside `kern_kevent()` (`sys/kern/kern_event.c:872-1000`) the raw value is
added to the current uptime and later converted by `tstohz_high()`
(`sys/kern/kern_clock.c:1227+`) or, for ppoll (`KEVENT_TIMEOUT_PRECISE`),
by `ustimeout = atx.tv_sec * 1000000 + atx.tv_nsec / 1000`
(`kern_event.c:975`) — both of which **overflow/truncate** for unnormalized
huge sub-second fields, and both of which treat negative targets as
"already expired".

Contrast: the `nd == 0` / `nfds == 0` paths of the very same syscalls go to
`dotimeout_only()` → `nanosleep1()` → `clock_nanosleep1()`, which DOES
reject `tv_sec < 0 || tv_nsec < 0 || tv_nsec >= 1000000000` with EINVAL
(`sys/kern/kern_time.c:467`).

## Demonstrated (unprivileged, deterministic over 3 runs)

| test | call | POSIX | DragonFly observed |
|------|------|-------|--------------------|
| T1  | `pselect(pipe, {tv_sec:-1})`            | EINVAL | **rc=0 in ~20-90 µs** |
| T2  | `ppoll(pipe, {tv_nsec: 2^62})`          | EINVAL | **rc=0 after ~1.7-2.0 s** (intended ~146 years!) |
| T2b | `ppoll(pipe, {tv_sec:-1})`              | EINVAL | rc=0 in ~15 µs |
| T3  | `select(pipe, {tv_usec:-5})`            | EINVAL | rc=0 in ~20 µs |
| T7  | `select(pipe, {tv_usec: 1500000})`      | EINVAL | rc=0, sleeps 1.5 s |
| T8  | `select(pipe, {tv_usec: 2^62})`         | EINVAL | **rc=0 in ~40-70 µs** (intended ~146 years) |
| T4/T5 | controls `{2s}` / `{0.5s}`            | —      | 2.000 s / 0.500 s (rig sane) |
| T6  | `select(0 fds, {tv_sec:-1})`            | EINVAL | **EINVAL** (nd==0 path validates) |

Impact: any long-intended poll/select/watchdog built on these syscalls can
be made to return immediately or after an arbitrary wrong duration by an
unprivileged caller; POSIX conformance violation. Same observable class as
DF-5835 (kern_clock.c converters) but a distinct defect and fix location:
**missing validation at these syscall entries**, plus overflow sites
(`kern_event.c:975` precise multiply; `tvtohz_high` huge-usec `(int)` cast)
that only see garbage because the entries let it through.

## Reproduce

```
build.sh   # cc -O -o /tmp/timeout_rig /tmp/timeout_rig.c; cc -O -o /tmp/t8 /tmp/t8.c
run.sh     # /tmp/timeout_rig && /tmp/t8 && /tmp/t8
           # expect the table above (total runtime ~8 s)
```
