# DF-0672 — VERDICT

## Verdict: REPRODUCED at source level; live trigger requires malicious NBSSN server + user SMB client

The uninitialized `struct sockaddr_in sin` at
`sys/netproto/smb/smb_trantcp.c:206` is **real at the source level**
(verified by reading the function). The retarget branch (lines 258-260)
fills only `sin.sin_addr` (4B) and `sin.sin_port` (2B); `sin.sin_len`,
`sin.sin_family`, and `sin.sin_zero[8]` remain stack garbage when
`sin` is passed to `nb_connect_in` → `soconnect` at line 263.

The file **is built** into the loadable `smbfs.ko` module
(`optional netsmb` in `sys/conf/files`); `kldload smbfs` brings
`nbssn_rq_request` and `nb_connect_in` into the kernel symbol space
(verified: `nm /boot/kernel/smbfs.ko` shows both symbols).

The structural bug is reproducible at the C level — see
`df0672_uninit_sin.c` which mirrors the kernel stack-residue pattern.

A **live trigger** requires:
1. Loading `smbfs.ko` (`kldload smbfs` — root action; or it's already
   loaded if SMB mounts are configured).
2. A malicious NBSSN server (TCP/139 listener) sending
   `NB_SSN_RTGRESP` with a 6-byte retarget payload.
3. A user-space action that initiates an SMB session to that server
   (`mount_smbfs`, or any process opening `/dev/smbN` and issuing
   `SMBIOC_LOOKUP`).

Because (2)+(3) require a non-trivial network harness and user
interaction, the bug is verified here at the source level only — the
mechanism is unambiguous from reading `nbssn_rq_request`.

## Mechanism (cited path:line)

1. **`sys/netproto/smb/smb_trantcp.c:206`** declares
   `struct sockaddr_in sin;` with **NO initialization**:
   ```c
   struct sockaddr_in sin;
   ```
2. The retarget branch (lines 250-260), entered when the server replies
   with `NB_SSN_RTGRESP`:
   ```c
   254:    if (rplen != 6) { error = ECONNABORTED; break; }
   258:    md_get_mem(mdp, (caddr_t)&sin.sin_addr, 4, MB_MSYSTEM);
   259:    md_get_uint16(mdp, &port);
   260:    sin.sin_port = port;
   ```
   fills only `sin.sin_addr` (4B) and `sin.sin_port` (2B). The other
   fields of `sin` (`sin_len`, `sin_family`, `sin_zero[8]`) remain
   uninitialized stack residue.
3. **`smb_trantcp.c:263`** passes the partially-initialized `sin` to
   `nb_connect_in(nbp, &sin, td)`.
4. **`smb_trantcp.c:167` `nb_connect_in`** calls
   `soconnect(so, (struct sockaddr*)to, td, TRUE)`.
5. **`sys/netinet/in_pcb.c:942-957` `in_pcbladdr_find`** validates:
   ```c
   954:    if (nam->sa_len != sizeof *sin)  return (EINVAL);
   956:    if (sin->sin_family != AF_INET) return (EAFNOSUPPORT);
   ```
   With uninit `sin_len` and `sin_family`, the outcome is
   non-deterministic:
   - **Common case:** the uninit bytes don't match (`sin_len != 16` or
     `sin_family != AF_INET`), the connect returns `EINVAL`/`EAFNOSUPPORT`
     silently, and the SMB connection fails.
   - **Rare case (sin_len garbage == 16 AND sin_family garbage == 2):**
     the validation passes and `soconnect` proceeds with
     attacker-controlled `sin_addr`/`sin_port` (from the malicious
     server's retarget payload) — a confused-deputy connect to a
     server-chosen target.

## Impact

- **No memory corruption.** The bug is use of uninitialized memory.
- The dominant effect is that DFS-671-style recursion may proceed or
  not depending on stack residue per call level.
- The rare match case enables a confused-deputy connect (the kernel
  SMB client connects to an attacker-chosen IP:port using the victim's
  credentials) — limited confidentiality/availability impact
  (CVSS `C:L/I:N/A:L`).
- UB from using uninitialized memory is itself a defect.

## Recommended fix

`fix.diff` zeroes `sin` and sets `sin_len` and `sin_family` before
the `md_get_mem`/`md_get_uint16` calls in the retarget branch. This
**matches the finding proposal** (`bzero + sin_len=sizeof + sin_family=AF_INET`).
