# DF-0627 — mbuf chain leak on duplicate SMB responses (remote DoS)

## Verdict
**CONFIRMED by exhaustive source tracing — memory leak / remote DoS. Not exercised
at runtime in this evidence pack because the trigger requires a malicious SMB
server (network-attacker position); the leak is unambiguous in the code.**

## Mechanism (cited)
`sys/netproto/smb/smb_iod.c` `smb_iod_recvall()` (`:322-379`):
- `:324` `SMB_TRAN_RECV(vcp, &m, td)` receives an mbuf chain `m` from the network.
- `:354` `TAILQ_FOREACH(rqp, ...)` finds the outstanding request matching the
  response MID.
- `:358-359` first response: `md_initm(&rqp->sr_rp, m)` — **ownership of `m`
  transfers** to the request (`md_top = m`, `sys/kern/libmchain/subr_mchain.c:319`).
- `:361-362` multipacket: `md_append_record(&rqp->sr_rp, m)` — ownership transfers.
- `:363-366` **duplicate** response (same MID, `md_top` already set, not
  `SMBR_MULTIPACKET`): the `else` branch does
  `SMBRQ_SUNLOCK(rqp); SMBERROR("duplicate response ..."); break;` — it breaks out
  of the loop **without calling `md_initm`/`md_append_record` AND without
  `m_freem(m)`**. `m` is neither attached nor freed.
- `:374-377` the only post-loop `m_freem(m)` is gated on `if (rqp == NULL)` — but
  `rqp` is non-NULL (it matched at `:355`), so **`m_freem` is SKIPPED**.
- Next loop iteration `:323` `m = NULL;` then `:324` overwrites `m`; the orphaned
  chain is permanently leaked.

`md_initm` ownership claim: `sys/kern/libmchain/subr_mchain.c:316-319`
`mdp->md_top = mdp->md_cur = m;`. `SMB_MAXPKTLEN = 0x1FFFF` (`sys/netproto/smb/smb.h:292`);
`nbssn_recv` (`smb_trantcp.c:313`) returns each NetBIOS session message as a separate
chain, bounded by `:305`.

## Threat model / impact
- Attacker = the SMB server the victim client is connected to (network position;
  authenticated session sufficient). `UI:R` — a local user must mount the attacker's
  share.
- Trigger: server sends one valid reply for an outstanding MID, then K additional
  NetBIOS-framed SMB messages with the SAME MID. Each duplicate hits `:363` and leaks
  its chain (up to 128 KB). Sustained flooding → mbuf/memory exhaustion → panic/OOM.
- Impact: **remote kernel memory-exhaustion DoS** (CWE-401). Pure resource leak; no
  memory corruption, no privilege boundary crossed → no uid0 path.

## Why no runtime run here
Reproducing requires a malicious SMB1 server (NEGOTIATE + SESSION_SETUP + TREE_CONNECT
+ the duplicate flood). That harness is out of scope for this evidence pack; the bug
is proven line-by-line above. `netstat -m` on a victim under attack would show the
mbuf count climbing monotonically per duplicate.

## Fix
`fix.diff` adds `m_freem(m)` in the duplicate `else` branch before `break`, so every
received chain is either attached (`md_initm`/`md_append_record`) or freed. Matches
the finding markdown's recommended fix exactly.
