# DF-3291 — GANN propagation gate uses `&&` where `||` is required: TTL-exhausted GANNs re-broadcast with TTL wrapping 0→255

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

## What

```c
/* popagate only if decremented ttl >= 1 && forwarding is enabled */
if ((ie.gann_ttl - 1) < 1 && !(ms->ms_flags & IEEE80211_MESHFLAGS_FWD))
        return 0;
...
pgann.gann_hopcount = ie.gann_hopcount + 1;
pgann.gann_ttl = ie.gann_ttl - 1;        /* uint8_t: 0 - 1 -> 255 */
```
(:2690-2694)

The comment states the intended condition (propagate only if ttl-1 ≥ 1
**and** forwarding enabled) but the code ORs nothing: with the default
`IEEE80211_MESHFLAGS_FWD` set (mesh_vattach :683 sets AP|FWD), the
`&& !(FWD)` term is always false, so **every accepted GANN is
re-broadcast regardless of TTL**. A TTL=0 GANN is forwarded with

    pgann.gann_ttl = (uint8_t)(0 - 1) = 255,

violating the 802.11s hop limit and re-injecting the announcement with a
fresh full TTL budget (hopcount also wraps 255→0). The next hop's
`(255-1) < 1` check is again defeated by the same `&&`. Only per-gate
sequence dedup (itself not wrap-safe, DF-0290) bounds the flood.

## Reproduced (stock kernel)

Injected well-formed GANN with ttl=0 (harness step 22); victim
re-broadcast (captured):

```
tx[28] ... 0d 02 7d 0f 00 01 ff 02:00:00:02:00:40 01000000 1000
                                    ^^ TTL=0xff
```
hopcount incremented, TTL = **255**.

## Build / run

```
sh findings/poc/DF-3286/build.sh
sh findings/poc/DF-3291/run.sh
```

## Threat

Spec violation + mesh-wide announcement amplification with defeated TTL
(bounded only by seq dedup). Severity Low (protocol/logic; DoS
amplification marginal). Fix: `&&` → `||` (fix.diff hunk 6).
