# DF-2956 VERDICT

**status: reproduced** (impact: timestamp-integrity / correctness — no memory
corruption; per the honest-impact enum this maps to `impact: none`)

## What was run

Same guest/session as DF-2955 (stock kernel #0 → patched #1).

1. **Math harness** (`harness_guest.log` section B): `timespec2fattime` with
   post-2107 tv_sec:
   - 2108-01-01 → `dd=0x0021` (1980-01-01)
   - 4147-08-08 → `dd=0xeef8` → decodes 2099-07-24
   - year 5236 → `dd=0x705c` → decodes 2036-02-28
   - year 4461763 (2^47-ish) → `dd=0x5777` → decodes **2023-11-23**
   - 2^62 → `dd=0xf450` → decodes 2102-02-16

2. **End-to-end kernel PoC** (`poc_root.log`): on the real msdosfs mount,
   `utimes()` with explicit times:
   - X1 4354819200 (2108-01-01) → stat **1980-01-01 00:00:00**; on-disk
     entry bytes 24-25 = `21 00` → `MDate=0x0021` (`findentry.log`) —
     bit-for-bit the harness prediction.
   - X2 68718441600 (4147) → stat 2099-07-24.
   - X3 140737488355327 (year 4,461,763) → stat **2023-11-23 05:22:06**;
     on-disk `MDate=0x5777` (2023-11-23) — the 64→32 truncation of
     `t2 = t1 / DAY` (subr_fattime.c:157) aliases an absurd timestamp onto
     a plausible recent one.

3. **Unprivileged** (`poc_unpriv.log`): `mount_msdos -u 1001` + run as
   uid 1001 (file owner) → X-case MISMATCHs identical, no root.

## Root cause chain

`utimes`/`futimens` (no upper bound: `itimespecfix` kern_time.c:1047-1052;
owner/write gate: vfs_syscalls.c:3847 `naccess_lva(NLC_OWN|NLC_WRITE)`) →
`msdosfs_setattr` (msdosfs_vnops.c:419-420; allowed when cr_uid == pm_uid) →
`timespec2fattime` (sys/kern/subr_fattime.c:139):
`t2 = t1 / DAY` truncates int64→uint32 (:157); `(l * 4) << 9` overflows the
7-bit year field into the 16-bit `*ddp` (:173) for l*4 > 127. Result:
far-future dates persist as *arbitrary* dates in 1980..2107 with no error.

Distinct from known DF-0200 (negative tv_sec path; here tv_sec is positive
and huge).

## Why not higher severity

Writes only wrap into the caller's `uint16_t` date word (defined unsigned
wrap; table walks bounded m ≤ 47 — no OOB). Downstream table decomposition
remains in-bounds for any truncated t2 (verified by construction and fuzzing
the harness with t1 up to 2^62). Silent timestamp fabrication (integrity),
same class as DF-0199/DF-0200 (Low).

## Fix validation

`fix.diff` adds `#define T2107 ((2108-1980)*YEAR + 31 - 1)` and saturates
`t2 > T2107 → T2107` before the 2100 adjustment (plus the DF-2955 hunk; one
rebuild validated both).

Patched kernel #1 (`poc_fixed.log`):
- X1 2108-01-01 → stat **2107-12-31 00:00:00**, on-disk `MDate=0xff9f`
  (maximal representable FAT date).
- X2 → 2107-12-31 08:00:00 (time-of-day preserved).
- X3 → 2107-12-31 05:22:06 — **the 2023-11-23 alias is gone**.

fix_status: **fixed**.

Guest was reset (`vm.sh reset with-src`) after validation.
