# DF-5553 — usb_template_phone.c structural misfire (CDC patcher vs audio CS_INTERFACE descriptors)

**File:** `sys/bus/u4b/template/usb_template_phone.c` (416 LOC, pass 2)
**Evidence class:** structural — production tables extracted verbatim at build
time and classified with the exact predicate of the in-tree core. Gadget-mode
QEMU activation is impossible for this template (it is not selectable,
DF-5353), so per the pass-2 family standard the verdict rests on the
table-termination/classification replay below, run on the audit guest against
the guest's own `/usr/src`.

## Build

```sh
./build.sh        # extracts /usr/src/.../usb_template_phone.c body -> phone_body.inc,
                  # sha256s the source, builds table_check + table_check_fixed
```

Requires nothing but a C compiler; `SRC=<path>` overrides the source file.

## Run

```sh
./run.sh
```

Runs the baseline classification replay (misfires = the finding, structural
checks S1–S7 must PASS) and the fix-logic variant (`-DFIX_CLASSGATE`, CDC
patching gated on CDC interface classes; misfires must drop to 0). Exits 0
iff both behave exactly as expected.

## Expected output

- `build.log`: source sha256 `6dac1ced…1942` (identical to the audited tree),
  359 extracted lines, `BUILD_OK`.
- `run.log` / `run.2.log`: five `MISFIRE` lines —
  - interface 0 (AC header `subtype 0x01`, two feature units `subtype 0x06`):
    deltas `+= 0` (benign),
  - interface 1: `phone_raw_desc_20` byte[4] `+= 1  <-- CORRUPTED`,
  - interface 2: `phone_raw_desc_30` byte[4] `+= 2  <-- CORRUPTED`;
  - `ALL STRUCTURAL CHECKS PASSED` (S1–S7);
  - `MISFIRE lines under FIX_CLASSGATE: 0 (expected 0)`.
- Exit code 0, both runs identical (deterministic).

## What byte[4] is

`phone_raw_desc_20/_30` are USB Audio `AS_GENERAL` descriptors
(`{bLength=7, 0x24, subtype 0x01, bTerminalLink, bDelay=1, wFormatTag=0x0001}`);
byte[4] is `bDelay`. The core's CDC call-management patcher
(`usb_template.c:162-171`) reads it as `bDataInterface` and adds the containing
interface number, so the generated gadget descriptors advertise
`bDelay = 2` (playback, iface 1) and `bDelay = 3` (record, iface 2) instead of
the authored 1. Writes are in-bounds inside the generated config buffer —
this is descriptor corruption, not memory corruption.

## Artifacts

- `table_check.c` — harness (includes the audited file's body verbatim)
- `build.sh`, `run.sh`
- `build.log`, `run.log`, `run.2.log`, `env.txt`
- `fix.diff` — class-gated CDC renumbering (validated by `table_check_fixed`)
- `VERDICT.md`, `manifest.json`, `verdict.json`
