# DF-0484 detailed verdict

## Verdict: NOT REPRODUCED at runtime — real race by inspection (CWE-362), logic/DoS impact

## Mechanism
`tcp_syncache.c` uses a **single global** `MD5_CTX syn_ctx` (:1358) and a
**single global** `tcp_secret[SYNCOOKIE_NSECRETS]` (:1351-1354) with **no lock
and no per-CPU copy**. `syncookie_generate` (:1382, called from `syncache_add`
:1068) and `syncookie_lookup` (:1428, from `syncache_expand` :914) both run
`MD5Init/Update/Final` on that shared context and read/write `tcp_secret[]`.
TCP input is per-CPU netisr, so on ≥2 CPUs these execute concurrently against
the same state, interleaving the streaming MD5 transform and tearing
`ts_secbits` reads/writes. Result: generated cookie (`sc_iss`, :1406-1425) and
recomputed digest (:1442-1463) disagree ⇒ legitimate completing ACKs rejected
under SYN flood ⇒ SYN-cookie mitigation defeated exactly when engaged.

## Impact ceiling
Logic/DoS only. No corruption, no leak, no write primitive ⇒ **no escalation
chain** (this is not a memory-corruption finding; Phase 6 does not apply).

## Why not reproduced
Low-probability SMP race with no deterministic trigger; observable effect (one
dropped ACK) is indistinguishable from normal loss on a flooded link.
Established by the lockless single-global-state design (see `trace.md`).

## Privilege boundary
Network, unauthenticated (AV:N/PR:N). No local privilege required to
contribute SYNs to the race.

## Fix (applies + compiles + boots)
`fix.diff` adds `static struct spinlock syncookie_sl` and wraps the
secret-refresh + MD5Init..Final region in `spin_lock`/`spin_unlock` in both
functions (releasing before the early `return NULL` in `syncookie_lookup`).
Built in the combined single-fix kernel (#1); boots clean. A per-CPU
secret+context would remove contention but is a larger change. `fix_status =
not_testable` (no deterministic runtime marker).

## PoC changes
No seeded PoC. I authored `trace.md` (line-by-line race trace) and `fix.diff`.
A deterministic PoC is infeasible for this race class.
