# DF-0688 — sco_ctloutput PRCO_SETOPT unconditional NULL-deref

## Summary

`sys/netbt/sco_socket.c:123-135` `sco_ctloutput()` PRCO_SETOPT path
unconditionally dereferences NULL on every setsockopt, because line 124
`m = m_get(M_WAITOK, MT_DATA)` yields `m->m_len == 0`, the
`if (m->m_len == 0)` branch at line 127 therefore always fires (freeing
`m` and setting `m = NULL`), and the missing `break` at line 132 lets
control fall through to `sco_setopt(pcb, sopt->sopt_name, mtod(m, uint8_t *))`
which expands `mtod(NULL,...)` and reads `offsetof(struct mbuf, m_data)`
== 0x10 from NULL → page-fault panic.

## How to reproduce

```
./build.sh
ssh dfbsd 'kldload netbt.ko'   # admin Bluetooth setup (realistic precondition)
ssh dfbsd-maxx 'cd poc/DF-0688 && ./run.sh'
# expect: guest dies; panic in dfbsd-qemu/boot.log
```

## Expected (bug present)

```
Fatal trap 12: page fault while in kernel mode
fault virtual address    = 0x10
Stopped at      sco_ctloutput.cold.2+0x19:      movq    0x10,%rax
```

## Expected (after fix)

`setsockopt` returns `-1` with `errno=EIO` ("Input/output error"). Guest
stays up. No panic.

## Preconditions

- `netbt.ko` loaded by an admin (realistic Bluetooth deployment).
- Attacker is any local user (no special group); `socket(AF_BLUETOOTH,
  SOCK_SEQPACKET, BTPROTO_SCO)` is allowed for any user once the domain
  is registered.

## Impact

Local unprivileged DoS (kernel panic). No corruption primitive (the `m`
pointer is NULL, not stale). A single setsockopt kills the kernel.
