# DF-5330 — resettodr() pre-epoch wall clock → unbounded year loop → permanent kernel hang

File: `sys/platform/pc64/isa/clock.c` (pass 2, GLM 5.3)

## Summary

`resettodr()` (sys/platform/pc64/isa/clock.c:1148) converts the wall clock to
RTC Y/M/D with:

```c
unsigned long tm;
...
microtime(&tv);
tm = tv.tv_sec;                 /* clock.c:1158-1159: negative -> 0xFFFF...F */
crit_enter();                   /* clock.c:1161 */
writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR);
tm -= tz.tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
writertc(RTC_SEC, bin2bcd(tm%60)); tm /= 60;
...
for (y = 1970, m = DAYSPERYEAR + LEAPYEAR(y);   /* clock.c:1175-1178 */
     tm >= m;
     y++,      m = DAYSPERYEAR + LEAPYEAR(y))
        tm -= m;
```

`tm` is **unsigned long**. Any wall clock before 1970-01-01 (or a legal clock
pushed before the epoch by the `tz_minuteswest`/`adjkerntz` subtraction)
wraps `tm` to ~1.8e19. The year loop then needs ~5e16 iterations (~years of
CPU time) while `crit_enter()` defers preemption/interrupts on the CPU and
the caller holds `masterclock_lock` exclusively. Result: **permanent,
unkillable kernel hang, no panic, no dump**.

## Reachability

`settimeofday({tv_sec:-1})` → `sys_settimeofday()` (kern/kern_time.c:655,
privilege-checked with `caps_priv_check_self(SYSCAP_NOSETTIME)`) →
`settime()` (kern/kern_time.c:127) → `set_timeofday()` then **synchronous**
`resettodr()` (kern/kern_time.c:167). The syscall never returns.

Also reachable at shutdown (`resettodr_on_shutdown`, clock.c:1063) whenever
the system clock is pre-epoch at poweroff, and via `clock_settime()`
(kern_time.c:753 path). The securelevel>1 backward-step clamp
(kern_time.c:148) does not apply at the default `kern.securelevel = -1`.

Privileged (root / SYSCAP_NOSETTIME) → **Low severity DoS**, but certain and
trivial to trigger; the hang is total and unrecoverable (worse than a panic:
no crash dump, no watchdog story).

## Reproduce

```
# host
cd dfbsd-qemu && ./vm.sh up            # if down
# copy df5330.c into the guest, then:
# guest (root)
cc -O -o /root/df5330 df5330.c
( /root/df5330 > /root/df5330.log 2>&1 & ); sleep 12
cat /root/df5330.log     # only the "setting..." line; no RETURNED marker
ps axl | grep df5330     # hangs; system degraded, no panic
```

Expected (vulnerable kernel): `settimeofday()` never returns; the guest
wedges (ssh sessions hang mid-command; some userland on other CPUs limps);
no panic on serial console. After ~90 s the observation command times out
(RUN_RC=124).

Expected (patched kernel, fix.diff): `settimeofday` returns immediately;
marker line `settimeofday RETURNED (bug did not trigger)` is printed; guest
stays healthy; RTC is left untouched (resettodr bails out before writing
date registers).

## Artifacts

- `df5330.c`      trigger source
- `build.log`     compiler output (vulnerable build)
- `run.log`       decisive baseline run (vulnerable kernel) — hang
- `run.2.log`     patched-kernel re-run — returns cleanly
- `env.txt`       guest uname / sysctls
- `fix.diff`      git-apply-able one-hunk fix (validated on guest)
- `VERDICT.md`    full narrative
- `verdict.json`  machine verdict (persist_poc.py schema)
