# DF-0715 — smb_memdupin signed-length validation accepts zero

## Summary
`smb_memdupin` (`sys/netproto/smb/smb_subr.c:137`) validates its `int len`
parameter only with a signed `> 8*1024` check. When `len == 0`, DragonFly's
`kmalloc(0)` returns the sentinel `ZERO_LENGTH_PTR = ((void*)-8)` (not NULL),
which the sole caller `smb_usr_vc2spec` (`smb_usr.c:74-76`) fails to catch with
its `== NULL` check. The sentinel pointer flows to `dup_sockaddr`
(`smb_conn.c:462`) which dereferences `sa->sa_len` at address
`0xFFFFFFFFFFFFFFF8` — a non-canonical x86-64 address — causing a kernel panic
(fatal trap 12 / GPF). When `len < 0`, the signed check passes and `kmalloc`
receives a wrapped-to-huge `size_t`, panicking in the slab allocator.

## Impact
**Low** — root→kernel DoS. The only path is `/dev/nsmb` (0700 root:wheel).
No unprivileged escalation; no memory-corruption primitive (the GPF fires before
any write).

## Build
```
cc -o smb_memdupin_zero smb_memdupin_zero.c
```

## Run (must be root; needs smbfs.ko loaded)
```
kldload smbfs        # admin precondition: load the SMB client module
./smb_memdupin_zero
```

## Expected (bug present — unpatched)
Kernel panic:
```
Fatal trap 12: page fault while in kernel mode
fault virtual address = 0xfffffffffffffff8
Stopped at dup_sockaddr+0x18: movzbl (%rdi),%edi
```
Guest goes down (DDB prompt on serial console).

## Expected (bug fixed — patched)
```
SMBIOC_OPENSESSION: Cannot allocate memory
ioctl returned -1 (errno=12)
```
Guest stays up; no panic.

## Files
- `smb_memdupin_zero.c` — trigger PoC
- `build.sh` / `run.sh` — build/run scripts
- `fix.diff` — git-apply-able fix (reject `len <= 0` in `smb_memdupin` + `smb_memdup`)
- `VERDICT.md` — full analysis
- `panic.txt` — panic signature from serial console
- `run.log` / `fix_run.log` — unpatched / patched run output
- `fix_build.log` — patched kernel+module build log
- `env.txt` — guest environment
