# DF-3289 — Uninitialized stack `args[1]` sent in mesh peer-timeout CLOSE action frames

File: `sys/netproto/802_11/wlan/ieee80211_mesh.c` (pass 2 audit)

## What

`mesh_peer_timeout_cb` (:3091-3143) declares `uint16_t args[3]` and in
two branches sets only elements 0 and 2 before transmitting a CLOSE
action frame to the peer:

```c
case IEEE80211_NODE_MESH_OPENSNT:
case IEEE80211_NODE_MESH_OPENRCV:
        if (ni->ni_mlrcnt == ieee80211_mesh_maxretries) {
                args[0] = ni->ni_mlpid;
                args[2] = IEEE80211_REASON_MESH_MAX_RETRIES;   /* args[1] NEVER set */
                ieee80211_send_action(ni, ..., MESHPEERING_CLOSE, args);
...
case IEEE80211_NODE_MESH_CONFIRMRCV:
        args[0] = ni->ni_mlpid;
        args[2] = IEEE80211_REASON_MESH_CONFIRM_TIMEOUT;       /* args[1] NEVER set */
        ieee80211_send_action(ni, ..., MESHPEERING_CLOSE, args);
```

`args[1]` flows into `ieee80211_add_meshpeer(..., CLOSE, args[0],
args[1], args[2])` (:2902-2948): if the garbage is non-zero the frame is
built in long form (MPM_MAX_SZ) and the two uninitialized kernel-stack
bytes are transmitted on air in the Peer Link ID field.  The value also
selects the IE length (6 vs 8) — an uninitialized-value use in protocol
logic either way. CWE-457.

Any mesh peer can drive a victim into these branches: beacon → victim
auto-peers (OPENSNT) → attacker stays silent → 3×40 ms → CLOSE #1;
CONFIRM-then-silence → CONFIRMRCV timeout → CLOSE #2.

## Verification result (stock kernel)

Harness steps 1/3 reproduced the timeout CLOSE frames (captured at the
radio): both the MAX_RETRIES and CONFIRM_TIMEOUT closes were emitted in
**short form** (`75 06 0000 <llid> <rcode>`), i.e. on this build the
uninitialized slot read as 0 and no bytes leaked on air. The
uninitialized read itself is certain from source; the on-air disclosure
depends on the stack garbage being non-zero, which was not observed on
this kernel/callout path. Filed Low: latent info-leak/hygiene defect.

Captured CLOSE (CONFIRMRCV-timeout path):
```
tx[31] fc0=d0 len= 39: d0000000 02:00:00:00:00:aa > 02:00:00:00:00:f2 seq=0x2300
  0f 03 72 03 70776e 75 06 0000 eed1 3800      # close, meshid pwn, meshpeer len=6,
  #  llid=0xd1ee rcode=0x38(MAX_RETRIES) -- no peerid (uninit slot read 0)
```

## Build / run

```
sh findings/poc/DF-3286/build.sh
sh findings/poc/DF-3289/run.sh     # beacon, confirm, silence, dump CLOSEs
```

## Fix

`args[1] = 0;` at the top of mesh_peer_timeout_cb (fix.diff hunk 5).
