# DF-3402 — if_sl: slstart drains sc_fastq/ifsq under the tty locks while sloutput fills them under the ifsq serializer (no common lock)

## What

`sys/net/sl/if_sl.c` shares two packet queues between two lock domains
that never intersect:

* **Producer** — `sloutput_serialized` (`:451-507`), running under the
  interface's hardware serializer (`sloutput` `:516`
  `ifsq_serialize_hw`): `IF_ENQUEUE(&sc->sc_fastq, m)` (`:494`) and
  `ifsq_enqueue(ifsq, m)` (`:498`). Holds **no tty token**.
* **Consumer** — `slstart` (`:529-713`), invoked from the tty drain
  path (e.g. sio's `siopoll` under `tty_token`,
  `sys/dev/serial/sio/sio.c:2241`) or from `sl_outfill`
  (`:1040-1060`): `IF_DEQUEUE(&sc->sc_fastq, m)` (`:568`) and
  `ifsq_dequeue(ifsq)` (`:572`) under `t_token` only
  (`:539`). Holds **no ifsq serializer**.

`struct ifqueue`/`ifaltq` operations are non-atomic TAILQ
manipulations. Concurrent enqueue on one CPU and dequeue on another
corrupts the queue: lost mbufs, one mbuf reachable from two queues, or
a `m_nextpkt` chain that later gets `m_freem`'d twice (double free into
the mbuf objcache → use-after-free on subsequent allocations), or a
dequeue that walks into a freed chain. `sloutput_serialized:505` also
calls `slstart` directly while holding the serializer — the reverse
order of every other caller — so even the same-CPU interleavings
cross the domains.

DF-0576..0579 covered the callout/t_typ lifetime races and the BPF
stack copy; this queue-domain violation was missed. MPSAFE tag at
`:2` notwithstanding, the fastq has no lock at all and the ifsq's
serializer is not held by the drain side.

## Impact

Requires SLIP configured (root: `SLIPDISC` line discipline needs
`SYSCAP_RESTRICTEDROOT`, `:251`) and then concurrent interactive-class
(IPTOS_LOWDELAY → fastq) TX traffic while the tty drains — e.g. a
multi-CPU box routing telnet-style traffic over slip. Mbuf queue
corruption is memory-safety class (double-free/UAF), realistically a
panic. LEGACY bucket. Low / likely. Phase V skipped (legacy, race,
needs serial-line driver + SMP contention — per batch instructions).

## Fix

Protect `sc->sc_fastq` with the tty token in `sloutput_serialized`
(acquire `sc->sc_ttyp->t_token` around the fastq enqueue) and make
`slstart`'s ifsq dequeue run under the serializer (or move both sides
to a single lock, e.g. always call `slstart` via the ifsq serializer
the way `sloutput:505` already does).
