# DF-4159 — RX livelock in xe_intr(): dropped packets are never released

**File:** `sys/dev/netif/xe/if_xe.c` (xe(4), Xircom CreditCard/RealPort PCMCIA ethernet)
**Severity:** Medium · **CWE-835** · hardware-gated (source-certain control flow)

## What this pack contains

- `livelock_harness.c` — userland logic model of the exact RX loop control flow
  from `if_xe.c:742-844` (copied verbatim; drop paths parameterized), with the
  card register semantics from `if_xereg.h` and Linux `xirc2ps_cs.c`.
- `build.sh` / `run.sh` — exact commands (built and run on the DF QEMU guest,
  which has a real toolchain; no Xircom hardware exists there, hence *logic
  model* rather than kernel run).
- `build.log` / `run.log` — full untrimmed output.
- `fix.diff` — one-line-per-path fix.
- `verdict.json` / `manifest.json`.

## Build

    cc -O2 -Wall -o livelock_harness livelock_harness.c

## Run

    ./run.sh          # runs 6 scenarios: as-written vs fixed, per drop path
    # or individually:  ./livelock_harness MODE FAIL_MGET FAIL_MCL LEN_ZERO

## Expected output

Scenarios with MODE=0 (DragonFly code as written) and any error path taken
(zero-length frame, MGETHDR failure, or MCLGET failure) print:

    RESULT: LIVELOCK — loop exceeded 200000 iterations; packet NEVER released (XE_DO skip writes: 0)

The normal path (MODE 0, no failure) and every fixed scenario (MODE 1) print:

    RESULT: loop terminated normally after 1 iterations (drops: N, XE_DO skip writes: 1, ...)

## Interpretation

In the kernel, `xe_intr()` runs in hard-interrupt context holding the ifnet
serializer (`bus_setup_intr(..., scp->ifp->if_serializer)` at `if_xe.c:333`).
The three `continue` statements at `if_xe.c:758`, `:772`, `:779` jump back to
the loop condition (`XE_INB(XE_ESR) & XE_ESR_FULL_PACKET_RX`) **without**
writing `XE_DO = XE_DO_SKIP_RX_PACKET` (`if_xe.c:843`). The unreleased packet
keeps ESR.FULL_PACKET_RX asserted, so the loop never exits → permanent
interrupt-livelock with the serializer held → system-wide hang (no panic; the
box must be power-cycled). Cross-validated: Linux's `xirc2ps_cs.c` for the
same silicon issues the skip **unconditionally** per iteration with the
comment *"clear the received/dropped/error packet"*.

Trigger: any inbound frame on the xe interface while the matching drop
condition holds — most realistically `MGETHDR`/`MCLGET` failure under kernel
memory pressure (an unprivileged local user can exhaust mbuf clusters while a
remote peer sends traffic), or a CRC-only frame (`RBC==4` → `len==0`).
