Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH AUTOSEL 6.18-5.10] wifi: brcmfmac: Set DMA direction for msgbuf packet IDs
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
@ 2026-10-19 13:45 ` Sasha Levin
  2026-10-19 13:45 ` [PATCH AUTOSEL 6.18-6.6] wifi: iwlwifi: mvm: ignore sync frames when sync is disabled Sasha Levin
                   ` (39 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:45 UTC (permalink / raw)
  To: patches, stable
  Cc: Can Peng, Arend van Spriel, Johannes Berg, Sasha Levin,
	linux-wireless, brcm80211, brcm80211-dev-list.pdl, linux-kernel

From: Can Peng <pengcan@kylinos.cn>

[ Upstream commit f0ba5fd51ff23077ce66cb9be79d41a4b7c19c5e ]

brcmf_msgbuf_init_pktids() takes the DMA direction from its callers,
but never stores it in the packet ID state.  Since the state is zeroed,
pktids->direction remains DMA_BIDIRECTIONAL for both the TX and RX
packet ID pools.

All msgbuf packet ID map and unmap paths use pktids->direction.  As a
result, TX buffers requested with DMA_TO_DEVICE and RX buffers requested
with DMA_FROM_DEVICE are mapped and unmapped as DMA_BIDIRECTIONAL
instead.

Store the caller-provided direction when initializing the packet ID
state.

Signed-off-by: Can Peng <pengcan@kylinos.cn>
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Link: https://patch.msgid.link/20260724092530.674624-1-pengcan@kylinos.cn
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **5.15.221** (`pending-5.15`). The missing
`pktids->direction` store is present here, so this is a one-line DMA
correctness fix for this tree.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

Step 1.1: PARSE THE SUBJECT LINE
Record: **[wifi / brcmfmac]** **[Set]** Store DMA direction on msgbuf
packet ID pools so TX/RX map/unmap use the caller’s direction instead of
the zeroed `DMA_BIDIRECTIONAL` default.

Step 1.2: PARSE ALL COMMIT MESSAGE TAGS
From the commit text under review:
- **Acked-by:** Arend van Spriel `<arend.vanspriel@broadcom.com>`
  (brcm80211 maintainer)
- **Link:**
  `https://patch.msgid.link/20260724092530.674624-1-pengcan@kylinos.cn`
- **Signed-off-by:** Can Peng `<pengcan@kylinos.cn>` (author)
- **Signed-off-by:** Johannes Berg `<johannes.berg@intel.com>` (wireless
  maintainer)
- No **Fixes:** / **Cc: stable** / **Reported-by** in the applied
  message (expected for this review queue)

Original mailing-list submission (openwall / LKML, msgid
`20260724092530.674624-1-pengcan@kylinos.cn`) **did** include:
- `Fixes: 9a1bb60250d2 ("brcmfmac: Adding msgbuf protocol.")`
- `Cc: stable@vger.kernel.org`

Those tags were dropped when the patch was applied. That is
author/maintainer intent, not a pipeline “already selected” marker.
Decision below is still on technical merit.

Step 1.3: ANALYZE THE COMMIT BODY TEXT
Record:
**Bug:** `brcmf_msgbuf_init_pktids()` takes `enum dma_data_direction
direction` but never writes `pktids->direction`. `pktids` is zeroed, and
`DMA_BIDIRECTIONAL == 0`.
**Symptom:** TX pools created with `DMA_TO_DEVICE` and RX pools with
`DMA_FROM_DEVICE` are mapped/unmapped as bidirectional.
**Version:** Introduced with msgbuf (2014); no version cutoff in the
message.
**Root cause:** Missing store of a parameter that every map/unmap path
already reads.

Step 1.4: DETECT HIDDEN BUG FIXES
Record: Not a disguised cleanup. It is an explicit DMA-direction
correctness fix. The unused parameter plus zeroed field is the entire
bug.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

Step 2.1: INVENTORY THE CHANGES
Record:
- **File:** `drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c`
- **Scope:** +1 line in `brcmf_msgbuf_init_pktids()` (`pktids->direction
  = direction;`)
- **Classification:** single-file surgical fix
- Mainline hunk context uses `kzalloc_objs` / `kzalloc_obj`; this 5.15
  tree uses `kcalloc` / `kzalloc`. The added line is the same.

Step 2.2: UNDERSTAND THE CODE FLOW CHANGE
Record:
**Before:** After allocating the array and `pktids`, only `array` and
`array_size` are set. `direction` stays 0.
**After:** The caller-provided direction is stored.
**Path:** Probe/init (`brcmf_proto_msgbuf_attach`), then every TX/RX
`dma_map_single` / `dma_unmap_single` via `pktids->direction`.

Step 2.3: IDENTIFY THE BUG MECHANISM
Record: **Logic / DMA API correctness** (with IOMMU and cache/bounce
side effects).
Callers already pass the right direction:

```1580:1585:drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
        msgbuf->tx_pktids = brcmf_msgbuf_init_pktids(NR_TX_PKTIDS,
                                                     DMA_TO_DEVICE);
        if (!msgbuf->tx_pktids)
                goto fail;
        msgbuf->rx_pktids = brcmf_msgbuf_init_pktids(NR_RX_PKTIDS,
                                                     DMA_FROM_DEVICE);
```

Map/unmap always use `pktids->direction` (`brcmf_msgbuf_alloc_pktid`,
`brcmf_msgbuf_get_pktid`, `brcmf_msgbuf_release_array`). Verified
`DMA_BIDIRECTIONAL = 0` in `include/linux/dma-direction.h`.

Verified DMA consequences in this tree:
- **IOMMU:** `dma_info_to_prot()` maps BIDIRECTIONAL → `IOMMU_READ |
  IOMMU_WRITE`, TO_DEVICE → `IOMMU_READ` only, FROM_DEVICE →
  `IOMMU_WRITE` only (`drivers/iommu/dma-iommu.c`). TX SKBs currently
  get device **write** permission they should not have.
- **Docs:** Networking TX must be `DMA_TO_DEVICE`, RX `DMA_FROM_DEVICE`
  (`Documentation/core-api/dma-api-howto.rst`).
- **SWIOTLB / non-coherent:** direction selects bounce copy and
  `arch_sync_dma_*` behavior.

Step 2.4: ASSESS THE FIX QUALITY
Record: Obviously correct: the parameter exists only to be stored. One
assignment, no API/lock/structure change. Regression risk is low: it
uses the directions the callers already requested. Using stricter TX
mapping (device read-only) is the intended, safer model.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

Step 3.1: BLAME THE CHANGED LINES
Record: Buggy code from **`9a1bb60250d2`** (“brcmfmac: Adding msgbuf
protocol.”, Hante Meuleman, 2014-07-30). `git describe --contains` →
`v3.17-rc1`. Field, parameter, and missing store have been this way
since introduction. `git merge-base --is-ancestor 9a1bb60250d2b HEAD`
succeeded.

Step 3.2: FOLLOW THE FIXES: TAG
Record: Applied commit has no Fixes tag. Original submission fixes
**`9a1bb60250d2`**, which **is** in this tree. No later intermediate fix
stores `direction` (`git log --grep` on this file found none).

Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES
Record: Recent related commit already here: **`ddb864ea9ca2e`** (“wifi:
brcmfmac: unmap dma buffer in brcmf_msgbuf_alloc_pktid()”) — error-path
unmap, still using `pktids->direction`. Standalone; not part of a
numbered series.

Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS
Record: Can Peng has **no** other commits in this 5.15 brcm80211
history. Arend van Spriel is the listed brcm80211 maintainer
(`MAINTAINERS`) and **Acked-by** the patch.

Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS
Record: No new helpers. The one-line store applies on the existing
`kcalloc`/`kzalloc` function. **Standalone.**

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION
Record: `b4 dig -c` on this tree cannot target the mainline SHA (commit
not present). lore.kernel.org fetch returned 403. Thread recovered from:
- https://lists.openwall.net/linux-kernel/2026/07/24/732 (v1 submission)
- https://lkml.iu.edu/hypermail/linux/kernel/2608.0/00969.html (Ack)

Single revision. No NAK. Maintainer ack only.

Step 4.2: CHECK WHO REVIEWED THE PATCH
Record: To: Arend van Spriel. Cc: linux-wireless, brcm80211 lists,
linux-kernel, **stable@vger.kernel.org**. Ack from the brcm80211
maintainer. Applied by Johannes Berg.

Step 4.3: SEARCH FOR THE BUG REPORT
Record: No syzbot/bugzilla/user crash in the message. Bug is from code
inspection (parameter never stored).

Step 4.4: CHECK FOR RELATED PATCHES AND SERIES
Record: Standalone 1-line patch, not `N/M`.

Step 4.5: CHECK STABLE MAILING LIST HISTORY
Record: Author Cc’d stable on submission. Targeted
lore.kernel.org/stable search did not return a later rejection thread
(lore 403 / search noise). **UNVERIFIED:** no explicit stable-list NAK
found.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF
Record: `brcmf_msgbuf_init_pktids()` only. Consumers of the field:
`brcmf_msgbuf_alloc_pktid`, `brcmf_msgbuf_get_pktid`,
`brcmf_msgbuf_release_array`.

Step 5.2: TRACE CALLERS
Record:
- Init: `brcmf_proto_msgbuf_attach()` → TX `DMA_TO_DEVICE`, RX
  `DMA_FROM_DEVICE`.
- Alloc: TX from `brcmf_msgbuf_txflow`; RX from
  `brcmf_msgbuf_rxbuf_data_fill` and ioctl/event buffer post.
- Get/unmap: TX status and RX complete paths.
Hot path for **PCIe** brcmfmac (`CONFIG_BRCMFMAC_PCIE` selects
`BRCMFMAC_PROTO_MSGBUF`). SDIO/USB use BCDC, not this file.

Step 5.3: TRACE CALLEES
Record: `dma_map_single` / `dma_unmap_single` with `pktids->direction`.

Step 5.4: FOLLOW THE CALL CHAIN
Record: Userspace networking on Broadcom FullMAC **PCIe** WiFi (TX/RX).
Unprivileged traffic hits this path. Not an init-only leak.

Step 5.5: SEARCH FOR SIMILAR PATTERNS
Record: All four map/unmap sites in this file already use
`pktids->direction`. No second missing store.

===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================

Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?
Record: **Yes.** `msgbuf.c` lines 294–313 omit the store. Introduced in
v3.17, present for the entire 5.15 lifetime. `git log --grep="Set DMA
direction for msgbuf"` on this file is empty.

Step 6.2: CHECK FOR BACKPORT COMPLICATIONS
Record: **Clean apply** of the one added line. Context around allocators
differs (`kcalloc` vs mainline `kzalloc_objs`); do not transplant the
mainline hunk blindly—only add `pktids->direction = direction;`.

Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE
Record: Only the 2022 unmap-on-alloc-failure fix (`ddb864ea9ca2e`).
Direction is still unset.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY
Record: **wifi / brcmfmac msgbuf (PCIe).** **IMPORTANT** — common
laptop/embedded Broadcom FullMAC PCIe devices, not core mm/VFS.

Step 7.2: ASSESS SUBSYSTEM ACTIVITY
Record: Mature driver (msgbuf since 2014). File still gets targeted
fixes; this is an old latent bug, not churn from a new API.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

Step 8.1: DETERMINE WHO IS AFFECTED
Record: **Driver-specific / config-specific:** `CONFIG_BRCMFMAC` +
`CONFIG_BRCMFMAC_PCIE` (msgbuf). Not SDIO/USB BCDC. Enabled in several
ARM/arm64 defconfigs; widely used on x86 laptops with Broadcom PCIe
WiFi.

Step 8.2: DETERMINE THE TRIGGER CONDITIONS
Record: Every TX map and RX buffer post for msgbuf. Common path.
Unprivileged traffic can trigger it. Not a rare race.

Step 8.3: DETERMINE THE FAILURE MODE SEVERITY
Record:
- **IOMMU:** TX buffers mapped writable to the device → expanded DMA
  attack surface / isolation bug. **HIGH** (security-relevant).
- **Non-coherent / bounce DMA:** extra or wrong sync/copy vs the
  documented TX/RX directions → possible packet corruption. **HIGH** if
  it hits; **MEDIUM** on typical coherent x86 without IOMMU
  (BIDIRECTIONAL is documented to “work” at a cost).
- No oops in the commit message. Severity still **HIGH** because DMA
  permission and coherency are real user-visible classes, not style.

Step 8.4: CALCULATE RISK-BENEFIT RATIO
Record: **Benefit: high** (correct DMA direction on every packet for a
common WiFi driver; tighter IOMMU perms on TX). **Risk: very low** (one
assignment of an already-passed enum). **Ratio: strongly favors
backport.**

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

Step 9.1: COMPILE THE EVIDENCE

**FOR:**
- Real, long-standing bug: direction parameter never stored; field stays
  `DMA_BIDIRECTIONAL`.
- Code is in this 5.15 tree (`9a1bb60250d2` is an ancestor).
- One-line, obviously correct, no new API.
- IOMMU maps BIDIRECTIONAL as R+W; TX should be device-read-only.
- DMA API requires precise TX/RX directions for networking.
- Maintainer Acked-by; original submission had Fixes + Cc: stable
  (dropped on apply).
- Applies here with only the one store.

**AGAINST:**
- No crash/syzbot report; driver has “worked” since 2014 on many
  coherent platforms.
- Affects PCIe msgbuf only, not all brcmfmac buses.

**UNRESOLVED:**
- Could not `b4 dig` the mainline SHA (not in this checkout);
  lore.kernel.org HTTP 403.
- No evidence of a stable-list rejection.

Step 9.2: APPLY THE STABLE RULES CHECKLIST
1. Obviously correct and tested? **PASS** — missing store; maintainer
   ack.
2. Fixes a real bug that affects users? **PASS** — wrong DMA direction
   on live TX/RX.
3. Important issue (crash, security, corruption, deadlock)? **PASS** —
   IOMMU write on TX buffers; coherency/bounce mismatch.
4. Small and contained? **PASS** — +1 line, one function.
5. No new features or APIs? **PASS**.
6. Can apply to the local tree? **PASS** — add the assignment after
   `pktids->array_size = nr_array_entries;`.

Step 9.3: CHECK FOR EXCEPTION CATEGORIES
Record: Not a device-ID/quirk/DT/docs exception. Ordinary correctness
fix.

Step 9.4: MAKE YOUR DECISION
Backport. The bug exists in 5.15, the fix is the intended store of an
existing parameter, and DMA direction is not optional cosmetics: it
controls IOMMU prot and cache/bounce behavior on a production WiFi
datapath.

What it solves for stable users: PCIe brcmfmac currently maps TX and RX
SKBs as bidirectional. That grants the device write access to TX buffers
under IOMMU and uses the wrong sync/bounce path. Storing the caller
direction restores `DMA_TO_DEVICE` / `DMA_FROM_DEVICE` as the attach
path already requests.

Risk vs benefit: one assignment vs a persistent DMA-permission/coherency
bug. No prerequisites beyond code already in this tree.

Verification:
- [Phase 1] Tags on applied commit: Acked-by Arend van Spriel, Link
  msgid, SOBs Can Peng / Johannes Berg; no Fixes/Cc in applied text
- [Phase 1] Original mail: Fixes 9a1bb60250d2, Cc:
  stable@vger.kernel.org (openwall 2026-07-24)
- [Phase 2] Diff: +1 line `pktids->direction = direction;` in
  `brcmf_msgbuf_init_pktids`
- [Phase 2] Local `dma-direction.h`: `DMA_BIDIRECTIONAL = 0`
- [Phase 2] `dma_info_to_prot`: BIDIRECTIONAL → READ|WRITE; TO_DEVICE →
  READ
- [Phase 3] `git blame`: missing store since 9a1bb60250d2 (v3.17-rc1)
- [Phase 3] `git merge-base --is-ancestor 9a1bb60250d2b HEAD`: yes
- [Phase 3] This fix not in tree (`git log --grep` empty on msgbuf.c)
- [Phase 3] Related: ddb864ea9ca2e already in tree; still uses unset
  direction
- [Phase 4] b4 dig: cannot run on missing mainline SHA; lore 403
- [Phase 4] Thread: v1 only; Ack 2026-08-02; no NAK
- [Phase 5] Callers: attach + TX flow + RX/ioctl/event buffer post; PCIe
  msgbuf hot path
- [Phase 6] `git describe HEAD`: p-5.15-2-g6703e5d2f3a29; `make
  kernelversion`: 5.15.221
- [Phase 6] Local init still lacks the store (lines 310–313)
- [Phase 8] Failure: wrong DMA dir / IOMMU TX writable; severity HIGH
- UNVERIFIED: full lore.kernel.org thread via b4; explicit stable-list
  NAK (none found)

**YES**

 drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
index 45fbcbdc7d9e4..de47d6b7e02b2 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
@@ -310,6 +310,7 @@ brcmf_msgbuf_init_pktids(u32 nr_array_entries,
 	}
 	pktids->array = array;
 	pktids->array_size = nr_array_entries;
+	pktids->direction = direction;
 
 	return pktids;
 }
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18-6.6] wifi: iwlwifi: mvm: ignore sync frames when sync is disabled
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
  2026-10-19 13:45 ` [PATCH AUTOSEL 6.18-5.10] wifi: brcmfmac: Set DMA direction for msgbuf packet IDs Sasha Levin
@ 2026-10-19 13:45 ` Sasha Levin
  2026-10-19 13:45 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: support TTL platform device ID Sasha Levin
                   ` (38 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:45 UTC (permalink / raw)
  To: patches, stable
  Cc: Emmanuel Grumbach, Miri Korenblit, Sasha Levin, linux-wireless,
	linux-kernel

From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>

[ Upstream commit a790f60cc4d7dc64a2d7cadb94a3d9f60392bed4 ]

Gate time-sync frame interception on the active flag so frames are not
queued after time-sync teardown.

Assisted-by: GitHubCopilot:GPT-5.3-Codex
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Link: https://patch.msgid.link/20260717172958.ac73ee199a25.Ic1489244f9b02da93060f0a0e5b300a73527f265@changeid
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **7.3.0-rc4** (`v7.3-rc4-27-gf0100363d8c37`). This
analysis is only about that checkout: the iwlwifi MVM time-sync path
exists here, and the two-line guard is a real teardown leak/drop fix.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

Step 1.1: PARSE THE SUBJECT LINE
Record: **[iwlwifi/mvm] [ignore/gate] intercept time-sync frames only
while time-sync is active**

Step 1.2: PARSE ALL COMMIT MESSAGE TAGS
Record:
- **Assisted-by:** GitHubCopilot:GPT-5.3-Codex
- **Signed-off-by:** Emmanuel Grumbach (author)
- **Link:** https://patch.msgid.link/20260717172958.ac73ee199a25.Ic14892
  44f9b02da93060f0a0e5b300a73527f265@changeid
- **Signed-off-by:** Miri Korenblit (iwlwifi maintainer)
- **No Fixes:, Reported-by:, Tested-by:, Reviewed-by:, Acked-by:, or Cc:
  stable** (absence is expected for this pipeline)
- Ignored: any pipeline “already selected” markers (none present beyond
  a normal maintainer SOB)

Step 1.3: ANALYZE THE COMMIT BODY TEXT
Record:
- **Bug:** After time-sync teardown, matching TM/FTM frames are still
  intercepted and queued.
- **Symptom:** Frames sit on `frame_list` instead of going through the
  normal RX/TX-status path; they are not consumed by firmware time-sync
  notifications once the feature is off.
- **Version info in message:** none.
- **Root cause (from message + code):** interception is keyed only on
  `peer_addr`, which is left set after disable.

Step 1.4: DETECT HIDDEN BUG FIXES
Record: This is an explicit bug fix (not style). “Ignore … when
disabled” / “frames are not queued after teardown” is incomplete disable
handling, which produces an skb leak and dropped TM/FTM frames.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

Step 2.1: INVENTORY THE CHANGES
Record:
- **File:** `drivers/net/wireless/intel/iwlwifi/mvm/time-sync.h` (+4 /
  ~0; copyright year + 2-line guard)
- **Function:** `iwl_mvm_time_sync_frame()`
- **Scope:** single-file surgical fix

Step 2.2: UNDERSTAND THE CODE FLOW CHANGE
Record:
- **Before:** If `peer_addr` matches and the skb is a TM or FTM action
  frame, queue it on `mvm->time_sync.frame_list` and return true (caller
  skips `ieee80211_tx_status_skb` / `iwl_mvm_pass_packet_to_mac80211`).
- **After:** If `!mvm->time_sync.active`, return false immediately so
  the frame takes the normal path.
- **Path:** RX NAPI and TX-status reclaim; not probe init.

Step 2.3: IDENTIFY THE BUG MECHANISM
Record:
- **Category:** logic/correctness + resource leak on teardown.
- **Mechanism:** `iwl_mvm_time_sync_config()` sets `active = (protocols
  != 0)` and purges `frame_list` when inactive, but still copies
  `peer_addr`. The interceptor never consulted `active`, so after
  disable it kept stealing matching frames.
- Compared with MLD: `iwl_mld_time_sync_frame()` already no-ops when
  `mld->time_sync` is NULL after `iwl_mld_deinit_time_sync()`. MVM
  stores time-sync in an embedded struct, so it needs the `active` flag.

Step 2.4: ASSESS THE FIX QUALITY
Record:
- Obviously correct: gate on the same flag config already uses.
- Minimal; no API/data-structure change.
- Regression risk is low. A remaining TOCTOU vs
  `iwl_mvm_time_sync_config()` (mutex vs RX/TX softirq, no `READ_ONCE`)
  is pre-existing; this closes the post-teardown window, which is the
  user-visible bug.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

Step 3.1: BLAME THE CHANGED LINES
Record:
- Interceptor introduced in **c7eca79def44f** (`wifi: iwlwifi: mvm:
  report hardware timestamps in RX/TX status`, Avraham Stern,
  2023-03-20).
- First appeared in **v6.4-rc1** (`git describe --contains
  c7eca79def44f` → `v6.4-rc1~132^2~151^2~105`).
- `struct iwl_time_sync_data { frame_list, peer_addr, active }` is from
  that same commit. The bug is old, not last-month code.

Step 3.2: FOLLOW THE FIXES: TAG
Record: No `Fixes:` tag. The incomplete disable path is
**cf85123a210fe** (`wifi: iwlwifi: mvm: support enabling and disabling
HW timestamping`, also v6.4-rc1): it stopped auto-enabling on station
add, added purge-on-disable, and removed `iwl_mvm_time_sync_sta_rm()`,
but did not gate `iwl_mvm_time_sync_frame()`.

Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES
Record (on this tree, path-limited):
- `a790f60cc4d7d` — this fix
- `08e6183ed2568` — wifi action-frame struct move
- `cf85123a210fe` — enable/disable HW timestamping
- `a2f49f7d52a9e` / `c7eca79def44f` — original time-sync
Standalone. Series tag is **3/8** of an iwlwifi-next bundle; patches 1–2
and 4–8 touch other files. This hunk does not depend on them.

Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS
Record: Emmanuel Grumbach is a long-time iwlwifi developer. Nearby July
2026 commits are other iwlwifi correctness fixes. Maintainer **Miri
Korenblit** signed off and applied it.

Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS
Record: Needs `mvm->time_sync.active` and `iwl_mvm_time_sync_frame()`,
both present since v6.4 and in this 7.3 tree. Applies standalone.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION
Record:
- `b4 dig -c a790f60cc4d7` → https://patch.msgid.link/20260717172958.ac7
  3ee199a25.Ic1489244f9b02da93060f0a0e5b300a73527f265@changeid
- `b4 dig -a`: single **v1** series `[PATCH iwlwifi-next 0/8] wifi:
  iwlwifi: updates - 07-17-2026`
- Cover letter: “A couple of fixes, features and cleanups.” This patch
  is listed under Emmanuel’s fixes.
- Saved mbox: 9 messages (cover + 8 patches), **no review replies, NAKs,
  or Cc: stable**.
- WebFetch of lore returned **403**; discussion recovered via `b4 dig
  -m`.

Step 4.2: CHECK WHO REVIEWED THE PATCH
Record (`b4 dig -w`): Miri Korenblit, Johannes Berg
(`johannes@sipsolutions.net`), linux-wireless, Emmanuel Grumbach. Right
lists/maintainers; no extra Reviewed-by on this patch. Miri’s SOB is the
maintainer merge.

Step 4.3: SEARCH FOR THE BUG REPORT
Record: No Reported-by / bugzilla / syzbot. Bug is from code inspection
of teardown vs interceptor.

Step 4.4: CHECK FOR RELATED PATCHES AND SERIES
Record: Mixed iwlwifi-next series. This patch only changes `mvm/time-
sync.h`. Other patches are MLD/ACPI/debug and are **not** prerequisites.

Step 4.5: CHECK STABLE MAILING LIST HISTORY
Record: WebSearch of lore.kernel.org/stable for this subject found
**no** discussion. UNVERIFIED beyond that search (lore HTML 403).

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF
Record: `iwl_mvm_time_sync_frame()` only.

Step 5.2: TRACE CALLERS
Record:
1. `drivers/net/wireless/intel/iwlwifi/mvm/tx.c` — TX-status reclaim: if
   interceptor returns true, skip `ieee80211_tx_status_skb()`.
2. `drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c` — RX: if true, skip
   pass-to-mac80211.

Both are hot NAPI/TX-complete paths, but the match is rare (TM/FTM
action frames to a configured peer).

Step 5.3: TRACE CALLEES
Record: `ether_addr_equal()`, `ieee80211_is_timing_measurement()`,
`ieee80211_is_ftm()`, `skb_queue_tail()`. No alloc/locks in the inline
itself. Disable path: `iwl_mvm_time_sync_config()` under `mvm->mutex`
(from `iwl_mvm_set_hw_timestamp()` via mac80211 `set_hw_timestamp`).

Step 5.4: FOLLOW THE CALL CHAIN
Record:
- Enable/disable: userspace nl80211 `SET_HW_TIMESTAMP` →
  `ieee80211_set_hw_timestamp()` → `iwl_mvm_set_hw_timestamp()` →
  `iwl_mvm_time_sync_config()`.
- After disable, any later TM/FTM RX/TX for that `peer_addr` hits the
  interceptor.
- Reachable from the air for RX (FTM/TM responses) once the feature was
  enabled then disabled. Not a general unprivileged syscall crash path.

Step 5.5: SEARCH FOR SIMILAR PATTERNS
Record: MLD already treats “no time_sync object” as inactive. No second
MVM copy of this bug.

===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================

Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?
Record:
- Tree: **7.3.0-rc4** (`git describe HEAD` =
  `v7.3-rc4-27-gf0100363d8c37`).
- `git merge-base --is-ancestor a790f60cc4d7 HEAD` succeeded (commit is
  in this lineage; expected for mainline, not used as “already
  selected”).
- Pre-fix interceptor and `time_sync.active` / `peer_addr` /
  `frame_list` all exist here. Bug introduced in v6.4, **not** after
  this tree.

Step 6.2: CHECK FOR BACKPORT COMPLICATIONS
Record: Current `time-sync.h` matches the patched form. Against the pre-
fix function (unchanged since c7eca79 except this guard), apply is
**clean**.

Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE
Record: Only this commit implements the `active` gate. `ead65aa2d5155`
(“send time sync only if needed”) is unrelated.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY
Record: **wifi / iwlwifi MVM** (Intel wireless). **IMPORTANT** (very
common hardware), not core mm/VFS. Time-sync/HW timestamping is a
narrower slice of that driver.

Step 7.2: ASSESS SUBSYSTEM ACTIVITY
Record: iwlwifi is actively developed (many 2026 commits). This
particular file is mature (stable since 6.4 aside from the action-frame
helper move).

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

Step 8.1: DETERMINE WHO IS AFFECTED
Record: Intel iwlwifi **MVM** users who used nl80211 HW timestamping
(TM/FTM) and then disabled it, while TM/FTM frames for that peer
continue. Not universal.

Step 8.2: DETERMINE THE TRIGGER CONDITIONS
Record:
- Trigger: enable HW timestamp for a peer, then disable (`protocols ==
  0`). `peer_addr` stays set; `active` is false; interceptor still
  matched.
- Not every boot; requires that userspace API.
- After that, RX of matching FTM/TM frames from the network can keep
  filling `frame_list`.
- Enable/disable typically needs netlink admin; subsequent RX leak can
  be driven by frames on the air.

Step 8.3: DETERMINE THE FAILURE MODE SEVERITY
Record:
- Unbounded **skb leak** of intercepted frames (purge only runs on a
  later inactive config).
- **Dropped** TM/FTM frames that should have gone to mac80211.
- **Missing TX status** (`ieee80211_tx_status_skb` skipped) for
  intercepted TX frames.
- Not a panic, UAF, or filesystem corruption.
- **Severity: HIGH** for the leak/drop on a live packet path; feature is
  uncommon so blast radius is limited.

Step 8.4: CALCULATE RISK-BENEFIT RATIO
Record:
- **Benefit:** stops post-disable frame theft, skb leak, and missing TX
  completion. Small but real.
- **Risk:** very low (2 functional lines, same flag already used in
  config).
- **Ratio:** favorable for any tree that has MVM time-sync (this 7.3
  tree does).

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

Step 9.1: COMPILE THE EVIDENCE

**FOR backporting to this tree:**
- Real teardown bug: interceptor ignored `active` while `peer_addr`
  survived disable.
- Consequences: skb leak, silent TM/FTM drops, skipped TX status.
- Two-line, obviously correct guard; no new API.
- Bug in code present since v6.4; this 7.3 tree has that code.
- Author + iwlwifi maintainer SOB; sent to linux-wireless / Johannes
  Berg.
- Standalone; other 3/8 series patches not required.
- MLD already has the equivalent “don’t intercept after teardown”
  behavior.

**AGAINST:**
- No `Fixes:` / `Reported-by` / syzbot / stable discussion.
- Path is niche (HW timestamping), not a crash/CVE-class bug.
- Commit message is short and Copilot-assisted.
- Mixed “fixes + features” series with no extra review on this patch.

**UNRESOLVED:**
- lore HTML 403; used b4 mbox instead.
- No public user reports found.

Step 9.2: APPLY THE STABLE RULES CHECKLIST
1. Obviously correct and tested? **PASS** — matches existing `active`
   flag; merged by iwlwifi maintainer (no separate Tested-by).
2. Fixes a real bug that affects users? **PASS** — post-disable
   intercept/leak/drop.
3. Important issue? **PASS** — unbounded skb leak and missing TX
   completion on a packet path (not a panic; still user-visible).
4. Small and contained? **PASS** — one inline, +2 functional lines.
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — `time_sync.active` and
   callers exist; hunk is trivial.

Step 9.3: CHECK FOR EXCEPTION CATEGORIES
Record: None (not a device ID / quirk / DT / build / docs exception).
Ordinary small driver correctness fix.

Step 9.4: MAKE YOUR DECISION
This tree’s iwlwifi MVM time-sync stack still has the disable path that
leaves `peer_addr` set. Without the `active` check, teardown is
incomplete: TM/FTM skbs are queued forever and never get TX status or
mac80211 RX. The patch is the same check MVM config already uses and
that MLD gets via a NULL time-sync object. That is in scope for this 7.3
tree and meets stable rules.

What it solves for users of this tree: after HW timestamping is turned
off, FTM/TM frames are delivered normally instead of leaking on
`frame_list`.

Risk vs benefit: two lines vs a real leak/drop; benefit wins.

No missing prerequisites in this checkout.

Verification:
- [Phase 1] Parsed tags: Assisted-by Copilot, SOB Grumbach + Korenblit,
  msgid.link; no Fixes/Reported-by/Cc stable
- [Phase 2] Diff: +2-line `if (!mvm->time_sync.active) return false;` in
  `iwl_mvm_time_sync_frame()`
- [Phase 2] Confirmed disable leaves `peer_addr` set in
  `iwl_mvm_time_sync_config()` (`time-sync.c` around the `active =
  protocols != 0` assignment and `skb_queue_purge`)
- [Phase 3] `git blame` parent: interceptor from c7eca79def44f
  (v6.4-rc1); disable redesign cf85123a210fe (v6.4-rc1)
- [Phase 3] No Fixes: tag; related history limited to `mvm/time-sync.*`
- [Phase 3] `git merge-base --is-ancestor a790f60cc4d7 HEAD` — commit is
  in this 7.3 lineage
- [Phase 4] `b4 dig -c/-a/-w/-m`: v1 iwlwifi-next 3/8, no replies;
  recipients Korenblit, Johannes, linux-wireless
- [Phase 4] WebFetch lore 403; stable WebSearch found no thread
- [Phase 5] Callers: `mvm/tx.c` TX status, `mvm/rxmq.c` RX; userspace
  via `set_hw_timestamp`
- [Phase 5] MLD equivalent already NULL-checks `time_sync` after deinit
- [Phase 6] `git describe HEAD` = v7.3-rc4-27; `make kernelversion` =
  7.3.0-rc4; feature present
- [Phase 8] Failure mode: skb leak + dropped TM/FTM + skipped TX status;
  severity HIGH on that path
- UNVERIFIED: public user reports; full lore HTML thread rendering

**YES**

 drivers/net/wireless/intel/iwlwifi/mvm/time-sync.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-sync.h b/drivers/net/wireless/intel/iwlwifi/mvm/time-sync.h
index 2cfd0fb5e781a..7bdbacb640787 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/time-sync.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-sync.h
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
 /*
  * Copyright (C) 2022 Intel Corporation
+ * Copyright (C) 2026 Intel Corporation
  */
 #ifndef __TIME_SYNC_H__
 #define __TIME_SYNC_H__
@@ -19,6 +20,9 @@ int iwl_mvm_time_sync_config(struct iwl_mvm *mvm, const u8 *addr,
 static inline
 bool iwl_mvm_time_sync_frame(struct iwl_mvm *mvm, struct sk_buff *skb, u8 *addr)
 {
+	if (!mvm->time_sync.active)
+		return false;
+
 	if (ether_addr_equal(mvm->time_sync.peer_addr, addr) &&
 	    (ieee80211_is_timing_measurement(skb) || ieee80211_is_ftm(skb))) {
 		skb_queue_tail(&mvm->time_sync.frame_list, skb);
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18] wifi: iwlwifi: support TTL platform device ID
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
  2026-10-19 13:45 ` [PATCH AUTOSEL 6.18-5.10] wifi: brcmfmac: Set DMA direction for msgbuf packet IDs Sasha Levin
  2026-10-19 13:45 ` [PATCH AUTOSEL 6.18-6.6] wifi: iwlwifi: mvm: ignore sync frames when sync is disabled Sasha Levin
@ 2026-10-19 13:45 ` Sasha Levin
  2026-10-19 13:45 ` [PATCH AUTOSEL 6.18-5.10] wifi: rtlwifi: fix disabling of ASPM for RTL8723BE with AER flooding Sasha Levin
                   ` (37 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:45 UTC (permalink / raw)
  To: patches, stable
  Cc: Miri Korenblit, Johannes Berg, Sasha Levin, linux-wireless,
	linux-kernel

From: Miri Korenblit <miriam.rachel.korenblit@intel.com>

[ Upstream commit 3bff0d12c36247073fca976498b58a940fca72dc ]

Add support for a new device ID that we will have on TTL (sc2).

Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Link: https://patch.msgid.link/20260714165826.46183446954f.Icc260831e530c1c92c9be615a7077768b1b9ae30@changeid
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

Local tree is **7.3.0-rc4** (`v7.3-rc4-27-gf0100363d8c37`). The change
is a one-line PCI ID add for existing iwlwifi Sc/sc2 support. That is
the stable device-ID exception, so the rest of this write-up is the
forensic checklist behind a **YES**.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

**Step 1.1: PARSE THE SUBJECT LINE**
Record: **[iwlwifi / wifi] [support] [add PCI device ID for TTL (sc2)
platform]**

- Subsystem: `wifi: iwlwifi`
- Verb: **support** (hardware enablement, not a crash fix)
- Intent: bind iwlwifi to a new Intel platform PCI ID

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- **Reviewed-by:** Johannes Berg `<johannes.berg@intel.com>` (iwlwifi
  maintainer)
- **Link:** `https://patch.msgid.link/20260714165826.46183446954f.Icc260
  831e530c1c92c9be615a7077768b1b9ae30@changeid`
- **Signed-off-by:** Miri Korenblit
  `<miriam.rachel.korenblit@intel.com>` (author)
- No **Fixes:** tag (expected; this is not a regression fix)
- No **Cc: stable** (expected for this review path)
- No **Reported-by**, **Tested-by**, **Acked-by**, syzbot, or bugzilla
  tags
- Ignore pipeline **Signed-off-by: Sasha Levin** / **[Upstream commit
  ...]** (none present on the real commit `3bff0d12c36247`)

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug/problem:** Driver does not claim PCI device `0x9327`, so TTL
  (sc2) Wi-Fi does not bind.
- **Symptom:** iwlwifi never probes; no wireless interface on that SKU.
- **Version info:** none in the message. Author date 2026-07-14; landed
  as `v7.2-rc1-199-g3bff0d12c3624`.
- **Root cause (author):** missing PCI ID in `iwl_hw_card_ids` for
  hardware “we will have on TTL (sc2).” Same wording as the earlier RZL
  ID commit (`6a1b633fdcd904`).

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: **Not a hidden leak/race/UAF.** It is an explicit new-PCI-ID
addition. That is an allowed stable exception, not a disguised memory-
safety fix.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `drivers/net/wireless/intel/iwlwifi/pcie/drv.c` (**+1 / -0**)
- Function/data: `iwl_hw_card_ids[]` (PCI ID table)
- Scope: **single-file surgical**, one table entry

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:
- **Before:** Sc block lists `0xE440`, `0xE340`, `0xD340`, `0x6E70`,
  `0xD240` with `iwl_sc_mac_cfg`. `0x9327` does not match;
  `iwl_pci_driver.id_table` does not bind.
- **After:** `{IWL_PCI_DEVICE(0x9327, PCI_ANY_ID, iwl_sc_mac_cfg)}` is
  added. Probe is `iwl_pci_probe()` → `iwl_pci_gen1_2_probe()` with
  existing Sc MAC config.
- Path affected: **PCI enumeration / driver bind** for that device ID
  only.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record: **[Hardware workaround / device ID addition]**
- Macro expands to Intel vendor, device `0x9327`, any
  subvendor/subdevice, `driver_data = iwl_sc_mac_cfg`.
- Newer iwlwifi devices are identified from HW RF/MAC registers via
  `iwl_pci_find_dev_info()`; Sc IDs are not duplicated as `DEVICE(0x…)`
  in `iwl_dev_info_table`. FM/WH/PE RF entries already exist. Same
  pattern as `0xD240`.
- `MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids)` updates userspace modalias
  matching.

**Step 2.4: ASSESS THE FIX QUALITY**
Record:
- **Quality:** Obviously correct; identical to neighboring Sc IDs.
- **Regression risk:** Very low. Only PCI `8086:9327` is affected. Wrong
  ID would only mis-bind another Intel function using that ID (Intel
  assigns these IDs).
- No API, locking, or data-structure change.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

**Step 3.1: BLAME THE CHANGED LINES**
Record:
- Line adding `0x9327`: commit **`3bff0d12c36247`** (Miri Korenblit,
  2026-07-14).
- Surrounding Sc IDs: `c96a36491003d7` (2025-05-08) and `6a1b633fdcd904`
  (RZL `0xD240`, 2025-06-12).
- `iwl_sc_mac_cfg` and Sc support are long-lived in this 7.3 tree, not
  last-month code.

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: **No Fixes: tag.** Not introduced by a buggy prior commit; the
ID was simply absent.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record:
- Related: `6a1b633fdcd904` “support RZL platform device ID” (same one-
  line pattern).
- `5f88b045d959f` “pcie: add two LNL PCI IDs”.
- No later `-S 0x9327` follow-up; the ID was not corrected or reverted.
- Nearby series mates (compile-time hcmd check, FCS d3 fix, etc.) do
  **not** touch this table entry.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Miri Korenblit is a regular iwlwifi author (often applying Intel
wireless patches). Johannes Berg reviewed this ID add. Same author wrote
the RZL ID add.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record:
- Needs `iwl_sc_mac_cfg` and the Sc PCI block — **present** in this tree
  (`cfg/sc.c`, `iwl-config.h`, `drv.c`).
- sc2 firmware prefixes `IWL_SC2_A_FM_C_FW_PRE` /
  `IWL_SC2_A_WH_A_FW_PRE` and `IWL_CFG_MAC_TYPE_SC2` are already here;
  MAC type is read from CSR at runtime, not from this PCI ID.
- **Standalone:** one line; does not need the other 14 patches from the
  07-14-2026 series.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- `b4 dig -c 3bff0d12c36247`: **[PATCH v2 iwlwifi-next 04/15] wifi:
  iwlwifi: support TTL platform device ID**
- URL: `https://patch.msgid.link/20260714165826.46183446954f.Icc260831e5
  30c1c92c9be615a7077768b1b9ae30@changeid`
- `b4 dig -a`: v2 of “wifi: iwlwifi: updates - 07-14-2026”. Cover
  letter: v2 was a resend so -next contained an unrelated compile fix
  for a sibling patch. **This ID hunk did not change between versions.**
- Thread mbox: **16 messages, all series patches**; no NAKs, no public
  review replies, no `Cc: stable` discussion on this patch.
- Cover letter: “Usual fixed, cleanups and **features** from our
  internal tree.” This ID add is listed under Miri’s patches, not as a
  CVE/crash fix.
- WebFetch to lore.kernel.org returned **403**; discussion recovered via
  `b4 dig -m`.

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record (`b4 dig -w`): To/Cc **Johannes Berg**, **linux-
wireless@vger.kernel.org**. **Reviewed-by: Johannes Berg** already on
the sent patch (internal review). Right maintainer and list.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: No Reported-by / bugzilla / syzbot. This is vendor hardware
enablement, not a user crash report.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: 15-patch **iwlwifi-next** “updates” mix (validations, recovery,
LARI v14, UHR DBE). **04/15 is independent.** Other patches are not
required for this ID to apply or work.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: lore.kernel.org/stable WebFetch **403**. `b4` thread has **no**
stable-list discussion. **UNVERIFIED** whether anyone later nominated it
on stable@.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

**Step 5.1: IDENTIFY KEY FUNCTIONS**
Record: No function body edited. Data: **`iwl_hw_card_ids[]`**.
Consumers: `MODULE_DEVICE_TABLE`, `iwl_pci_driver.id_table`, probe
`iwl_pci_probe()`.

**Step 5.2: TRACE CALLERS**
Record:
- `iwl_pci_register_driver()` registers `iwl_pci_driver` with `.id_table
  = iwl_hw_card_ids`.
- PCI core calls `iwl_pci_probe()` on match.
- Context: process/probe, not IRQ. Common path **only if** device
  `8086:9327` is present.

**Step 5.3: TRACE CALLEES**
Record: Probe enables PCI, maps BAR0, reads `CSR_HW_REV`, calls
`iwl_pci_gen1_2_probe(..., iwl_sc_mac_cfg, ...)`. Device family
`IWL_DEVICE_FAMILY_SC` is already used by other Sc IDs.

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: PCI enumerates → id_table match → `iwl_pci_probe` → gen1/2
trans/op-mode → firmware via existing sc/sc2 names. **Reachable from
userspace** only by having the hardware (or VFIO/passthrough of that
ID). Not a syscall fuzz path.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: Same one-line Sc ID adds (`0xD240` RZL). No extra
`IWL_DEV_INFO(DEVICE(0x9327))` for other Sc IDs either.

===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: **Yes.** `drivers/net/wireless/intel/iwlwifi/pcie/drv.c` Sc
block and `iwl_sc_mac_cfg` exist. Without this ID, `0x9327` is
unmatched. sc2 (`IWL_CFG_MAC_TYPE_SC2` / `iwlwifi-sc2-a0-*`) already
exists. Bug/gap is “missing ID,” not missing subsystem.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: **Clean apply.** Neighboring lines match the candidate diff. No
refactor needed on 7.3-rc4.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: No alternate TTL ID fix. `0x9327` appears only from this commit.
Prerequisite Sc/sc2 stack is already in 7.3.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: **drivers/net/wireless/intel/iwlwifi** — **IMPORTANT** (very
common laptop/desktop Wi-Fi), not mm/core. Only TTL/sc2 SKUs with this
ID.

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: **Active** (regular Intel iwlwifi-next dumps). ID tables are
still the supported way to enable new SKUs; this is not staging.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: **Driver-specific / hardware-specific.** Users with Intel Wi-Fi
PCI `0x9327` (TTL/sc2). Everyone else: no behavior change.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record: Boot or hotplug of that device. Common **on that platform**,
never otherwise. Unprivileged users cannot trigger it without the
hardware. **UNVERIFIED** whether TTL has shipped at evaluation time;
Intel’s “we will have” language matches prior RZL ID adds.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record: **No oops/UAF/corruption.** Failure is **Wi-Fi never binds** on
that SKU. Severity for those users is **HIGH** (device unusable); global
severity **LOW**. Stable still takes these ID adds.

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record:
- **Benefit:** Enables existing iwlwifi/Sc/sc2 on TTL platforms that
  this tree already knows how to drive.
- **Risk:** **Very low** (1 line, existing cfg pointer, isolated PCI
  match).
- **Ratio:** Benefit/risk favors taking it.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

**Step 9.1: COMPILE THE EVIDENCE**

FOR:
- Canonical **new PCI ID on an existing driver**
- 1 line, same as other Sc IDs and RZL
- `iwl_sc_mac_cfg`, sc2 firmware names, RF matching already in this tree
- Maintainer Reviewed-by (Johannes Berg)
- `MODULE_DEVICE_TABLE` so autoload works
- Standalone; no series dependency
- Zero impact on other devices

AGAINST:
- Not a crash/security/corruption fix; iwlwifi-next “features” series
- Future-tense “we will have”; shipping status unverified
- No stable@ nomination in the thread
- Mixed 15-patch series (this patch itself is still self-contained)

UNRESOLVED:
- lore.kernel.org HTTP 403 (mailbox recovered via b4)
- No stable@ thread found
- Whether TTL silicon is in users’ machines yet

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — one table row, maintainer
   Reviewed-by.
2. Fixes a real bug that affects users? **PASS** — missing ID means the
   driver never attaches (real for that SKU).
3. Important issue (crash, security, corruption, deadlock)? **FAIL** as
   crash/security; **PASS** under the documented **device-ID
   exception**.
4. Small and contained? **PASS** — +1 line, one file.
5. No new features or APIs? **PASS** — no new API; only an ID on
   existing probe/config.
6. Can apply to the local tree? **PASS** — Sc/sc2 and `iwl_sc_mac_cfg`
   are here; hunk applies cleanly.

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: **NEW DEVICE ID (PCI) to an existing driver.** Driver already
exists; only `0x9327` is new. Same class as “drm/i915: Add new device ID
for Raptor Lake.”

**Step 9.4: MAKE YOUR DECISION**
This tree already has iwlwifi Sc/sc2. Adding PCI ID `0x9327` is the
standard, low-risk way to make TTL hardware work. It should be taken for
this tree.

### What it solves and why it matters here
Without the ID, PCI `8086:9327` never matches `iwl_pci_driver`, so Wi-Fi
stays down on TTL (sc2) even though this kernel already has
`iwl_sc_mac_cfg` and sc2 firmware naming. That is exactly the hardware-
enablement stable trees routinely accept.

### Stable rules
Small, correct, no new APIs, applies here. Importance is “device works,”
via the PCI-ID exception, not a KASAN-class bug.

### Risk vs benefit
Risk is a single ID match. Benefit is working wireless on that Intel
SKU. Other machines are unchanged.

### Concerns
None that block a backport here: no missing prerequisites, no extra
`IWL_DEV_INFO` needed (other Sc IDs have none), no follow-up fix to
`0x9327`. Firmware blobs remain a linux-firmware concern, not a reason
to omit the ID.

Verification:
- [Phase 1] Subject/tags: support new ID; Reviewed-by Johannes Berg;
  Link msgid; no Fixes/stable/syzbot
- [Phase 1] Body: “new device ID that we will have on TTL (sc2)”
- [Phase 2] Diff: +1 line in `iwl_hw_card_ids[]` under Sc devices:
  `0x9327` → `iwl_sc_mac_cfg`
- [Phase 2] `IWL_PCI_DEVICE` → Intel vendor + `MODULE_DEVICE_TABLE` +
  `iwl_pci_driver.id_table`
- [Phase 2] Other Sc IDs also lack `DEVICE(0x…)` in
  `iwl_dev_info_table`; FM/WH matching already present
- [Phase 3] `git describe HEAD` / Makefile: **7.3.0-rc4**
  (`v7.3-rc4-27-gf0100363d8c37`)
- [Phase 3] `git blame`: `0x9327` is `3bff0d12c36247`; neighbors
  `c96a36491003d7` / `6a1b633fdcd904`
- [Phase 3] `git merge-base --is-ancestor 3bff0d12c36247 HEAD` → yes;
  `git describe 3bff0d12c36247` → `v7.2-rc1-199-g3bff0d12c3624`
- [Phase 3] `git log -S 0x9327 -- drv.c` → only this commit (no later
  correction)
- [Phase 3] RZL analog `6a1b633fdcd904` is the same one-line pattern
- [Phase 4] `b4 dig -c/-a/-w/-m`: v2 iwlwifi-next 04/15; Johannes +
  linux-wireless; no NAK; v2 resend unrelated to this hunk
- [Phase 4] Cover letter: mixed fixes/cleanups/features; this ID listed
  under Miri
- [Phase 4] UNVERIFIED: lore HTTP 403; no stable@ thread retrieved
- [Phase 5] Callers: PCI probe via `iwl_pci_probe` →
  `iwl_pci_gen1_2_probe`; sc2 MAC type from CSR (`iwl-drv.c`)
- [Phase 6] `iwl_sc_mac_cfg` in `cfg/sc.c`; sc2 FW prefixes present;
  hunk context matches
- [Phase 6] Apply difficulty: clean
- [Phase 7] iwlwifi: important, actively maintained
- [Phase 8] Failure: no driver bind on `0x9327`; risk very low
- UNVERIFIED: whether TTL hardware is already shipping

**YES**

 drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index 0e8481219839b..4314d95dd12af 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -548,6 +548,7 @@ VISIBLE_IF_IWLWIFI_KUNIT const struct pci_device_id iwl_hw_card_ids[] = {
 	{IWL_PCI_DEVICE(0xD340, PCI_ANY_ID, iwl_sc_mac_cfg)},
 	{IWL_PCI_DEVICE(0x6E70, PCI_ANY_ID, iwl_sc_mac_cfg)},
 	{IWL_PCI_DEVICE(0xD240, PCI_ANY_ID, iwl_sc_mac_cfg)},
+	{IWL_PCI_DEVICE(0x9327, PCI_ANY_ID, iwl_sc_mac_cfg)},
 #endif /* CONFIG_IWLMVM || CONFIG_IWLMLD */
 
 	{0}
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] wifi: rtlwifi: fix disabling of ASPM for RTL8723BE with AER flooding
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (2 preceding siblings ...)
  2026-10-19 13:45 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: support TTL platform device ID Sasha Levin
@ 2026-10-19 13:45 ` Sasha Levin
  2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7921: fix memory leak when skb_linearize fails in mcu rx event Sasha Levin
                   ` (36 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:45 UTC (permalink / raw)
  To: patches, stable
  Cc: William Hansen-Baird, Ping-Ke Shih, Sasha Levin, linux-wireless,
	linux-kernel

From: William Hansen-Baird <william.hansen.baird@gmail.com>

[ Upstream commit 04a46c2dbf3b516c96a1d19b72917b56055ad6c1 ]

commit 77a6407c6ab2 ("wifi: rtlwifi: disable ASPM for RTL8723BE with subsystem ID 11ad:1723")
adds code which sets ppsc->support_aspm to false in
_rtl_pci_update_default_setting() in order to disable ASPM.
This does not, however, disable ASPM. Rather, it disables driver
control of ASPM, and blocks calls to rtl_pci_enable_aspm()
and rtl_pci_disable_aspm().

In some cases, the pci device supplied to the probe function has
ASPM enabled. The code would therefore not disable ASPM, as it means to,
but rather just leave it enabled.
This was discovered through testing on a Razer Blade 14 2017.

Implement a new __rtl_pci_disable_aspm(hw) function which does not check
ppsc->support_aspm before disabling and call it from
rtl_pci_disable_aspm().

Then move the code added in the previous commit to rtl_pci_init_aspm() to
allow adding a call to __rtl_pci_disable_aspm(hw).
This makes sure ASPM is disabled while still disabling
driver control of ASPM to block it from being enabled later.

Signed-off-by: William Hansen-Baird <william.hansen.baird@gmail.com>
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260630141553.785769-2-william.hansen.baird@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

Local tree is **7.3.0-rc4**. The original incomplete RTL8723BE ASPM
quirk is in this lineage; this commit is a small, tested hardware-quirk
fix that actually clears ASPM instead of only blocking driver control.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

Step 1.1: PARSE THE SUBJECT LINE

Record: `[wifi: rtlwifi:] [fix] [ASPM disable for RTL8723BE with AER
flooding actually takes effect]`

Step 1.2: PARSE ALL COMMIT MESSAGE TAGS

Record:
- No `Fixes:` tag (v3 cover letter: “Removed misleading Fixes tag from
  patch 1”)
- No `Reported-by:` / `Tested-by:` on this commit (testing is described
  in the body: Razer Blade 14 2017)
- `Acked-by: Ping-Ke Shih <pkshih@realtek.com>` (rtlwifi maintainer)
- `Signed-off-by: William Hansen-Baird` (author)
- `Signed-off-by: Ping-Ke Shih` (maintainer applied to rtw-next)
- `Link: https://patch.msgid.link/20260630141553.785769-2-
  william.hansen.baird@gmail.com`
- No `Cc: stable@vger.kernel.org` (expected for this pipeline; not a
  negative)
- Pipeline `Signed-off-by: Sasha Levin` / `[Upstream commit ...]`
  ignored per instructions

Step 1.3: ANALYZE THE COMMIT BODY TEXT

Record:
- **Bug:** `77a6407c6ab2` set `ppsc->support_aspm = false` intending to
  disable ASPM. That only disables *driver control* of ASPM
  (`rtl_pci_enable_aspm` / `rtl_pci_disable_aspm` return early). If
  firmware/BIOS left ASPM on at probe, it stays on.
- **Symptom:** PCIe AER flooding, heavy lag, poor throughput, occasional
  lock-ups on RTL8723BE (subsystem 11ad:1723; same class of issue on
  other 8723BE cards).
- **Root cause:** Early return `if (!ppsc->support_aspm) return;` in
  `rtl_pci_disable_aspm()` prevents the register write that would clear
  L0s/L1.
- **Fix:** `__rtl_pci_disable_aspm()` skips that check; quirk in
  `rtl_pci_init_aspm()` calls it, then sets `support_aspm = false` so
  ASPM is not re-enabled.
- **Version info:** Fixes incomplete quirk from April 2025; that quirk
  is in this tree (first in v6.16).

Step 1.4: DETECT HIDDEN BUG FIXES

Record: Not hidden. Explicit fix of a broken hardware quirk. Not
cleanup-only.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

Step 2.1: INVENTORY THE CHANGES

Record:
- File: `drivers/net/wireless/realtek/rtlwifi/pci.c` only (`26`
  insertions, `13` deletions)
- Functions: `_rtl_pci_update_default_setting` (quirk removed),
  `rtl_pci_disable_aspm` renamed to `__rtl_pci_disable_aspm` (early
  `support_aspm` check dropped), new thin `rtl_pci_disable_aspm`
  wrapper, `rtl_pci_init_aspm` (quirk moved here +
  `__rtl_pci_disable_aspm()` call)
- Scope: single-file surgical hardware-quirk fix

Step 2.2: UNDERSTAND THE CODE FLOW CHANGE

Record:
- **Before:** `_rtl_pci_update_default_setting()` for 11ad:1723 only
  sets `support_aspm = false`. Later `rtl_pci_disable_aspm()` /
  `rtl_pci_enable_aspm()` no-op. `rtl_pci_init_aspm()` never clears
  LNKCTL ASPM bits. RTL8723BE default `const_pci_aspm = 3` would have
  taken `RT_RF_PS_LEVEL_ALWAYS_ASPM` and tried to *enable* ASPM; the
  quirk blocked that enable but did not clear already-set bits.
- **After:** After defaults, matching 11ad:1723 calls
  `__rtl_pci_disable_aspm()` (writes LNKCTL, clears L0s/L1), then
  `support_aspm = false`. ALWAYS_ASPM then calls
  `rtl_pci_enable_aspm()`, which no-ops. Normal disable path still
  respects `support_aspm`.

Step 2.3: IDENTIFY THE BUG MECHANISM

Record:
- Category: **hardware workaround / logic correctness** (quirk did not
  do what it claimed)
- Mechanism: `support_aspm = false` was treated as “ASPM off” but it
  only gated driver helpers. Probe-time ASPM from firmware stayed
  enabled → AER RxErr flood.

Step 2.4: ASSESS THE FIX QUALITY

Record:
- Obviously correct: disable first, then lock out re-enable.
- Minimal: no API change; other chips still go through the guarded
  wrapper.
- Regression risk low: extra disable only for 11ad:1723; wrapper
  preserves old behavior elsewhere.
- Residual limit (pre-existing): `__rtl_pci_disable_aspm()` still
  returns if bridge vendor is UNKNOWN. Not introduced here.
- `_rtl8723be_enable_aspm_back_door()` still runs in `hw_init` and can
  poke L0s/L1 via DBI; `enable_aspm()` afterward no-ops. Same as the
  original quirk. Author testing reported AER flood stopped. Not a
  reason to reject this patch.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

Step 3.1: BLAME THE CHANGED LINES

Record:
- Incomplete quirk introduced by `77a6407c6ab24` (“wifi: rtlwifi:
  disable ASPM for RTL8723BE with subsystem ID 11ad:1723”), 2025-04-28,
  **in v6.16** (not v6.15).
- That commit had `Cc: stable`, `Fixes: a619d1abe20c` (rtl8723be driver
  add), bugzilla 218127, Tested-by.
- ASPM helpers themselves date to the original rtlwifi PCI code (much
  older).

Step 3.2: FOLLOW THE FIXES: TAG

Record: No `Fixes:` on the candidate (intentionally dropped as
“misleading” in v3). Functionally it completes `77a6407c6ab24`. That
commit **is** an ancestor of this HEAD.

Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES

Record: 3-patch series (v4):
1. **This commit** — actual bugfix (standalone)
2. `676e59a3825c6` — if-statement → `rtl_aspm_quirks` table (refactor)
3. `2b7858891b100` — add 17aa:b736 (Razer Blade 14 2017)

This patch does not need 2 or 3. Later `b3943b3c29714` (2023) removed
*bogus bridge* ASPM writes; this patch only uses the remaining device
LNKCTL path, so it does not restore that danger.

Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS

Record: William Hansen-Baird authored this series plus one unrelated
rtl8723be irq cleanup. Applied and Acked by Ping-Ke Shih (Realtek
rtlwifi maintainer).

Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS

Record: Needs `77a6407c6ab24` (or equivalent 11ad:1723 quirk) and
existing `rtl_pci_disable_aspm` / `pcie_capability_*` helpers. All
present here. Standalone vs the rest of the series.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION

Record:
- `b4 dig -c 04a46c2dbf3b5` → https://patch.msgid.link/20260630141553.78
  5769-2-william.hansen.baird@gmail.com
- v1 2026-06-14, v2 2026-06-16, v3 2026-06-26, v4 2026-06-30 (applied)
- v2: split `__rtl_pci_disable_aspm()` so the check is bypassed only for
  the quirk
- v3: style nits; **removed misleading Fixes tag**; trailing whitespace
- v4: whitespace/`{}` nits; Acked-by carried forward
- No NAKs. Ping-Ke: “looks good to me” + Acked-by; applied all 3 to rtw-
  next
- No reviewer `Cc: stable` in the saved thread
- lore.kernel.org HTTP fetch returned 403; thread recovered via `b4 dig
  -m`

Step 4.2: CHECK WHO REVIEWED THE PATCH

Record: `b4 dig -w`: author, `pkshih@realtek.com`, `linux-
wireless@vger.kernel.org`, `linux-kernel@vger.kernel.org`. Maintainer
reviewed and applied.

Step 4.3: SEARCH FOR THE BUG REPORT

Record: This commit cites in-person testing on a Razer Blade 14 2017.
Underlying AER issue: kernel bugzilla 218127 and lore discussion from
`77a6407c6ab24` (ASUS F441U/X555UQ, 11ad:1723). Real user impact (lags,
lock-ups), not theoretical.

Step 4.4: CHECK FOR RELATED PATCHES AND SERIES

Record: Patch 1 is the mechanism fix and is self-contained. Patches 2–3
are refactor + extra ID; not required for *this* commit.

Step 4.5: CHECK STABLE MAILING LIST HISTORY

Record: **UNVERIFIED** — lore.kernel.org/stable blocked (Anubis). No in-
tree evidence this was rejected for stable.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF

Record: `_rtl_pci_update_default_setting`, `__rtl_pci_disable_aspm` (new
name of old body), `rtl_pci_disable_aspm` (new wrapper),
`rtl_pci_init_aspm`.

Step 5.2: TRACE CALLERS

Record:
- `rtl_pci_init_aspm()` from `rtl_pci_probe()` (device enumeration)
- `rtl_pci_disable_aspm()` from disconnect and `intf_ops->disable_aspm`
- `disable_aspm`/`enable_aspm` from rtl8723be `hw_init`, other rtlwifi
  chips, and `ps.c` power save
- Probe/init path; not a syscall hot path. Userspace-visible via loading
  the driver on affected laptops.

Step 5.3: TRACE CALLEES

Record: `pcie_capability_read_word` /
`_rtl_pci_platform_switch_device_pci_aspm` →
`pcie_capability_clear_and_set_word` on `PCI_EXP_LNKCTL`; optional
clkreq via `_rtl_pci_switch_clk_req`.

Step 5.4: FOLLOW THE CALL CHAIN

Record: PCI probe → `rtl_pci_init_aspm` → quirk disable. Reachable on
affected hardware when `rtl8723be`/`rtlwifi` loads. Not a
sanitizer/syzbot path; real laptop hardware.

Step 5.5: SEARCH FOR SIMILAR PATTERNS

Record: Toshiba 8192SE still only sets `support_aspm = false` without
forcing disable. Same class of incompleteness; this commit does not
touch it. Follow-up series extends the same disable+flag pattern to
17aa:b736 via an ID table.

===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================

Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?

Record: **Yes.** Checkout is **7.3.0-rc4**
(`v7.3-rc4-27-gf0100363d8c37`). `77a6407c6ab24` is an ancestor (present
since v6.16). Parent of the candidate still has the 11ad:1723 block that
only clears `support_aspm`. Driver, PCI ASPM helpers, and
`HARDWARE_TYPE_RTL8723BE` are all here. Bug was **not** introduced after
this tree branched.

Step 6.2: CHECK FOR BACKPORT COMPLICATIONS

Record: Against the parent of `04a46c2dbf3b5`, the patch is a clean
apply on this file. Later 7.3 commits already refactored that quirk into
`rtl_aspm_quirks[]`; that is post-fix evolution, not a missing
prerequisite. No rework needed for this tree’s lineage.

Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE

Record: No alternate fix of the same “flag vs actually clear LNKCTL” bug
besides this series. Original `77a6407c6ab24` is the incomplete version
this completes.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY

Record: `drivers/net/wireless/realtek/rtlwifi` —
**PERIPHERAL/IMPORTANT** for owners of RTL8723BE laptops (ASUS
F441U/X555UQ and similar). Not core mm/fs, but a shipping WiFi adapter
in production machines.

Step 7.2: ASSESS SUBSYSTEM ACTIVITY

Record: Mature driver; still receiving bugfixes. rtlwifi 8723BE is old
but still the in-tree driver for that chip.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

Step 8.1: DETERMINE WHO IS AFFECTED

Record: Driver-specific: RTL8723BE with subsystem **11ad:1723** (ASUSTek
F441U, X555UQ, etc.). Only that ID in *this* commit.

Step 8.2: DETERMINE THE TRIGGER CONDITIONS

Record: Trigger is boot/probe with ASPM already enabled (common). Not a
race. Unprivileged users do not need a special exploit; plugging/using
the laptop is enough. Confirmed on real hardware.

Step 8.3: DETERMINE THE FAILURE MODE SEVERITY

Record: AER correctable-error flood → system-wide slowdown, bad WiFi
throughput, **occasional lock-ups**. Severity **HIGH** (hang/lock-up and
severe lag), not a KASAN crash.

Step 8.4: CALCULATE RISK-BENEFIT RATIO

Record:
- **Benefit:** High for affected laptops; makes an already-stable quirk
  actually work.
- **Risk:** Low (~26/+13 lines, one file, ID-gated, maintainer Acked,
  tested).
- **Ratio:** Strongly favors backport.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

Step 9.1: COMPILE THE EVIDENCE

**FOR:**
- Real hardware bug: AER flood, lag, lock-ups on known laptops
- Existing stable-bound quirk (`77a6407c6ab24`) did not disable ASPM
  when it was already on
- Small, obviously correct, ID-scoped
- Hardware quirk exception
- Maintainer Acked-by and applied; author tested
- Prerequisite incomplete quirk is in this 7.3 tree
- Self-contained as patch 1/3

**AGAINST:**
- Affects a specific PCI subsystem ID, not all users
- No `Fixes:`/`Cc: stable` (expected here; Fixes was dropped as
  misleading)
- DBI backdoor in `hw_init` still exists (pre-existing; testing said AER
  stopped)

**UNRESOLVED:**
- Stable mailing-list history (lore/stable fetch blocked)
- Direct lore.kernel.org HTTP (403); discussion recovered via b4

Step 9.2: APPLY THE STABLE RULES CHECKLIST

1. Obviously correct and tested? **PASS** — maintainer ack; tested on
   affected hardware; v2–v4 review
2. Fixes a real bug that affects users? **PASS** — broken quirk left
   ASPM on; AER/lag/lock-ups
3. Important issue? **PASS** — lock-ups and severe performance, not
   cosmetic
4. Small and contained? **PASS** — one file, +26/-13
5. No new features or APIs? **PASS** — completes an existing quirk
6. Can apply to the local tree? **PASS** — `pci.c` and `77a6407c6ab24`
   are here; context matches

Step 9.3: CHECK FOR EXCEPTION CATEGORIES

Record: **Hardware quirk/workaround** for a broken RTL8723BE/ASPM
combination.

Step 9.4: MAKE YOUR DECISION

This tree has the incomplete 11ad:1723 quirk and the rtlwifi ASPM path.
The change is a small, reviewed fix that actually clears ASPM so those
laptops do not keep flooding AER and locking up. It belongs in this
tree.

Verification:
- [Phase 1] Tags: Acked-by Ping-Ke Shih; Link msgid
  20260630141553.785769-2; no Fixes/Cc:stable; v3 changelog said Fixes
  was removed as misleading
- [Phase 1] Body: `support_aspm=false` blocks disable/enable helpers
  instead of clearing ASPM
- [Phase 2] Diff: pci.c +26/-13; quirk moved to `rtl_pci_init_aspm`;
  `__rtl_pci_disable_aspm` skips the flag check
- [Phase 2] RTL8723BE default `const_pci_aspm = 3` / `aspm_support = 1`
  verified in `rtl8723be/sw.c`
- [Phase 3] `git merge-base --is-ancestor 77a6407c6ab24 HEAD` → yes;
  original first in v6.16, not v6.15
- [Phase 3] `git merge-base --is-ancestor 04a46c2dbf3b5 HEAD` → yes; not
  an ancestor of v7.2; is in v7.3-rc1
- [Phase 3] Series: this commit, then ID-table refactor, then 17aa:b736;
  this patch standalone
- [Phase 4] `b4 dig -c 04a46c2dbf3b5` / `-a` / `-w` / `-m`: v1–v4,
  maintainer Ack, applied to rtw-next; no NAK
- [Phase 4] WebFetch lore 403; stable lore Anubis — UNVERIFIED via HTTP
- [Phase 5] Callers: `rtl_pci_probe` → `rtl_pci_init_aspm`;
  `intf_ops->disable_aspm` from rtl8723be `hw_init` and `ps.c`
- [Phase 6] `make kernelversion` / `git describe HEAD`: 7.3.0-rc4 /
  `v7.3-rc4-27-gf0100363d8c37`; origin torvalds/linux.git
- [Phase 6] Parent of candidate still has 11ad:1723 `support_aspm =
  false` only
- [Phase 8] Failure mode: AER flood, lag, lock-ups — HIGH; change ID-
  gated — low risk
- UNVERIFIED: Whether this was discussed on stable@; whether DBI
  backdoor re-enables L0s/L1 after probe on all machines (testing said
  AER stopped)

The patch is a contained hardware-quirk correctness fix for a bug this
tree actually has.

**YES**

 drivers/net/wireless/realtek/rtlwifi/pci.c | 39 ++++++++++++++--------
 1 file changed, 26 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c
index 8fb9604c3c533..f9f05252b890e 100644
--- a/drivers/net/wireless/realtek/rtlwifi/pci.c
+++ b/drivers/net/wireless/realtek/rtlwifi/pci.c
@@ -156,15 +156,6 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw)
 				PCI_EXP_LNKCTL_ASPM_L1 | PCI_EXP_LNKCTL_CCC))
 		ppsc->support_aspm = false;
 
-	/* RTL8723BE found on some ASUSTek laptops, such as F441U and
-	 * X555UQ with subsystem ID 11ad:1723 are known to output large
-	 * amounts of PCIe AER errors during and after boot up, causing
-	 * heavy lags, poor network throughput, and occasional lock-ups.
-	 */
-	if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8723BE &&
-	    (rtlpci->pdev->subsystem_vendor == 0x11ad &&
-	     rtlpci->pdev->subsystem_device == 0x1723))
-		ppsc->support_aspm = false;
 }
 
 static bool _rtl_pci_platform_switch_device_pci_aspm(
@@ -203,7 +194,7 @@ static void _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u16 value)
 }
 
 /*Disable RTL8192SE ASPM & Disable Pci Bridge ASPM*/
-static void rtl_pci_disable_aspm(struct ieee80211_hw *hw)
+static void __rtl_pci_disable_aspm(struct ieee80211_hw *hw)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
@@ -215,9 +206,6 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw)
 	u16 aspmlevel = 0;
 	u16 tmp_u1b = 0;
 
-	if (!ppsc->support_aspm)
-		return;
-
 	if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) {
 		rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE,
 			"PCI(Bridge) UNKNOWN\n");
@@ -240,6 +228,16 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw)
 	_rtl_pci_platform_switch_device_pci_aspm(hw, linkctrl_reg);
 }
 
+static void rtl_pci_disable_aspm(struct ieee80211_hw *hw)
+{
+	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+	if (!ppsc->support_aspm)
+		return;
+
+	__rtl_pci_disable_aspm(hw);
+}
+
 /*Enable RTL8192SE ASPM & Enable Pci Bridge ASPM for
  *power saving We should follow the sequence to enable
  *RTL8192SE first then enable Pci Bridge ASPM
@@ -330,10 +328,25 @@ static void rtl_pci_parse_configuration(struct pci_dev *pdev,
 
 static void rtl_pci_init_aspm(struct ieee80211_hw *hw)
 {
+	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
 
 	_rtl_pci_update_default_setting(hw);
 
+	/*
+	 * RTL8723BE found on some ASUSTek laptops, such as F441U and
+	 * X555UQ with subsystem ID 11ad:1723 are known to output large
+	 * amounts of PCIe AER errors during and after boot up, causing
+	 * heavy lags, poor network throughput, and occasional lock-ups.
+	 */
+	if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8723BE &&
+	    (rtlpci->pdev->subsystem_vendor == 0x11ad &&
+	     rtlpci->pdev->subsystem_device == 0x1723)) {
+		__rtl_pci_disable_aspm(hw);
+		ppsc->support_aspm = false;
+	}
+
 	if (ppsc->reg_rfps_level & RT_RF_PS_LEVEL_ALWAYS_ASPM) {
 		/*Always enable ASPM & Clock Req. */
 		rtl_pci_enable_aspm(hw);
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7921: fix memory leak when skb_linearize fails in mcu rx event
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (3 preceding siblings ...)
  2026-10-19 13:45 ` [PATCH AUTOSEL 6.18-5.10] wifi: rtlwifi: fix disabling of ASPM for RTL8723BE with AER flooding Sasha Levin
@ 2026-10-19 13:46 ` Sasha Levin
  2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-6.6] wifi: mac80211_hwsim: clear PMSR request state on abort Sasha Levin
                   ` (35 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:46 UTC (permalink / raw)
  To: patches, stable
  Cc: Prashant Rahul, Felix Fietkau, Sasha Levin, lorenzo, ryder.lee,
	matthias.bgg, angelogioacchino.delregno, linux-wireless,
	linux-kernel, linux-arm-kernel, linux-mediatek

From: Prashant Rahul <prashantrahul23@gmail.com>

[ Upstream commit 4361f1660101270611eb5dc39799f620b35f2e4d ]

The ownership of sk_buff skb is passed to mt7921_queue_rx_skb, each
path inside it under the switch case handles cleaning of skb and it
is true for mt7921_mcu_rx_event as well.

mt7921_mcu_rx_event, on a success path, either queues skb via
mt76_mcu_rx_event or cleans it immediately inside
mt7921_mcu_uni_rx_unsolicited_event.

However inside mt7921_mcu_rx_event, if skb_linearize fails, the function
returns immediately and never bothers cleaning skb which leaks skb.

Since skb is fully owned at this point, it is safe to call
dev_kfree_skb which fixes the leak.

Granted, the skb_linearize failure is rare as it can only fail under
heavy memory usage, but at the same time, leaking memory under heavy
memory usage can worsen the OOM condition.

Signed-off-by: Prashant Rahul <prashantrahul23@gmail.com>
Link: https://patch.msgid.link/20260716-mt7921-mem-leak-v1-1-6e9c0ea19f63@gmail.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

# Stable backport analysis: mt7921 MCU RX skb leak

**Tree decided:** `pending-6.6` (6.6.157), SHA `04810563abb71`.
At the start of this evaluation `git describe`/`make kernelversion`
reported **6.6.157**. The working copy later moved to v7.3-rc4; every
presence/absence claim below was rechecked against **`pending-6.6`**,
not that later checkout.

The candidate is mainline `4361f16601012` (`wifi: mt76: mt7921: fix
memory leak when skb_linearize fails in mcu rx event`).

---

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1 — Subject**
Record: **[wifi: mt76: mt7921]** **[fix]** memory leak when
`skb_linearize` fails in MCU RX event.

**Step 1.2 — Tags**
- `Signed-off-by: Prashant Rahul <prashantrahul23@gmail.com>` (author)
- `Link: https://patch.msgid.link/20260716-mt7921-mem-
  leak-v1-1-6e9c0ea19f63@gmail.com`
- `Signed-off-by: Felix Fietkau <nbd@nbd.name>` (mt76 maintainer;
  applied the patch)
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Acked-
  by:`, or `Cc: stable` (absence of Fixes/Cc-stable is expected for this
  review).
Record: Maintainer SOB; msgid shows **v1 patch 1/1** (standalone).

**Step 1.3 — Body**
Record:
- **Bug:** `mt7921_queue_rx_skb` transfers skb ownership into
  `mt7921_mcu_rx_event`. Success paths free or queue the skb. If
  `skb_linearize()` fails, the function returns without freeing.
- **Symptom:** skb leak. Author notes failure is rare (ENOMEM) but
  leaking under memory pressure can worsen OOM.
- **Root cause:** missing `dev_kfree_skb` on the linearize error path.
- **Version info in message:** none.

**Step 1.4 — Hidden bug fix?**
Record: **No disguise.** This is an explicit leak fix, not cleanup-as-
fix.

---

## PHASE 2: DIFF ANALYSIS

**Step 2.1 — Inventory**
Record:
- File: `drivers/net/wireless/mediatek/mt76/mt7921/mcu.c` (**+3 / −1**)
- Function: `mt7921_mcu_rx_event`
- Scope: **single-file surgical fix**

**Step 2.2 — Flow**
Before (pending-6.6 `mcu.c:312-313`):

```
if (skb_linearize(skb))
    return;
```

After:

```
if (skb_linearize(skb)) {
    dev_kfree_skb(skb);
    return;
}
```

Record: **error path only.** Success paths unchanged.

**Step 2.3 — Bug mechanism**
Record: **[resource leak]** On `skb_linearize` failure (`-ENOMEM` for
nonlinear skbs), the still-owned skb is dropped. Caller
`mt7921_queue_rx_skb` does not free after `PKT_TYPE_RX_EVENT`. Other
switch arms in the same caller (`dev_kfree_skb` / `napi_consume_skb`)
and other arms of `mt7921_mcu_rx_event` (`dev_kfree_skb`,
`mt76_mcu_rx_event` queue) already consume the skb.

**Step 2.4 — Fix quality**
Record: **Obviously correct.** Matches established kernel pattern (`if
(skb_linearize(skb)) { dev_kfree_skb(_any)(skb); return; }`). Same free
helper already used in this MCU event path. No API/lock/data-structure
change. Regression risk: **very low** (could only be a double-free if
linearize already freed; it does not — see Phase 5).

---

## PHASE 3: GIT HISTORY

**Step 3.1 — Blame**
Record: Leak introduced by **`f0ff5d3aa64812`** (`mt76: mt7921: make all
event parser reusable between mt7921s and mt7921e`, Sean Wang,
2021-10-19). That commit added `skb_linearize` + early return and never
freed on failure. Present since ~5.16-era; **`git merge-base --is-
ancestor f0ff5d3aa64812 pending-6.6` succeeds.**

**Step 3.2 — Fixes: tag**
Record: **None.** Introducer identified by blame: `f0ff5d3aa64812`,
which **is** in this 6.6 tree.

**Step 3.3 — File history (pending-6.6)**
Recent 6.6 work on this file is CLC firmware validation, not MCU RX. No
competing leak fix. Record: **standalone**; not part of a multi-patch
series.

**Step 3.4 — Author**
Prashant Rahul has **no other commits** in this tree’s mt76 history.
Applied by **Felix Fietkau**, listed maintainer of MEDIATEK MT76 in
`MAINTAINERS`. Record: one-off contributor; **maintainer-applied**.

**Step 3.5 — Dependencies**
The hunk only needs `mt7921_mcu_rx_event` + `skb_linearize` +
`dev_kfree_skb`, all present. Mailing-list patch context matches 6.6
(the extra `MCU_EVENT_RSSI_NOTIFY` in later mainline is **below** the
change). Record: **applies standalone**.

---

## PHASE 4: MAILING LIST / EXTERNAL

**Step 4.1 — Original discussion**
- `b4 dig -c <msgid>` / `b4 mbox`: no match (404).
- lore.kernel.org: **403**.
- Recovered from Openwall and Ratatoskr:
  https://lists.openwall.net/linux-kernel/2026/07/16/1707
  msgid `20260716-mt7921-mem-leak-v1-1-6e9c0ea19f63@gmail.com`
Record: **v1, single patch**, applied as submitted (`4361f16601012`
matches that diff). No v2/v3.

**Step 4.2 — Recipients (`b4 dig -w` unavailable; headers from
Openwall)**
To: Felix Fietkau, Lorenzo Bianconi, Ryder Lee, Shayne Chen, Sean Wang
(mt76 maintainers/reviewers), plus MediaTek ARM contacts. Cc: linux-
wireless, linux-kernel, linux-mediatek, linux-arm-kernel. Record:
**correct maintainer set**.

**Step 4.3 — Bug report**
Record: **No syzbot/bugzilla.** Static ownership analysis; author states
the leak is rare.

**Step 4.4 — Series**
Record: **1/1 standalone.** No sibling mt7925/mt7915 patches required
for this tree (only mt7921 has this `skb_linearize` in pending-6.6).

**Step 4.5 — Stable list**
Search for this subject on lore stable returned unrelated hits. Record:
**no prior stable NAK found** (lore 403 limited this).

---

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1 — Functions**
Record: `mt7921_mcu_rx_event` only.

**Step 5.2 — Callers**
`mt7921_queue_rx_skb()` (`mac.c`) `case PKT_TYPE_RX_EVENT:` calls it and
does **not** free afterwards.

That `rx_skb` hook is registered for **PCIe, USB, and SDIO**:
- `mt7921/pci.c`, `usb.c`, `sdio.c` → `.rx_skb = mt7921_queue_rx_skb`
- Invoked from `mt76_dma_rx_process` (NAPI), `mt76u` USB RX,
  `mt76s_process_rx_queue` (SDIO)

Record: **hot RX path** for MT7921E/S/U.

**Step 5.3 — Callees**
`skb_linearize` → `__skb_linearize` → `__pskb_pull_tail`; returns
`-ENOMEM` on failure and **does not free** the skb
(`include/linux/skbuff.h`: “If there is no free memory -ENOMEM is
returned”). Success continues to `mt7921_mcu_uni_rx_unsolicited_event` /
`mt76_mcu_rx_event` / `mt7921_mcu_rx_unsolicited_event`.

**Step 5.4 — Reachability**
Nonlinear MCU events are real:
- SDIO `mt76s_build_rx_skb` uses `skb_add_rx_frag` when payload >
  `MT_SKB_HEAD_LEN` — this is **why** `f0ff5d3aa64812` added linearize
  (“paged fragment skb for the SDIO device”).
- USB `mt76u_build_rx_skb` same pattern.
- DMA `mt76_add_fragment` builds fraglists for multi-buffer RX.

Record: reachable from normal firmware MCU events; unprivileged users
can generate MCU traffic by using WiFi. Failure needs **ENOMEM during
linearize**.

**Step 5.5 — Similar patterns**
In pending-6.6, `skb_linearize` appears **only here** under mt76. No
duplicate site left unfixed in this tree.

---

## PHASE 6: LOCAL TREE (pending-6.6 / 6.6.157)

**Step 6.1 — Buggy code present?**
Record: **Yes.**
`pending-6.6:drivers/net/wireless/mediatek/mt76/mt7921/mcu.c:312-313`:

```
if (skb_linearize(skb))
    return;
```

`git merge-base --is-ancestor 4361f16601012 pending-6.6` → **false**
(fix not here).
`git merge-base --is-ancestor f0ff5d3aa64812 pending-6.6` → **true**
(bug intro is here).
Bug age: **2021**, well before 6.6.

**Step 6.2 — Backport difficulty**
Submitted hunk is 4 lines around `skb_linearize` with context that
matches 6.6 (`struct mt76_connac2_mcu_rxd *rxd` then the if).
`MCU_EVENT_RSSI_NOTIFY` is later mainline-only context **below** the
edit. Record: **clean apply / trivial**.

**Step 6.3 — Related fixes already here?**
`git log --grep=skb_linearize` on mt76 in this tree: **empty**. No
alternate fix. Record: **none**.

---

## PHASE 7: SUBSYSTEM CONTEXT

**Step 7.1**
Record: **wifi / mt76 / mt7921**. Criticality: **IMPORTANT** — MT7921E
is a common laptop WiFi 6 adapter (PCIe); USB/SDIO variants exist
(`MT7921E/S/U` in Kconfig). Not core mm/net, not staging.

**Step 7.2**
Record: Mature driver (MCU support from `1c099ab44727c8`, 2021). 6.6
still receives mt76 bugfixes (CLC, etc.).

---

## PHASE 8: IMPACT AND RISK

**Step 8.1 — Who is affected**
Record: **driver-specific**, users with MediaTek MT7921 (very common on
laptops). Config: `CONFIG_MT7921E/S/U`.

**Step 8.2 — Trigger**
Record: Firmware MCU RX event whose skb is nonlinear, **and**
`skb_linearize` fails (GFP/ENOMEM). Unprivileged WiFi use can generate
events; the failure itself is **uncommon**. SDIO long events are the
originally cited nonlinear case; USB/DMA can also fragment.

**Step 8.3 — Failure mode**
Record: **skb leak under memory pressure**, which can deepen OOM. Not a
panic/UAF. Severity: **MEDIUM–HIGH** (hot-path leak, not a one-time
probe leak).

**Step 8.4 — Risk/benefit**
- Benefit: **medium** — stops a real leak on a widely shipped chip; most
  valuable when the system is already under memory pressure.
- Risk: **very low** — 3 lines, error path, same free as sibling paths.
- Ratio: **favor backport**.

---

## PHASE 9: SYNTHESIS

**Step 9.1 — Evidence**

**For:**
- Real leak with verified ownership (caller does not free).
- Code and introducer are in 6.6.157; fix is not.
- Tiny, obviously correct, maintainer-applied.
- MT7921 is production hardware, not staging.
- Leak on an RX path under OOM is a stability issue, not a style
  cleanup.

**Against:**
- Trigger is rare (`skb_linearize` ENOMEM).
- No crash/syzbot/CVE.
- No explicit `Cc: stable` (not a negative per the review rules).

**Unresolved:** Full lore thread (403/404); no reviewer comments beyond
maintainer merge. Does not change the technical verdict.

**Step 9.2 — Stable rules**
1. Obviously correct and tested — **PASS** (3-line ownership fix; in
   mainline via Felix).
2. Real bug affecting users — **PASS** (skb leak on MT7921 MCU RX).
3. Important (crash/security/corruption/deadlock) — **PASS** as an RX-
   path leak that can worsen OOM; not a panic, but in the leak class
   stable regularly takes.
4. Small and contained — **PASS** (4 lines, one function).
5. No new features/APIs — **PASS**.
6. Can apply to this tree — **PASS** (hunk matches 6.6).

**Step 9.3 — Exceptions**
Record: none needed (not an ID/quirk/DT/build/doc exception). Ordinary
small leak fix.

**Step 9.4 — Decision**
Backport to **this** 6.6.157 tree. The bug exists here, the fix is
surgical, and regression risk is negligible.

---

## What the commit solves for stable users

On MT7921, firmware MCU events are handed to `mt7921_mcu_rx_event` with
full skb ownership. Nonlinear events (especially SDIO, also USB/DMA
fragments) are linearized first. If that allocation fails, 6.6 returns
and leaks the skb. Under memory pressure that leak makes OOM worse.
Adding `dev_kfree_skb(skb)` on that path closes the leak without
changing success behavior.

## Risk vs benefit

Benefit is a real leak fix on a common WiFi chip; risk is a three-line
error-path free that matches existing code in the same function.

## Concerns

None material: no prerequisites, no API change, no locking, expected
clean apply. Trigger rarity is the only weak point and is not enough to
reject a contained leak fix.

---

## Verification

- **[Phase 1]** Parsed tags: author SOB, Link msgid, Felix Fietkau SOB;
  no Fixes/Reported-by/Cc-stable.
- **[Phase 2]** Diff: +3/−1 in `mt7921_mcu_rx_event`; adds
  `dev_kfree_skb` on `skb_linearize` failure.
- **[Phase 3]** `git blame` on pending-6.6: leak from `f0ff5d3aa64812`
  (2021-10-19); `git merge-base --is-ancestor f0ff5d3aa64812
  pending-6.6` true.
- **[Phase 3]** `git show f0ff5d3aa64812`: added `if
  (skb_linearize(skb)) return;` with no free.
- **[Phase 3]** `git log --author=Prashant Rahul`: no other mt76 commits
  in this history.
- **[Phase 4]** Openwall/Ratatoskr: v1 1/1, same diff as
  `4361f16601012`; mt76 maintainers on To:.
- **[Phase 4]** `b4 mbox` msgid: 404; lore.kernel.org: 403.
  **UNVERIFIED:** full review replies / explicit stable nomination.
- **[Phase 5]** Callers: `mt7921_queue_rx_skb` (no free on
  `PKT_TYPE_RX_EVENT`); hooked from pci/usb/sdio `.rx_skb`.
- **[Phase 5]** `skb_linearize` documented to return `-ENOMEM` and not
  free; USB/SDIO `skb_add_rx_frag` makes nonlinear skbs.
- **[Phase 6]** `git describe` at start: `p-6.6-3-g04810563abb71`, `make
  kernelversion` 6.6.157.
- **[Phase 6]** `git grep` on `pending-6.6`: leak at `mcu.c:312-313`.
- **[Phase 6]** `git merge-base --is-ancestor 4361f16601012 pending-6.6`
  false.
- **[Phase 8]** Failure mode: skb leak under ENOMEM on MCU RX; severity
  MEDIUM–HIGH.
- **UNVERIFIED:** complete lore thread text after 403.

The fix is small, matches stable leak-fix practice, and the buggy code
is in this 6.6 tree.

**YES**

 drivers/net/wireless/mediatek/mt76/mt7921/mcu.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
index 8c8b35cba856c..f63ef02542387 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
@@ -354,8 +354,10 @@ void mt7921_mcu_rx_event(struct mt792x_dev *dev, struct sk_buff *skb)
 {
 	struct mt76_connac2_mcu_rxd *rxd;
 
-	if (skb_linearize(skb))
+	if (skb_linearize(skb)) {
+		dev_kfree_skb(skb);
 		return;
+	}
 
 	rxd = (struct mt76_connac2_mcu_rxd *)skb->data;
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18-6.6] wifi: mac80211_hwsim: clear PMSR request state on abort
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (4 preceding siblings ...)
  2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7921: fix memory leak when skb_linearize fails in mcu rx event Sasha Levin
@ 2026-10-19 13:46 ` Sasha Levin
  2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.15] wifi: mt76: set the EOSP bit in the QoS header of the last released frame Sasha Levin
                   ` (34 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:46 UTC (permalink / raw)
  To: patches, stable
  Cc: Zhao Li, Johannes Berg, Sasha Levin, johannes, linux-wireless,
	linux-kernel

From: Zhao Li <enderaoelyther@gmail.com>

[ Upstream commit 37a77bd1395e8261d1760ae39c7f5eb637300550 ]

mac80211_hwsim saves the in-flight cfg80211 PMSR request and its wdev
in data->pmsr_request / data->pmsr_request_wdev when a measurement
starts, and clears them only when it reports completion.

mac80211_hwsim_abort_pmsr() never cleared that saved state. cfg80211
owns the request and frees it once the abort callback returns
(cfg80211_pmsr_process_abort() calls rdev_abort_pmsr() then
kfree(req)), so after an abort data->pmsr_request dangles. A later
hwsim PMSR report then dereferences the freed request in
hwsim_pmsr_report_nl() and completes it; a use-after-free.

Clear data->pmsr_request and data->pmsr_request_wdev once the abort
matches the active request. Move the wmediumd/virtio notification check
below the clear so the saved state is dropped even when no notification
is sent.

Assisted-by: Codex:gpt-5
Assisted-by: Claude:opus-4.8
Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
Link: https://patch.msgid.link/20260708195911.84365-2-enderaoelyther@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## Phase 1: Commit message forensics

**Step 1.1: Subject line**
Record: **[wifi: mac80211_hwsim]** **[clear]** in-flight PMSR request
pointers when abort matches, so cfg80211’s free cannot leave a dangling
`data->pmsr_request`.

**Step 1.2: Tags**
Committed message (pipeline-stripped):
- Link: `https://patch.msgid.link/20260708195911.84365-2-
  enderaoelyther@gmail.com`
- Assisted-by: Codex:gpt-5, Claude:opus-4.8
- Signed-off-by: Zhao Li; Johannes Berg
- No Fixes:/Cc: stable/Reported-by in the committed text (expected for
  this pipeline)

Original mailing-list submission (from the saved mbox, not used as
circular “already selected” evidence):
- Fixes: `5530c04c87c5` (“mac80211_hwsim: add PMSR request support via
  virtio”)
- Cc: `stable@vger.kernel.org`
- Cover letter: `[PATCH 0/8] wifi: fix PMSR lifetime and frame
  validation issues`

**Step 1.3: Body**
Record:
- **Bug:** `mac80211_hwsim_abort_pmsr()` never NULLs
  `data->pmsr_request` / `data->pmsr_request_wdev`. cfg80211 owns the
  request and `kfree(req)` after `rdev_abort_pmsr()`.
- **Symptom:** later `hwsim_pmsr_report_nl()` uses the freed request →
  use-after-free. Abort also leaves a non-NULL pointer so a new start
  can see `-EBUSY` forever.
- **Root cause:** abort notifies wmediumd/virtio but does not drop saved
  state; an early `return` when wmediumd/virtio is absent skips even the
  mutex.
- **Version:** not stated in the message. Introduction is v6.4-rc1
  (verified in Phase 3).

**Step 1.4: Hidden bug fix?**
Record: **No.** This is an explicit UAF fix, not cleanup disguised as a
fix.

---

## Phase 2: Diff analysis

**Step 2.1: Inventory**
Record:
- File: `drivers/net/wireless/virtual/mac80211_hwsim_main.c` (+7 / −3)
- Function: `mac80211_hwsim_abort_pmsr()` only
- Scope: single-file surgical fix

**Step 2.2: Flow change**
Record:
- **Before:** read `data->wmediumd`; if no wmediumd and no virtio,
  **return unlocked** with saved pointers intact. If notification is
  sent, still never NULL the pointers.
- **After:** take the mutex, match `data->pmsr_request == request`, then
  set both pointers to NULL **before** the notification check. Missing
  wmediumd/virtio is `goto out` (unlock), not an early return.

**Step 2.3: Bug mechanism**
Record: **Use-after-free / dangling pointer** (also a lifetime/refcount-
style leak of a cfg80211-owned object). cfg80211 frees the request;
hwsim keeps the pointer; `hwsim_pmsr_report_nl()` later calls
`cfg80211_pmsr_report()` / `cfg80211_pmsr_complete()` on it.

**Step 2.4: Fix quality**
Record: Obviously correct: abort that matches the in-flight request must
drop the saved pointers because cfg80211 will free the object. Mutex
already covers start/abort/report. Regression risk is low: a late report
after abort now hits `if (!data->pmsr_request) return -EINVAL`, which is
the intended post-abort behavior. No API/data-structure change.

---

## Phase 3: Git history

**Step 3.1: Blame**
Record: Pre-fix abort body is entirely from **`8ba1da95053e0`**
(“mac80211_hwsim: add PMSR abort support via virtio”, Jaewan Kim,
2023-03-22). Pointers are stored in **`5530c04c87c59`** (start/request
support, same day). First appears in **v6.4-rc1**. Present for a long
time in this lineage.

**Step 3.2: Fixes: target**
Record: Original Fixes: `5530c04c87c5` is an ancestor of HEAD (`git
merge-base --is-ancestor` exit 0). Closest actual miss is abort itself
(`8ba1da95053e0`), also an ancestor. Related: `2bef4d1fb8b34` (NULL
deref in `hwsim_pmsr_report_nl`, 2023) — different bug, already here.

**Step 3.3: File history**
Record: Neighbor `aeea930c7a878` (“authenticate PMSR report senders”) is
series patch 2/8, parent of this commit, **independent** (touches
`hwsim_pmsr_report_nl()`, not abort). File split `340f2ab83a5c9` / move
`f79cbc77abde2` already in this tree. No extra prerequisite for the
abort clear.

**Step 3.4: Author**
Record: Zhao Li is not the wireless maintainer. Same-day sibling is the
report-sender auth patch. Maintainer **Johannes Berg** applied this
commit.

**Step 3.5: Dependencies**
Record: Standalone. Uses existing `data->pmsr_request`, `data->mutex`,
`hwsim_virtio_enabled`. Series 1/8; does not need 2/8–8/8. Can apply
without `aeea930c7a878`.

---

## Phase 4: Mailing list

**Step 4.1: Original discussion**
Record:
- Lore URL: https://patch.msgid.link/20260708195911.84365-2-
  enderaoelyther@gmail.com
- Cover: https://patch.msgid.link/20260708195911.84365-1-
  enderaoelyther@gmail.com
- Series: **v1 only** as this patch (`b4 dig -a` “v2” is a different
  nl80211 color-change patch; false match)
- Johannes on the cover (2026-07-21): will take the two hwsim patches
  for **wireless-next**; **“I don’t think hwsim is all that relevant in
  deployed systems.”** Not a NAK of the UAF. He did apply this patch the
  same day.
- No reviewer asked for changes to this hunk. Other series patches
  (probe-resp, S1G TWT) were called out as LLM-pattern issues; **this
  patch was not**.

**Step 4.2: Recipients (`b4 dig -w`)**
Record: linux-wireless, Johannes Berg, Jaewan Kim (original PMSR
author), Intel/Qualcomm/Marvell names, **stable@vger.kernel.org**. Right
lists for a hwsim UAF.

**Step 4.3: Bug report**
Record: No syzbot/bugzilla. Found by review. Cover letter: KASAN hwsim
boot; after the fix, a stale `REPORT_PMSR` got `-EINVAL` with no KASAN
splat. Author-tested, not an external user report.

**Step 4.4: Series**
Record: 8 patches, mixed subsystems. This one is self-contained. 2/8
(sender auth) is a separate spoofing fix, not required to stop the abort
UAF (it only narrows who can fire `hwsim_pmsr_report_nl()`).

**Step 4.5: Stable list**
Record: lore.kernel.org returned HTTP 403 via WebFetch. Original
submission **did** Cc stable. Johannes’s “not relevant in deployed
systems” is the only maintainer comment on hwsim priority. **No NAK and
no “do not backport” found in the mbox.**

---

## Phase 5: Semantic / call chain

**Step 5.1: Functions**
Record: `mac80211_hwsim_abort_pmsr()` only. Consumers of the pointers:
`mac80211_hwsim_start_pmsr()`, `hwsim_pmsr_report_nl()`.

**Step 5.2: Callers**
Record:
- `ieee80211_ops.abort_pmsr` → `drv_abort_pmsr()` →
  `ieee80211_abort_pmsr()` → `rdev_abort_pmsr()` →
  `cfg80211_pmsr_process_abort()` which **then `kfree(req)`**.
- Abort work: `cfg80211_pmsr_free_wk` / `cfg80211_pmsr_wdev_down`.
- Socket teardown: `nl80211` URELEASE → `cfg80211_release_pmsr()`.

**Step 5.3: Callees**
Record: mutex, `genlmsg_new`, `mac80211_hwsim_send_pmsr_request`,
virtio/wmediumd unicast. After the fix, notification is best-effort;
**state drop is not**.

**Step 5.4: Reachability**
Record: Yes, from userspace on this tree:
1. `NL80211_CMD_PEER_MEASUREMENT_START` (`GENL_UNS_ADMIN_PERM`) with
   PMSR capa on an hwsim radio (wmediumd or virtio).
2. Close the nl80211 socket or take the wdev down → abort → cfg80211
   frees `req`.
3. `HWSIM_CMD_REPORT_PMSR` has **no** `GENL_UNS_ADMIN_PERM` (verified at
   the genl op). Combined with a leftover pointer, that is the UAF.
4. Extra path: wmediumd URELEASE sets `data->wmediumd = 0`
   (`hwsim_register_wmediumd(net, 0)`). Old abort **returned
   immediately** and never cleared.

**Step 5.5: Similar patterns**
Record: Same lifetime bug described for iwlwifi MLD in series 3/8
(`mld->ftm_initiator.req` left dangling). hwsim abort was the incomplete
half of start-saves/complete-clears.

---

## Phase 6: This checkout

**Step 6.1: Local tree and buggy code**
Record:
- `git describe HEAD`: **v7.3-rc4-27-gf0100363d8c37**
- `make kernelversion`: **7.3.0-rc4**
- Buggy abort (save on start, clear only in `hwsim_pmsr_report_nl()`)
  exists here; pre-image at `37a77bd1395e8^` still has the early return
  and no NULL. Introduced v6.4-rc1; **not after this branch point**.

**Step 6.2: Backport difficulty**
Record: **Clean apply** on this tree’s `mac80211_hwsim_main.c`. Function
and fields (`pmsr_request`, `pmsr_request_wdev`, `mutex`) are present.

**Step 6.3: Related fixes already here**
Record: No earlier abort-clear. `2bef4d1fb8b34` is a different NULL
check. `aeea930c7a878` is sender auth, not this UAF.

---

## Phase 7: Subsystem

**Step 7.1**
Record: **drivers/net/wireless/virtual** (mac80211_hwsim). Kconfig:
“Simulated radio testing tool… not needed for normal wireless LAN
usage.” Criticality: **PERIPHERAL** as hardware, but **IMPORTANT** as a
virtual/test driver shipped as a module and used by
CI/syzkaller/wmediumd.

**Step 7.2**
Record: File is actively developed (NAN, virtio, many 2026 hwsim fixes).
PMSR abort itself has been unchanged since 2023 — a long-standing hole,
not churn from last month.

---

## Phase 8: Impact and risk

**Step 8.1: Who**
Record: Users with `CONFIG_MAC80211_HWSIM` who start PMSR
(wmediumd/virtio) and abort. Not general Wi-Fi laptops. Distros often
ship the module; Android Cuttlefish / mac80211 selftests use it.

**Step 8.2: Trigger**
Record: Start PMSR, then abort (socket close / iface down), then a
report **or** wmediumd disconnect so abort’s old early-return fires.
Needs CAP_NET_ADMIN to **start**; report genl op is unrestricted.
Timing-dependent if wmediumd still reports after abort;
**deterministic** dangling pointer after abort regardless.

**Step 8.3: Failure mode**
Record: **Use-after-free** in `cfg80211_pmsr_report` /
`cfg80211_pmsr_complete` (`req->cookie`, `req->nl_portid`, …). Severity:
**HIGH** (oops/KASAN; possible memory corruption). Secondary: stuck
`-EBUSY` on later PMSR.

**Step 8.4: Risk vs benefit**
Record: Benefit **high** for anyone hitting hwsim PMSR abort (crash).
Risk **very low**: ~10-line pointer clear under an existing mutex. Ratio
favors taking it on this tree.

---

## Phase 9: Synthesis

**Step 9.1: Evidence**
For:
- Real UAF with a traced cfg80211 `kfree(req)` after `rdev_abort_pmsr()`
- Small, obviously correct, mutex-protected
- Bug in this tree since v6.4-rc1
- Standalone; no new API
- Author tested abort-then-report under KASAN
- Wireless maintainer applied it
- Original submission had Fixes: + Cc: stable

Against:
- Test/simulator driver; Johannes said hwsim is not very relevant on
  deployed systems
- No syzbot/external user report
- Start path needs admin + wmediumd/virtio
- LLM-assisted series (maintainer criticized *other* patches, not this
  one)

Unresolved: stable@ lore search (HTTP 403). Does not change the local-
tree technical picture.

**Step 9.2: Stable rules**
1. Obviously correct and tested? **PASS** (clear-on-abort; KASAN boot
   described)
2. Real user-visible bug? **PASS** (UAF / oops; also stuck PMSR)
3. Important (crash/security/corruption/deadlock)? **PASS** (UAF → HIGH)
4. Small and contained? **PASS** (+7/−3, one function)
5. No new features/APIs? **PASS**
6. Applies to this tree? **PASS** (code present; clean)

**Step 9.3: Exceptions**
Record: None (not a device ID/quirk/DT/build/doc exception). Qualifies
as a normal memory-safety fix.

**Step 9.4: Decision**
This checkout is **v7.3-rc4**. The buggy hwsim PMSR abort path is here.
The patch is a small UAF fix with no prerequisites. Maintainer
skepticism about hwsim on production APs does not make a use-after-free
in this tree’s driver “not a bug.” It should be taken.

---

## What the commit solves for this tree

`mac80211_hwsim` stores cfg80211’s PMSR request in `data->pmsr_request`.
cfg80211 frees that object when abort finishes. This tree’s abort
callback never dropped the pointer (and skipped all cleanup if wmediumd
had already exited). A later `HWSIM_CMD_REPORT_PMSR` dereferences freed
memory. Clearing the two pointers under `data->mutex` when abort matches
is the whole fix.

## Risk vs benefit

Benefit: prevent a KASAN/UAF oops on PMSR abort and allow a later start.
Risk: negligible; notification becomes best-effort after the pointer is
already gone, which is what cfg80211 requires.

## Concerns

None that block this tree: no missing helpers, no series dependency,
file is already `mac80211_hwsim_main.c`. Johannes’s “deployed systems”
comment is priority, not a correctness NAK.

---

## Verification

- **[Phase 1]** Parsed committed tags: Link msgid
  `20260708195911.84365-2`; SOBs Zhao Li + Johannes Berg; no Fixes in
  committed text
- **[Phase 1]** mbox of original mail: Fixes `5530c04c87c5`, Cc: stable
- **[Phase 2]** `git show 37a77bd1395e8`: +7/−3 in
  `mac80211_hwsim_abort_pmsr` only
- **[Phase 2]** Read current abort (lines 3848–3911) and
  `hwsim_pmsr_report_nl` (4213–4277): report uses `data->pmsr_request`
  then NULLs it
- **[Phase 2]** Read `cfg80211_pmsr_process_abort()`:
  `rdev_abort_pmsr()` then `kfree(req)`
- **[Phase 3]** `git blame` on pre-image: abort from `8ba1da95053e0`;
  `git describe --contains` → v6.4-rc1
- **[Phase 3]** `git merge-base --is-ancestor 5530c04c87c59 HEAD` → 0;
  same for `8ba1da95053e0`
- **[Phase 3]** `git log --oneline --grep=pmsr --
  drivers/net/wireless/virtual/`: series neighbor `aeea930c7a878`
  independent
- **[Phase 3]** `git log --oneline -S mac80211_hwsim_abort_pmsr --
  drivers/net/wireless/virtual/`: only intro + this fix
- **[Phase 4]** `b4 dig -c 37a77bd1395e8`: patch.msgid.link `…84365-2`
- **[Phase 4]** `b4 dig -a`: v1 of this patch; “v2” is unrelated nl80211
  color-change
- **[Phase 4]** `b4 dig -w`: linux-wireless, Johannes, Jaewan Kim,
  stable@
- **[Phase 4]** mbox msg from Johannes: wireless-next; hwsim “not all
  that relevant in deployed systems”; no NAK of this diff
- **[Phase 4]** WebFetch lore/stable: HTTP 403 — UNVERIFIED whether it
  was discussed on stable@ beyond original Cc
- **[Phase 5]** Grep: abort wired in `ieee80211_ops`; nl80211 URELEASE
  calls `cfg80211_release_pmsr`
- **[Phase 5]** `HWSIM_CMD_REPORT_PMSR` op has no `GENL_UNS_ADMIN_PERM`;
  `NL80211_CMD_PEER_MEASUREMENT_START` has it
- **[Phase 5]** wmediumd URELEASE zeros portid via
  `hwsim_register_wmediumd(net, 0)`
- **[Phase 6]** `git describe HEAD` v7.3-rc4-27-gf0100363d8c37; Makefile
  7.3.0-rc4
- **[Phase 6]** `git merge-base --is-ancestor 37a77bd1395e8 HEAD` → 0
  (present; judged on merit, not as “already selected”)
- **[Phase 6]** Pre-fix abort still has early return without NULL (shown
  at `37a77bd1395e8^`)
- **[Phase 7]** Kconfig: test tool, module `mac80211_hwsim`
- **[Phase 8]** `cfg80211_pmsr_complete()` derefs `req->cookie` /
  `req->nl_portid` — UAF if abort already freed `req`
- **UNVERIFIED:** How many distro .configs enable `MAC80211_HWSIM` — not
  used to drive the verdict; UAF is in-tree regardless

The fix is small, surgical, and matches stable rules for a real use-
after-free in code this tree has had since v6.4.

**YES**

 drivers/net/wireless/virtual/mac80211_hwsim.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c
index 484198766efda..89794c724858c 100644
--- a/drivers/net/wireless/virtual/mac80211_hwsim.c
+++ b/drivers/net/wireless/virtual/mac80211_hwsim.c
@@ -3654,9 +3654,6 @@ static void mac80211_hwsim_abort_pmsr(struct ieee80211_hw *hw,
 	int err = 0;
 
 	data = hw->priv;
-	_portid = READ_ONCE(data->wmediumd);
-	if (!_portid && !hwsim_virtio_enabled)
-		return;
 
 	mutex_lock(&data->mutex);
 
@@ -3665,6 +3662,13 @@ static void mac80211_hwsim_abort_pmsr(struct ieee80211_hw *hw,
 		goto out;
 	}
 
+	data->pmsr_request = NULL;
+	data->pmsr_request_wdev = NULL;
+
+	_portid = READ_ONCE(data->wmediumd);
+	if (!_portid && !hwsim_virtio_enabled)
+		goto out;
+
 	skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
 	if (!skb) {
 		err = -ENOMEM;
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18-5.15] wifi: mt76: set the EOSP bit in the QoS header of the last released frame
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (5 preceding siblings ...)
  2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-6.6] wifi: mac80211_hwsim: clear PMSR request state on abort Sasha Levin
@ 2026-10-19 13:46 ` Sasha Levin
  2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.10] wifi: rtlwifi: rtl8723be: Remove unnecessary irq save/restore in hw_init() Sasha Levin
                   ` (33 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:46 UTC (permalink / raw)
  To: patches, stable
  Cc: Felix Fietkau, Sasha Levin, lorenzo, ryder.lee, matthias.bgg,
	angelogioacchino.delregno, linux-wireless, linux-kernel,
	linux-arm-kernel, linux-mediatek

From: Felix Fietkau <nbd@nbd.name>

[ Upstream commit 0b8d2524716099ea4743fa65bc364f94b3106a31 ]

When the driver implements .release_buffered_frames, mac80211 leaves the
U-APSD signalling entirely to the driver: "In this case it is also
responsible for setting the EOSP flag in the QoS header of the frames"
(include/net/mac80211.h). Only IEEE80211_TX_STATUS_EOSP was being set,
which merely ends the service period inside mac80211, so on air the
service period was never terminated. Clients that wait for EOSP before
going back to doze keep the SP open and stop triggering, which stalls all
downlink traffic for that station.

Set the wire EOSP bit on the last frame of a U-APSD service period.
EOSP has no meaning for a PS-Poll response, so pass the release reason
down and leave those frames alone.

Link: https://patch.msgid.link/20260801145334.1166751-4-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

This is a real U-APSD protocol bug in mt76 that already exists in this
5.15.221 tree. The fix is small, applies here, and is independent of the
rest of the series.

## Phase 1: Commit message forensics

**Step 1.1 — subject**
Record: `[wifi: mt76:]` `[set]` set the EOSP bit in the QoS header of
the last released frame. “Set” here is a protocol-correctness fix, not a
feature add.

**Step 1.2 — tags**
Record:
- `Link: https://patch.msgid.link/20260801145334.1166751-4-nbd@nbd.name`
  (linux-wireless, series 04/10)
- `Signed-off-by: Felix Fietkau <nbd@nbd.name>` (mt76 maintainer; Sasha
  Levin SOB ignored per instructions)
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Cc:
  stable` (absence is expected)

Mainline SHA (from `origin/master`, path-limited log):
`0b8d2524716099ea4743fa65bc364f94b3106a31`. First containing tag:
`v7.3-rc1`. Not an ancestor of this HEAD.

**Step 1.3 — body**
Record:
- **Bug:** `.release_buffered_frames` means mac80211 does not set the
  on-air EOSP bit; the driver must. mt76 only set
  `IEEE80211_TX_STATUS_EOSP` (ends the SP inside mac80211).
- **Symptom:** U-APSD clients that wait for EOSP never see it, keep the
  service period open, stop triggering, **all downlink for that STA
  stalls**.
- **Root cause:** missing `IEEE80211_QOS_CTL_EOSP` on the last QoS frame
  of a U-APSD SP. PS-Poll must not get EOSP.
- **Version info:** none in the message. Buggy code dates to 2017.

**Step 1.4 — hidden fix?**
Record: Not hidden. Explicit protocol/connectivity fix.

## Phase 2: Diff analysis

**Step 2.1 — inventory**
Record:
- File: `drivers/net/wireless/mediatek/mt76/tx.c` (`+12 / -4`)
- Functions: `mt76_queue_ps_skb`, `mt76_release_buffered_frames`
- Scope: single-file surgical change. `mt76_queue_ps_skb` is static;
  exported `mt76_release_buffered_frames` signature already has
  `reason`.

**Step 2.2 — flow**
Record:
- Before: last PS-release frame gets `IEEE80211_TX_STATUS_EOSP |
  IEEE80211_TX_CTL_REQ_TX_STATUS` and More Data cleared. QoS Control on
  the wire is untouched.
- After: same flags, plus if `reason == IEEE80211_FRAME_RELEASE_UAPSD`
  and the frame is QoS data, OR `IEEE80211_QOS_CTL_EOSP` into the QoS
  control field. `reason` is passed through both call sites.
- Path: U-APSD/PS-Poll release via `.release_buffered_frames`, not the
  normal TX burst path.

**Step 2.3 — bug mechanism**
Record: **Logic / protocol correctness.** mac80211’s own release path
(`net/mac80211/sta_info.c`) does `*qoshdr |= IEEE80211_QOS_CTL_EOSP` for
U-APSD. Drivers that implement `.release_buffered_frames` must do the
same (`include/net/mac80211.h`). mt76 did not.

**Step 2.4 — quality**
Record: Obviously correct and aligned with mac80211. Guards match the
docs (U-APSD only; QoS data only). skb is exclusively owned after
`ieee80211_tx_dequeue`. Header at `skb->data` matches existing
`mt76_skb_set_moredata()`. Regression risk is low: PS-Poll unchanged;
non-QoS last frames still lack wire EOSP (mac80211 already assumes
drivers mostly buffer QoS-data, or add a QoS-Null themselves). Pre-
existing unused `more_data` parameter is not changed.

## Phase 3: Git history

**Step 3.1 — blame**
Record: `mt76_queue_ps_skb` / `mt76_release_buffered_frames` introduced
in `17f1de56df0512` (“mt76: add common code…”, 2017-12-07,
**v4.16-rc1**). `IEEE80211_TX_STATUS_EOSP` added in `7267a7965dd7b`
(2018). Present for the entire 5.15 lifetime.

**Step 3.2 — Fixes: tag**
Record: None. Introducer is `17f1de56df0512`, which **is** in this tree.

**Step 3.3 — related file history**
Record: Recent 5.15 `tx.c` work is unrelated (locking, UAF, queue id).
This tree already has U-APSD AP support: `b807b368c4f9b` (mt76 AP
U-APSD), `4bf04d33f5b7e` (mt7915). No earlier EOSP-on-wire fix.

**Step 3.4 — author**
Record: Felix Fietkau is listed in `MAINTAINERS` as mt76 maintainer.
Sibling series patch 05 (`697badc27a9b3`, mt7603 U-APSD termination) is
a separate chip-specific fix, not a prerequisite.

**Step 3.5 — prerequisites**
Record: Series is **01–10**, but 04 does **not** depend on 01–03. Patch
01 (`a547b414bf7ea`) changes `mt76_txq_send_burst` / HW TIM buffering
and does not touch `mt76_queue_ps_skb`. 02/03/09/10 are
mt7915/mt7996/MLO (mt7996 is not in 5.15). 05–08 are mt7603-only. 04 is
standalone. All helpers used (`ieee80211_is_data_qos`,
`ieee80211_get_qos_ctl`, `IEEE80211_QOS_CTL_EOSP`,
`IEEE80211_FRAME_RELEASE_UAPSD`) exist in this tree via `mt76.h` →
`<net/mac80211.h>` / `ieee80211.h`.

## Phase 4: Mailing list / external

**Step 4.1 — original discussion**
Record: `b4 dig -c 0b8d252471609` →
https://patch.msgid.link/20260801145334.1166751-4-nbd@nbd.name
`b4 dig -a`: single **v1** series, 2026-08-01. Applied version is that
v1. Thread has the 10 patches plus a kernel-test-robot build error on
**10/10** (`ieee80211_txq_aql_pending` / patch 01), **not** on 04. No
NAK, no reviewer concern about EOSP. Merged via `wireless-
next-2026-08-06` into `v7.3-rc1`.

**Step 4.2 — recipients (`b4 dig -w`)**
Record: Felix Fietkau, `linux-wireless@vger.kernel.org`. Maintainer-
authored self-merge; no extra Reviewed-by. Normal for mt76.

**Step 4.3 — bug report**
Record: No syzbot/bugzilla. The series commit messages describe a
concrete on-air failure (clients waiting for EOSP). Unverified: no
public user stack trace beyond the author’s analysis.

**Step 4.4 — series context**
Record: 04 is the common-path EOSP fix. 05 is the mt7603 driver-PS-queue
analogue. Taking 04 without 05 still fixes mac80211-buffered frames on
**all** chips that use `mt76_release_buffered_frames` (mt76x0/x2,
mt7615, mt7915, mt7921, and mt7603’s fallback).

**Step 4.5 — stable list**
Record: `lore.kernel.org/stable/?q=mt76+EOSP+QoS` → **No results
found**. No recorded reason to skip it.

## Phase 5: Semantic / call graph

**Step 5.1 — functions**
Record: `mt76_queue_ps_skb`, `mt76_release_buffered_frames`.

**Step 5.2 — callers**
Record: `mt76_queue_ps_skb` only from `mt76_release_buffered_frames`.
That is `.release_buffered_frames` for mt76x0, mt76x2, mt7615, mt7915,
mt7921; mt7603 wraps it after draining `msta->psq`. mac80211 calls it
from `ieee80211_sta_ps_deliver_response()` →
`drv_release_buffered_frames()`.

**Step 5.3 — callees**
Record: `IEEE80211_SKB_CB`, `ieee80211_is_data_qos`,
`ieee80211_get_qos_ctl`, `mt76_skb_set_moredata`, `__mt76_tx_queue_skb`.
No new locks/allocs.

**Step 5.4 — reachability**
Record: Yes, from the air. AP RX of a U-APSD trigger
(`ieee80211_sta_uapsd_trigger` in `mac80211.c` / `rx.c`) →
`ieee80211_sta_ps_deliver_uapsd` → driver release. This tree sets
`WIPHY_FLAG_AP_UAPSD`. Typical trigger: a phone associated to an mt76
AP.

**Step 5.5 — similar patterns**
Record: mac80211 `sta_info.c` uses the same `*qoshdr |=
IEEE80211_QOS_CTL_EOSP`. Sibling mt7603 patch 05 does the same for TXD-
prefixed PS-queue frames (`skb->data[MT_TXD_SIZE]`). Common-path frames
from `ieee80211_tx_dequeue` have the 802.11 header at `skb->data` (same
as `mt76_skb_set_moredata`).

## Phase 6: This tree (5.15.221)

**Step 6.1 — buggy code present?**
Record: **Yes.** `drivers/net/wireless/mediatek/mt76/tx.c`
`mt76_queue_ps_skb()` (lines 344–358) sets only
`IEEE80211_TX_STATUS_EOSP`, not the QoS EOSP bit. Introduced v4.16;
U-APSD AP enabled here since 2020.

`git describe HEAD`: `p-5.15-2-g6703e5d2f3a29`. `make kernelversion`:
**5.15.221**. `git merge-base --is-ancestor 0b8d252471609 HEAD` → **not
present**.

**Step 6.2 — backport difficulty**
Record: **Clean apply.** `git apply --check` succeeded; hunks applied at
offset −69 only because `mt76_txq_dequeue` still uses
`MT_TX_HW_QUEUE_EXT_PHY` here vs `FIELD_PREP(MT_TX_HW_QUEUE_PHY, …)`
upstream. That function is context, not part of the change.

**Step 6.3 — related fixes already here?**
Record: No. Only `7267a7965dd7b` (TX status for the software EOSP flag),
which is exactly the incomplete behavior this commit finishes.

## Phase 7: Subsystem

**Step 7.1**
Record: `drivers/net/wireless/mediatek/mt76` — Wi-Fi driver.
**IMPORTANT** (not core kernel, but widely used: OpenWrt/home routers,
mt76x0/x2/7603/7615/7915/7921).

**Step 7.2**
Record: Mature driver; this PS-release path has been stable since 2017.
Not a bug in brand-new code.

## Phase 8: Impact and risk

**Step 8.1 — who**
Record: Driver/config-specific: `CONFIG_MT76*` AP mode with U-APSD
clients. Large real-world set (MediaTek AP SoCs).

**Step 8.2 — trigger**
Record: Associated STA in power-save using U-APSD (typical phones) sends
a trigger; AP releases buffered QoS data. Not a rare error path.
Unprivileged on the air (associated client). PS-Poll-only clients are
unaffected by the new bit.

**Step 8.3 — failure mode**
Record: **Station downlink stall** until the client gives up the SP. Not
a kernel oops. Severity: **HIGH** (loss of connectivity for that STA),
not CRITICAL (no panic/corruption).

**Step 8.4 — risk/benefit**
Record: Benefit high for mt76 AP + U-APSD clients. Risk very low: ~12
lines, QoS bit only on last U-APSD QoS-data frame, same pattern as
mac80211, clean apply, no API/struct change. Patch 01’s
`ieee80211_txq_aql_pending` is **not** required.

## Phase 9: Synthesis

**Step 9.1 — evidence**

For:
- Real, documented 802.11 bug: missing on-air EOSP → downlink stall
- Code and AP U-APSD flag exist in 5.15.221
- Bug since v4.16
- Maintainer-authored, merged to mainline (`v7.3-rc1`), no revert, no
  later rewrite of this function
- 12 insertions / 4 deletions, clean apply
- Matches mac80211
- Standalone despite 04/10 numbering

Against:
- Not crash/security/corruption
- No `Reported-by` / syzbot
- No extra reviewer
- mt7603 hardware PS-queue still wrong without patch 05 (does not make
  04 incorrect or unusable)

Unresolved: no independent end-user report found beyond the maintainer’s
analysis.

**Step 9.2 — stable rules**
1. Obviously correct and tested? **PASS** — same as mac80211; in
   mainline since v7.3-rc1
2. Real bug affecting users? **PASS** — U-APSD clients on mt76 APs
3. Important? **PASS** — full downlink stall for the STA (HIGH)
4. Small/contained? **PASS** — one file, ~12 lines
5. No new features/APIs? **PASS** — sets a standard 802.11 bit the
   driver was already required to set
6. Applies to this tree? **PASS** — `git apply --check` clean

**Step 9.3 — exceptions**
Record: None (not an ID/quirk/DT/build/doc exception). Qualifies as a
normal bugfix.

**Step 9.4 — decision**
This 5.15.221 tree has the buggy path, U-APSD AP support, and every API
the patch needs. The change is a small, self-contained protocol fix for
a serious AP-mode connectivity failure. It should be backported here.

---

### What it solves for 5.15 users
On MediaTek mt76 APs, U-APSD service periods never get the EOSP bit on
the last released QoS frame. mac80211 thinks the SP ended
(`IEEE80211_TX_STATUS_EOSP`), but the client never sees EOSP on the air,
stops triggering, and **downlink to that station stalls**. Setting
`IEEE80211_QOS_CTL_EOSP` on the last U-APSD QoS-data frame is what
mac80211 already documents and implements when the driver does not take
`.release_buffered_frames`.

### Stable rules / risk
Meets all six criteria. Benefit is restoring buffered downlink for
U-APSD clients; risk is a one-bit header update on a path that already
rewrites More Data. No series dependencies for this hunk. mt7603’s
separate PS-queue EOSP bug is a sibling, not a blocker.

### Verification
- [Phase 1] Parsed tags: Link to 04/10, author SOB only; no
  Fixes/Reported-by/Cc:stable
- [Phase 1] `git log origin/master --grep='set the EOSP bit' --
  drivers/net/wireless/mediatek/mt76/`: `0b8d252471609`
- [Phase 1] `git describe --contains --match 'v*' 0b8d252471609`:
  `v7.3-rc1~133^2~99^2~15^2~8`
- [Phase 2] Diff: `mt76_queue_ps_skb` + `reason`; EOSP OR on last U-APSD
  QoS-data frame; two call sites
- [Phase 2] Compared to `net/mac80211/sta_info.c:1708` (`*qoshdr |=
  IEEE80211_QOS_CTL_EOSP`) — same mechanism
- [Phase 2] Confirmed `include/net/mac80211.h` requires the driver to
  set EOSP when `.release_buffered_frames` is implemented
- [Phase 3] `git blame` on `tx.c` 345–403: introduced `17f1de56df0512`
  (v4.16-rc1)
- [Phase 3] `git log --grep='EOSP' --
  drivers/net/wireless/mediatek/mt76/`: only TX-status EOSP
  (`7267a7965dd7b`) in this tree
- [Phase 3] Patch 01 `a547b414bf7ea` does not touch `mt76_queue_ps_skb`
  (not a prerequisite)
- [Phase 4] `b4 dig -c 0b8d252471609`: lore URL above; `b4 dig -a`: v1
  only; `b4 dig -w`: linux-wireless + author
- [Phase 4] 11-message mbox: no NAK on 04; kbuild error is on 10/10 /
  patch 01
- [Phase 4] `curl` stable lore for `mt76 EOSP QoS`: no results
- [Phase 5] Callers: mt76x0/x2, mt7615, mt7915, mt7921 ops; mt7603
  wrapper; mac80211 `drv_release_buffered_frames`
- [Phase 5] This tree: `WIPHY_FLAG_AP_UAPSD` and
  `ieee80211_sta_uapsd_trigger` in `mt76/mac80211.c`
- [Phase 6] `git describe HEAD`: `p-5.15-2-g6703e5d2f3a29`; `make
  kernelversion`: 5.15.221
- [Phase 6] `git merge-base --is-ancestor 0b8d252471609 HEAD`: not in
  tree
- [Phase 6] `git apply --check` of 04/10: success, offset −69
- [Phase 6] APIs present: `IEEE80211_QOS_CTL_EOSP` `0x0010`,
  `ieee80211_get_qos_ctl`, `ieee80211_is_data_qos`,
  `IEEE80211_FRAME_RELEASE_UAPSD`
- [Phase 8] Failure mode: STA downlink stall (HIGH), not oops
- UNVERIFIED: no independent user bugzilla/syzbot report; impact
  inferred from protocol + maintainer description

**YES**

 drivers/net/wireless/mediatek/mt76/tx.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
index 731caeda72b52..93275bb692fa5 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -415,16 +415,23 @@ mt76_txq_dequeue(struct mt76_phy *phy, struct mt76_txq *mtxq)
 
 static void
 mt76_queue_ps_skb(struct mt76_phy *phy, struct ieee80211_sta *sta,
-		  struct sk_buff *skb, bool last)
+		  struct sk_buff *skb, bool last,
+		  enum ieee80211_frame_release_type reason)
 {
 	struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 
 	info->control.flags |= IEEE80211_TX_CTRL_PS_RESPONSE;
-	if (last)
+	if (last) {
 		info->flags |= IEEE80211_TX_STATUS_EOSP |
 			       IEEE80211_TX_CTL_REQ_TX_STATUS;
 
+		if (reason == IEEE80211_FRAME_RELEASE_UAPSD &&
+		    ieee80211_is_data_qos(hdr->frame_control))
+			*ieee80211_get_qos_ctl(hdr) |= IEEE80211_QOS_CTL_EOSP;
+	}
+
 	mt76_skb_set_moredata(skb, !last);
 	__mt76_tx_queue_skb(phy, MT_TXQ_PSD, skb, wcid, sta, NULL);
 }
@@ -457,14 +464,15 @@ mt76_release_buffered_frames(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
 
 			nframes--;
 			if (last_skb)
-				mt76_queue_ps_skb(phy, sta, last_skb, false);
+				mt76_queue_ps_skb(phy, sta, last_skb, false,
+						  reason);
 
 			last_skb = skb;
 		} while (nframes);
 	}
 
 	if (last_skb) {
-		mt76_queue_ps_skb(phy, sta, last_skb, true);
+		mt76_queue_ps_skb(phy, sta, last_skb, true, reason);
 		dev->queue_ops->kick(dev, hwq);
 	} else {
 		ieee80211_sta_eosp(sta);
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] wifi: rtlwifi: rtl8723be: Remove unnecessary irq save/restore in hw_init()
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (6 preceding siblings ...)
  2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.15] wifi: mt76: set the EOSP bit in the QoS header of the last released frame Sasha Levin
@ 2026-10-19 13:46 ` Sasha Levin
  2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.10] wifi: ath10k: trigger hardware recovery upon rx failures Sasha Levin
                   ` (32 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:46 UTC (permalink / raw)
  To: patches, stable
  Cc: William Hansen-Baird, Ping-Ke Shih, Sasha Levin, linux-wireless,
	linux-kernel

From: William Hansen-Baird <william.hansen.baird@gmail.com>

[ Upstream commit 1b4cd55626b6ffa93d18848412afb912a4add585 ]

rtl8723be hw_init() calls local_save_flags(flags) followed by
local_irq_enable(). Later, local_irq_restore(flags) is called.

This causes warnings from Lockdep on boot and modprobe,
as local_irq_restore(flags) should only be called while irqs are disabled.
The warning was introduced to detect this class of bug in [1].

With testing I found that all paths which call hw_init() have irqs
already enabled for rtl8723be.

Furthermore, the calls were originally added for the rtl8192ce
in commit f78bccd79ba3 ("rtlwifi: rtl8192ce: Fix too long disable of IRQs")
before later being added to most other rtlwifi drivers.

Commit d3feae41a347 ("rtlwifi: Update power-save routines for 062814 driver")
then replaces the call to spin_lock_irqsave() before hw_init(),
and thus the codepath which caused irqs to be disabled in hw_init and
prompted the original commit has been removed.

The same irq save/restore pattern is also present in the hw_init() of
rtl8192ce, rtl8723ae, rtl8188ee, rtl8192se and rtl8192cu,
however I don't have the hardware to test them,
so I did not include them in my changes.

Tested on a Razer Blade 14 2017.

Example of output from Lockdep prior to fix:

raw_local_irq_restore() called with IRQs enabled

...

Call Trace:
<TASK>
rtl8723be_hw_init+0x5992/0x7220 [rtl8723be]
? static_obj+0x61/0xa0
rtl_pci_start+0x222/0x5c0 [rtl_pci]
rtl_op_start+0x128/0x1a0 [rtlwifi]
? __kasan_check_read+0x11/0x20
drv_start+0x16c/0x550 [mac80211]

...

irq event stamp: 887679
hardirqs last  enabled at (887689): [<ffffffff96511170>] __up_console_sem+0x90/0xa0
hardirqs last disabled at (887698): [<ffffffff96511155>] __up_console_sem+0x75/0xa0
softirqs last  enabled at (887670): [<ffffffff962f4675>] __irq_exit_rcu+0x175/0x2f0
softirqs last disabled at (887649): [<ffffffff962f4675>] __irq_exit_rcu+0x175/0x2f0
---[ end trace 0000000000000000 ]---

[1] https://lore.kernel.org/all/20210111153707.10071-1-mark.rutland@arm.com/

Signed-off-by: William Hansen-Baird <william.hansen.baird@gmail.com>
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260609095359.2964193-1-william.hansen.baird@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **v7.3-rc4** (mainline 7.3). The candidate is a six-
line IRQ API fix in `rtl8723be_hw_init()` that stops a real `WARN_ONCE`
on boot. Full phase walkthrough follows.

---

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: PARSE THE SUBJECT LINE**

Record: **[wifi: rtlwifi: rtl8723be]** **[Remove]** unnecessary irq
save/restore in `hw_init()`. Intent: drop a leftover `local_save_flags`
/ `local_irq_enable` / `local_irq_restore` sequence that is no longer
valid.

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**

Record:
- **Acked-by:** Ping-Ke Shih `<pkshih@realtek.com>` (rtlwifi maintainer)
- **Signed-off-by:** William Hansen-Baird (author); Ping-Ke Shih
  (maintainer)
- **Link:** https://patch.msgid.link/20260609095359.2964193-1-
  william.hansen.baird@gmail.com
- No Fixes:, Reported-by:, Tested-by:, Cc: stable (absence expected)
- Ignore pipeline SOBs

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**

Record:
- **Bug:** `rtl8723be_hw_init()` does `local_save_flags(flags);
  local_irq_enable();` … `local_irq_restore(flags)` while IRQs are
  already enabled.
- **Symptom:** `WARN_ONCE` from `warn_bogus_irq_restore()`:
  `raw_local_irq_restore() called with IRQs enabled`, on boot and
  `modprobe`. Stack: `rtl8723be_hw_init` → `rtl_pci_start` →
  `rtl_op_start` → `drv_start`.
- **Root cause:** The save/enable/restore was copied from rtl8192ce
  (`f78bccd79ba3`, 2014) to keep IRQs enabled during a long `hw_init()`
  that used to run under `spin_lock_irqsave()`. `d3feae41a347` (2014)
  removed that irqsave around the power-save/`hw_init` path, so callers
  now enter with IRQs enabled. Restore of already-enabled flags is
  forbidden.
- **Version info:** Pattern present since the rtl8723be driver was added
  (`a619d1abe20cc`, 2014-02-28). Warning added in `997acaf6b4b59`
  (2021).
- **Author explanation:** All current rtl8723be `hw_init()` callers have
  IRQs enabled (tested on a Razer Blade 14 2017). Sibling chips still
  have the pattern but were left alone for lack of hardware.

**Step 1.4: DETECT HIDDEN BUG FIXES**

Record: Not hidden. Explicit lockdep/IRQ-restore warning fix. “Remove
unnecessary” is accurate: the sequence became a no-op plus a warning
after the 2014 caller change.

---

## PHASE 2: DIFF ANALYSIS

**Step 2.1: INVENTORY THE CHANGES**

Record:
- File: `drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c` — **6
  deletions, 0 additions**
- Function: `rtl8723be_hw_init()`
- Scope: single-file surgical fix

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**

Record:
- **Before:** Save flags, force IRQs on for the whole init, restore
  flags at the `exit:` label (success and error).
- **After:** Init runs in the caller’s IRQ state; `exit:` only clears
  `being_init_adapter`.
- **Path:** Normal and error `hw_init()` (boot, `modprobe`, interface
  start, IPS nic-on).

**Step 2.3: IDENTIFY THE BUG MECHANISM**

Record: **Logic / IRQ-flag API misuse** (WARN_ON class).
`local_irq_restore()` must be called with IRQs disabled
(`raw_check_bogus_irq_restore()` in `include/linux/irqflags.h`). Callers
already have IRQs enabled, so restore trips `WARN_ONCE`. Same class as
`8b144dedb928e` (“rtlwifi: rtl8192cu: Fix WARNING when calling
local_irq_restore() with interrupts enabled”), which used
`local_irq_disable()` before restore and was **Cc: stable**. Here the
save/enable/restore is removed because it is no longer needed.

**Step 2.4: ASSESS THE FIX QUALITY**

Record:
- Obviously correct if all callers have IRQs enabled (author tested;
  maintainer agreed; `rtl_pci_start` / `rtl_op_start` /
  `rtl_ps_enable_nic` are process-context, mutex/work, not
  `spin_lock_irqsave`).
- Minimal: six lines deleted, no unrelated edits.
- Regression risk: if some caller still had IRQs off, `hw_init()` could
  run ~hundreds of ms with IRQs disabled (the 2014 audio-underrun/clock-
  freeze bug). Verified not the case in this tree. Maintainer: “current
  `hw_init()` is not in scope of `spin_lock_irqsave()`, so irqs is not
  disabled.”

---

## PHASE 3: GIT HISTORY INVESTIGATION

**Step 3.1: BLAME THE CHANGED LINES**

Record: IRQ save/restore was in rtl8723be from **`a619d1abe20cc`
(“rtlwifi: rtl8723be: Add new driver”, 2014-02-28)**. Pattern copied
from rtl8192ce `f78bccd79ba3` (2014-02-01). Present for ~12 years.

**Step 3.2: FOLLOW THE FIXES: TAG**

Record: No Fixes: tag. Related history:
- `f78bccd79ba3` — **in this tree** — added save/enable/restore because
  `hw_init` ran too long with IRQs off.
- `d3feae41a347` — **in this tree** — replaced `spin_lock_irqsave`
  before `hw_init` with `spin_lock` / mutex; IRQ-disabled caller gone.
- `997acaf6b4b59` — **in this tree** — added the `WARN_ONCE`.
- `8b144dedb928e` (2021) — **in this tree** — same warning on rtl8192cu;
  **Cc: stable**.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**

Record: Recent `rtl8723be/hw.c` commits are unrelated (stack size, const
arrays, LED, `kfree_skb`). Standalone; not patch X/Y in the committed
form (v2 was a single patch).

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**

Record: William Hansen-Baird is a contributor, not the maintainer.
Nearby work is separate ASPM quirks for the same chip (June 30), not
prerequisites. Maintainer Ping-Ke Shih acked and applied it.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**

Record: None. Deletes three API calls that have existed since 2014.
Applies standalone.

---

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**

Record:
- Lore/msgid: https://patch.msgid.link/20260609095359.2964193-1-
  william.hansen.baird@gmail.com
- v1: https://patch.msgid.link/20260608135345.2526325-3-
  williamhb+k@fastmail.com
- v1 → v2: drop dmesg timestamps, `[1]` footnote, `rtw-next` subject
  prefix. **Code unchanged.**
- Maintainer: “I think removal is okay.” No NAK. No Cc: stable in
  review. Applied to rtw-next as `1b4cd55626b6`.

**Step 4.2: CHECK WHO REVIEWED THE PATCH**

Record: To/Cc: `pkshih@realtek.com`, linux-wireless, linux-kernel.
Subsystem maintainer reviewed and Acked.

**Step 4.3: SEARCH FOR THE BUG REPORT**

Record: No syzbot/bugzilla for this exact chip. Author reproduced on a
Razer Blade 14 2017 with a full lockdep-style trace. Same warning class
was syzbot+stable for rtl8192cu in 2021.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**

Record: v1 msgid `-3` looks like a series slot; v2 was sent standalone.
Other June 2026 Hansen-Baird rtlwifi patches are ASPM, independent.
Sibling drivers (rtl8192ce, rtl8723ae, rtl8188ee, rtl8192se, rtl8192cu)
still have the pattern; not required for this chip’s fix.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**

Record: No stable-thread discussion found for this subject. Precedent:
`8b144dedb928e` was explicitly Cc: stable for the same warning.

---

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1: IDENTIFY KEY FUNCTIONS**

Record: `rtl8723be_hw_init()` only.

**Step 5.2: TRACE CALLERS**

Record:
- `rtl_pci_start()` (`pci.c:1737`) ← `rtl_op_start()` (`core.c:129`,
  `conf_mutex`) ← mac80211 `drv_start`. Matches the reported stack.
  Process context, IRQs on.
- `rtl_ps_enable_nic()` (`ps.c:26`) ←
  `_rtl8723be_phy_set_rf_power_state()` IPS ERFON path (`phy.c:2534`) ←
  `rtl_ps_set_rf_state()` (plain `spin_lock`, not irqsave) ←
  `rtl_ips_nic_on()` (`ips_mutex`). Process/work context, IRQs on.
- USB `rtl_usb_start()` also calls `hw_init`; **RTL8723BE is PCIe-only**
  (`CONFIG_RTL8723BE`).

**Step 5.3: TRACE CALLEES**

Record: MAC/FW/PHY init, register I/O, `rtl8723be_dm_init`. Long-
running, sleepable. Must not run with IRQs off for hundreds of ms —
which is why 2014 added enable, and why it is safe to drop now that
callers already have IRQs on.

**Step 5.4: FOLLOW THE CALL CHAIN**

Record: Userspace-reachable: interface up / module load / IPS wake.
Unprivileged users who can bring the interface up can hit it. Debug
kernels dump a warning on every start.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**

Record: Same save/enable/restore still in rtl8723ae, rtl8192ce,
rtl8188ee, rtl8192se, rtl8192cu. rtl8192cu already does
`local_irq_disable()` before restore (`8b144dedb928e`). Systematic
leftover; this patch only fixes the tested chip.

---

## PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**

Record:
- Local tree: **`v7.3-rc4-27-gf0100363d8c37`**, `VERSION=7 PATCHLEVEL=3`
  (7.3.0-rc4).
- Driver and `rtl8723be_hw_init()` exist. Buggy sequence was here from
  2014 until **`1b4cd55626b6f`**, which is already in **v7.3-rc1** (not
  in v7.2).
- Current `hw.c` has no `local_save_flags` (grep empty). Evaluation is
  of the fix’s merit for this lineage, where the bug lived for years and
  the code still matches.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**

Record: Expected apply: **clean**. Six-line deletion of a pattern
unchanged since 2014. No structural dependency on later rtlwifi
refactors.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**

Record: This exact fix is in 7.3-rc1. No alternate fix for rtl8723be.
rtl8192cu’s 2021 workaround is a sibling, not a substitute.

---

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**

Record: **wifi / rtlwifi / rtl8723be** (Realtek RTL8723BE PCIe 802.11n).
**IMPORTANT** (common 2014–2018 laptop WiFi: ThinkPads, Razers, etc.),
not core mm/net.

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**

Record: Mature, low-churn vendor driver. Bug is old leftover, not a new-
feature regression.

---

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: DETERMINE WHO IS AFFECTED**

Record: **Driver-specific**, `CONFIG_RTL8723BE`. Warning only with
**`CONFIG_DEBUG_IRQFLAGS`** (selected by `DEBUG_LOCKDEP`). Debug/lockdep
kernels, syzbot-style configs, `panic_on_warn`. Production distro
kernels usually omit lockdep, so they would not print it — the API
misuse is still present.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**

Record: Every `hw_init()`: boot, `modprobe`, iface start. Not a race.
Unprivileged users can trigger via network start if the module is
loaded.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**

Record: `WARN_ONCE` in `warn_bogus_irq_restore()`. Not a panic/oops by
default. Can panic if `panic_on_warn`. Mark Rutland’s 2021 commit notes
restore-with-IRQs-enabled can desync IRQ-state tracing and break archs
whose `arch_local_irq_restore()` assumes IRQs are off. **Severity:
MEDIUM** (WARN_ON), with a documented arch/lockdep correctness angle.
Prompt lists WARN_ON triggers as a strong backport signal.

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**

Record:
- **Benefit:** Stops a boot-time warning on a common laptop chip;
  restores correct IRQ API use. Same class already taken into stable for
  rtl8192cu.
- **Risk:** Very low (6-line delete). Residual risk is long IRQ-off
  `hw_init` if some caller still had IRQs disabled — **not true in this
  tree**.
- **Ratio:** Favorable.

---

## PHASE 9: FINAL SYNTHESIS

**Step 9.1: COMPILE THE EVIDENCE**

**FOR:**
- Real, reproduced `WARN_ONCE` on boot/`modprobe` (Razer Blade 14 2017).
- Incorrect `local_irq_restore()` usage; can confuse lockdep and some
  arch restore paths.
- Six-line deletion, obviously correct once callers have IRQs enabled
  (verified in `rtl_pci_start` / `rtl_op_start` / IPS).
- Tested on hardware; Acked and applied by Ping-Ke Shih.
- Same warning on rtl8192cu was **Cc: stable** in 2021.
- Driver present since 2014; no missing prerequisites.
- WARN_ON is listed as a strong stable signal.

**AGAINST:**
- Warning is gated on `CONFIG_DEBUG_IRQFLAGS`; typical production
  kernels never print it.
- Not a crash, deadlock, corruption, or security hole in the default
  config.
- Sibling chips left unfixed (incomplete family-wide cleanup, not a
  dependency).
- Removing enable-IRQs-during-init would be harmful if an IRQ-disabled
  caller still existed (none found here).

**UNRESOLVED:** Could not fetch lore HTML (403); used `b4 dig -m` mbox
instead. No stable@ thread found for this specific subject.

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**

1. Obviously correct and tested? **PASS** — hardware test + maintainer
   ack; callers have IRQs on.
2. Fixes a real bug that affects users? **PASS** — lockdep/debug warning
   on every start of this NIC.
3. Important issue? **PASS** (MEDIUM) — WARN_ONCE; same class previously
   shipped to stable; not a production panic.
4. Small and contained? **PASS** — 6 lines, one function.
5. No new features or APIs? **PASS**.
6. Can apply to the local tree? **PASS** — code exists; deletion applies
   cleanly to the pre-fix file.

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**

Record: None (not a device ID, quirk table, DT, build, or docs-only
change). Qualifies as a normal small bugfix.

**Step 9.4: MAKE YOUR DECISION**

This is a small, verified fix for a real IRQ-flag warning that fires on
a common PCIe WiFi chip whenever `hw_init()` runs under debug
IRQ/lockdep configs. Callers in this tree already have IRQs enabled, so
deleting the leftover save/enable/restore is the right fix and does not
reintroduce long IRQ-off init. Benefit clearly beats risk.

---

### What the commit solves for stable users

`rtl8723be_hw_init()` restored IRQ flags while IRQs were already
enabled, which `CONFIG_DEBUG_IRQFLAGS` treats as broken and warns on
every boot/`modprobe`. The enable/restore dance was only needed when
`hw_init()` ran under `spin_lock_irqsave()`; that path has been gone
since 2014. Users of RTL8723BE (many 2014–2018 laptops) on debug kernels
get a stack dump at start; `panic_on_warn` would panic.

### Stable rules / risk vs benefit

Meets all six rules: tiny, tested, no new API, applies cleanly. Risk is
a 6-line delete. Benefit is removing a boot-time WARN and illegal
restore. Same bug class was already backported for rtl8192cu.

### Concerns

None that block a backport here: no extra commits required; sibling
chips are independent; production kernels without `DEBUG_IRQFLAGS`
simply never print the warning, but the misuse is still worth fixing.

---

Verification:
- [Phase 1] Parsed tags: Acked-by Ping-Ke Shih; Link msgid
  20260609095359; no Fixes/Cc:stable/syzbot
- [Phase 1] Body: lockdep `raw_local_irq_restore() called with IRQs
  enabled`; stack `rtl8723be_hw_init` → `rtl_pci_start` → `rtl_op_start`
- [Phase 2] Diff: 6 deletions in `rtl8723be_hw_init()` only (`git show
  1b4cd55626b6f`)
- [Phase 3] `git merge-base --is-ancestor`: `f78bccd79ba3`,
  `d3feae41a347`, `997acaf6b4b59`, `8b144dedb928e` all in HEAD
- [Phase 3] `git log -S local_save_flags -- rtl8723be/hw.c`: introduced
  in `a619d1abe20cc` (2014), removed in `1b4cd55626b6f`
- [Phase 3] `8b144dedb928e`: same warning on rtl8192cu, Cc: stable,
  added `local_irq_disable()` before restore
- [Phase 4] `b4 dig -c 1b4cd55626b6f`: lore match; v1→v2 message-only;
  maintainer ack, no NAK
- [Phase 4] `b4 dig -m`: saved /tmp/rtl8723be-thread.mbox (721 lines);
  WebFetch lore HTML 403
- [Phase 5] Callers: `rtl_pci_start` under `conf_mutex`;
  `rtl_ps_enable_nic` from IPS via `spin_lock` not irqsave
- [Phase 5] Grep: sibling drivers still have `local_save_flags`;
  rtl8723be file has none after the fix
- [Phase 6] `git describe HEAD`: v7.3-rc4-27-gf0100363d8c37; `make
  kernelversion` 7.3.0-rc4
- [Phase 6] Commit in v7.3-rc1, not v7.2; current hw.c already patched
- [Phase 7] `CONFIG_RTL8723BE` PCIe 802.11n; driver added 2014
- [Phase 8] `warn_bogus_irq_restore()` is `WARN_ONCE`; `DEBUG_LOCKDEP`
  selects `DEBUG_IRQFLAGS`
- UNVERIFIED: no stable@ mailing-list thread for this exact subject
  (search not exhaustive beyond b4/git)

The fix is small, surgical, and meets the stable criteria for this tree.

**YES**

 drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
index e1f8112188949..bf7b5a32adaaf 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
@@ -1333,11 +1333,6 @@ int rtl8723be_hw_init(struct ieee80211_hw *hw)
 	bool rtstatus = true;
 	int err;
 	u8 tmp_u1b;
-	unsigned long flags;
-
-	/* reenable interrupts to not interfere with other devices */
-	local_save_flags(flags);
-	local_irq_enable();
 
 	rtlhal->fw_ready = false;
 	rtlpriv->rtlhal.being_init_adapter = true;
@@ -1443,7 +1438,6 @@ int rtl8723be_hw_init(struct ieee80211_hw *hw)
 
 	rtl8723be_dm_init(hw);
 exit:
-	local_irq_restore(flags);
 	rtlpriv->rtlhal.being_init_adapter = false;
 	return err;
 }
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] wifi: ath10k: trigger hardware recovery upon rx failures
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (7 preceding siblings ...)
  2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.10] wifi: rtlwifi: rtl8723be: Remove unnecessary irq save/restore in hw_init() Sasha Levin
@ 2026-10-19 13:46 ` Sasha Levin
  2026-10-19 13:46 ` [PATCH AUTOSEL 6.18] wifi: mt76: wed: fix kernel panic on non-DBDC MT7986 Sasha Levin
                   ` (31 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:46 UTC (permalink / raw)
  To: patches, stable
  Cc: Manikanta Pubbisetty, Rameshkumar Sundaram, Baochen Qiang,
	Jeff Johnson, Sasha Levin, jjohnson, linux-wireless, ath10k,
	linux-kernel

From: Manikanta Pubbisetty <manikanta.pubbisetty@oss.qualcomm.com>

[ Upstream commit f78210dd4bea09090b828adc2733cad4b9916306 ]

When an error occurs during RX packet processing (e.g., MSDU done
failure), the driver sets rx_confused and drops all subsequent RX
packets until a Wi-Fi ON/OFF cycle clears the flag. This can leave
the device in a bad state where it cannot process RX data traffic.

Instead of leaving the device in such a state, trigger hardware
recovery so that such an error state can be reset and the device
can function again normally.

Tested-on: WCN3990 hw1.0 WLAN.HL.3.2.2.c10-00754-QCAHLSWMTPL-1
Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00288-QCARMSWPZ-1
Tested-on: QCA6174 hw3.2 SDIO WLAN.RMH.4.4.1-00189

Signed-off-by: Manikanta Pubbisetty <manikanta.pubbisetty@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20260710060406.3323260-1-manikanta.pubbisetty@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **Linux 7.3-rc4** (`v7.3-rc4-27-gf0100363d8c37`). The
surrounding ath10k RX and recovery code is present, and this is a small,
real device-hang fix.

---

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: PARSE THE SUBJECT LINE**
Record: **[wifi/ath10k] [trigger] [start hardware recovery when RX
processing fails instead of leaving the device stuck]**

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- **Fixes:** none (expected)
- **Reported-by:** none
- **Tested-on:** WCN3990 hw1.0; QCA6174 hw3.2 PCI; QCA6174 hw3.2 SDIO
  (three hardware/firmware combinations)
- **Reviewed-by:** Rameshkumar Sundaram, Baochen Qiang (Qualcomm ath
  reviewers)
- **Acked-by:** none
- **Link:** https://patch.msgid.link/20260710060406.3323260-1-
  manikanta.pubbisetty@oss.qualcomm.com
- **Cc: stable:** none (expected)
- **Signed-off-by:** Manikanta Pubbisetty (author); Jeff Johnson (ath
  maintainer). Ignoring Sasha Levin SOB if present in pipeline copies;
  the tree copy has none.

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** On RX processing errors (e.g. MSDU_DONE not set), the driver
  sets `htt->rx_confused` and then drops all further RX until a Wi-Fi
  ON/OFF cycle.
- **Symptom:** Device stays in a bad state and cannot process RX data
  traffic; connectivity is dead until the user toggles the interface.
- **Version info:** none in the message. The FIXME this removes dates to
  2014 (`e0bd7513bbc85`, v3.19-rc1).
- **Root cause:** Error paths mark the ring confused but never reset
  hardware, so the device stays inoperable.

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not a disguised cleanup. It is an explicit functional fix:
replace “leave device inoperable” with the existing recovery path. The
removed FIXME said the same thing since 2014.

---

## PHASE 2: DIFF ANALYSIS

**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `drivers/net/wireless/ath/ath10k/htt_rx.c` — **3 insertions, 3
  deletions** (`git show --stat`: 6 lines changed).
- Functions: `ath10k_htt_rx_handle_amsdu()`,
  `ath10k_htt_rx_in_ord_ind()` (two sites).
- Scope: single-file surgical error-path change.

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:
1. `ath10k_htt_rx_handle_amsdu()` when `ath10k_htt_rx_amsdu_pop()`
   returns `< 0`: previously purged skbs, set `rx_confused`, returned.
   Now also calls `ath10k_core_start_recovery(ar)`. FIXME removed.
2. `ath10k_htt_rx_in_ord_ind()` when pop-paddr-list fails: same recovery
   call after `rx_confused = true`.
3. Same function when `ath10k_htt_rx_extract_amsdu()` fails: same
   recovery call after purge + `rx_confused`.

All three are **error paths only**. Normal RX is unchanged.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record: **Logic / hardware-stuck recovery.** After RX ring corruption
the driver permanently refuses RX (`if (htt->rx_confused) return -EIO`).
Recovery queues `restart_work` → `ath10k_halt()` →
`ieee80211_restart_hw()` → `ath10k_start()` → `ath10k_core_start()` →
`ath10k_htt_rx_alloc()`, which sets `htt->rx_confused = false`. That is
the same recovery used on firmware crash and WMI timeout.

**Step 2.4: ASSESS THE FIX QUALITY**
Record: Obviously correct and minimal. `ath10k_core_start_recovery()`
only queues work (`queue_work(ar->workqueue_aux,
&ar->recovery_check_work)` in this tree), so it is safe from NAPI.
Existing consecutive-failure logic can WEDGE the device, so this does
not create an infinite restart loop. Risk is a brief firmware restart on
a path that was already dead. No API or data-structure changes.

---

## PHASE 3: GIT HISTORY INVESTIGATION

**Step 3.1: BLAME THE CHANGED LINES**
Record:
- Confused-without-reboot behavior introduced in **`e0bd7513bbc85`**
  (“ath10k: refactor htt->rx_confused”, 2014-11-20), first in
  **v3.19-rc1**.
- `handle_amsdu` error path from **`18235664e7f9a`** (Rajkumar
  Manoharan, 2016).
- In-order pop/extract error paths from **`c545070e404bf`** (“ath10k:
  implement rx reorder support”, 2015), v4.1 era.
- Recovery calls added by this commit **`f78210dd4bea0`**.

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No `Fixes:` tag. Historical introducer is `e0bd7513bbc85`
(ancestor of HEAD). `git merge-base --is-ancestor e0bd7513bbc85 HEAD` is
true.

**Step 3.3: CHECK FILE HISTORY**
Record: Related but independent: `7393878255e49` (skb leak on incomplete
MSDU pop) is a different patch/date/msgid. This commit is standalone
`1/1`. No prerequisite refactor in htt_rx.c.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Manikanta Pubbisetty is a Qualcomm ath10k contributor (leak fix
on the same file shortly before). Not the listed maintainer; maintainer
Jeff Johnson applied it.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record:
- `ath10k_core_start_recovery()` exists since **`5dadbe4e3718`**
  (v5.11-rc1) — ancestor of HEAD.
- Current implementation from **`f35a07a4842a8`** (Oct 2025) — ancestor
  of HEAD; queues work, does not block in the caller.
- Can apply standalone on this tree: the function, `rx_confused`, and
  both RX handlers exist.

---

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- Lore/msgid: https://patch.msgid.link/20260710060406.3323260-1-
  manikanta.pubbisetty@oss.qualcomm.com
- `b4 dig -a`: **v1 only**, single patch, no v2/v3.
- Reviews: Baochen Qiang Reviewed-by; Rameshkumar Sundaram “Actual
  change looks fine” + Reviewed-by. No NAKs, no stable nomination, no
  risk flags.
- Jeff Johnson: “Applied, thanks!” (`da5d73e12af2` in ath.git; mainline
  sha `f78210dd4bea0`).

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record: `b4 dig -w` original To/Cc: author,
`ath10k@lists.infradead.org`, `linux-wireless@vger.kernel.org`. Applied
by **Jeff Johnson**, listed ATH10K maintainer.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: No syzbot/bugzilla. Qualcomm Tested-on on three chipsets implies
they hit RX-stuck in product testing, not a theoretical FIXME-only
cleanup.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: Standalone `[ath-next] 1/1`. The earlier skb-leak patch is not
required for this change.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: lore.kernel.org HTTP fetch returned 403. `b4 dig` thread has no
stable discussion. **UNVERIFIED** whether linux-stable ever discussed
this specific patch; no evidence it was rejected.

---

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1: KEY FUNCTIONS**
Record: `ath10k_htt_rx_handle_amsdu`, `ath10k_htt_rx_in_ord_ind`; callee
`ath10k_core_start_recovery`.

**Step 5.2: TRACE CALLERS**
Record: Both called from `ath10k_htt_txrx_compl_task()` (NAPI poll): in-
order queue then `num_mpdus_ready` loop. On `-EIO` it stops processing.
That is the normal data RX completion path, not init-only.

**Step 5.3: TRACE CALLEES**
Record: `ath10k_core_start_recovery()` → `queue_work(workqueue_aux,
recovery_check_work)` → may `queue_work(workqueue, restart_work)` → halt
+ `ieee80211_restart_hw()`. No lock taken in `start_recovery`.
`in_ord_ind` holds `rx_ring.lock` while queuing work; that is safe.

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: Userspace/network RX → mac80211 → NAPI → htt_rx. Reachable on
any associated ath10k interface when firmware/DMA delivers a bad MSDU or
corrupted ring. Unprivileged traffic can contribute; the actual trigger
is firmware/hardware RX error, not a crafted syscall.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: Same `ath10k_core_start_recovery()` already used in `pci.c`
(firmware crash), `wmi.c` (command timeout), `sdio.c`/`snoc.c`,
`debug.c`. This patch extends that pattern to RX ring failure. All
`rx_confused = true` sites in htt_rx.c are covered.

---

## PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record:
- `git describe HEAD` / `make kernelversion`: **7.3.0-rc4**.
- File and functions exist. `rx_confused` still used. Recovery API
  present.
- Bug introduced v3.19; long present in this lineage.
- Working tree already contains `f78210dd4bea0` (`git merge-base --is-
  ancestor` exit 0). That is the mainline commit under review, not a
  reason to treat the bug as absent from this series’ code.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: Hunks match this tree’s htt_rx.c. Recovery is the non-blocking
workqueue form. Expected apply: **clean** on a 7.3-era tree that still
has the pre-image; current HEAD is already post-image.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: No earlier alternative fix for “reboot on rx_confused”.
`51fc7d74ce4a1` only clears the flag on load. This is the fix that
actually starts recovery.

---

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: SUBSYSTEM AND CRITICALITY**
Record: **drivers/net/wireless/ath/ath10k** — **IMPORTANT** (not core
mm/fs, but QCA6174/WCN3990 are common laptop/phone Wi-Fi). Status in
MAINTAINERS: Supported; maintainer Jeff Johnson.

**Step 7.2: SUBSYSTEM ACTIVITY**
Record: Actively maintained (Qualcomm patches through 2026). The stuck-
RX behavior itself is old; the recovery helper is mature.

---

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: WHO IS AFFECTED**
Record: **Driver-specific**, `CONFIG_ATH10K*`. QCA6174 is widely used in
PCs; WCN3990 on Qualcomm platforms.

**Step 8.2: TRIGGER CONDITIONS**
Record: RX ring pop/extract failure (incomplete MSDU, corrupted ring).
Not every packet; when it hits, RX stays dead until iface toggle. Not a
userspace exploit path.

**Step 8.3: FAILURE MODE SEVERITY**
Record: **Wi-Fi RX permanently stopped** until ON/OFF. Not a panic/UAF,
but the device is inoperable — the 2014 FIXME called it that. Severity
**HIGH** (driver hang / loss of connectivity). Consecutive recovery
failures can WEDGE, which is existing policy, not new.

**Step 8.4: RISK-BENEFIT RATIO**
Record:
- **Benefit:** Restores Wi-Fi after RX ring confusion without a manual
  toggle; uses the same recovery as firmware crash.
- **Risk:** Very low (3 calls to an existing queue_work helper; error
  paths only). Worst case is a restart of an already-dead radio.
- **Ratio:** Strongly favors taking the fix.

---

## PHASE 9: FINAL SYNTHESIS

**Step 9.1: COMPILE THE EVIDENCE**

FOR:
- Real user-visible bug: all RX dropped until Wi-Fi toggle.
- Acknowledged since 2014 in-tree FIXME.
- Small (3 calls, one file), obviously correct.
- Uses existing, NAPI-safe recovery.
- Tested on three chip/bus combinations.
- Reviewed and applied by ath maintainers; no NAKs.
- All `rx_confused = true` sites updated.
- Code and `ath10k_core_start_recovery()` exist in this 7.3-rc4 tree.

AGAINST:
- Not a crash, UAF, or security bug; workaround exists (iface bounce).
- Trigger is firmware/hardware RX error, not every boot.
- No `Fixes:`/`Cc: stable` (not a negative per the rules).

UNRESOLVED:
- lore.kernel.org WebFetch 403; thread recovered via `b4 dig -m`.
- No independent end-user bugzilla; product Tested-on only.

**Step 9.2: STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — three Tested-on lines, two
   Reviewed-by, maintainer applied.
2. Fixes a real bug that affects users? **PASS** — RX stays dead until
   ON/OFF.
3. Important issue? **PASS** — device inoperable / connectivity hang,
   HIGH.
4. Small and contained? **PASS** — 3/3 lines, one file.
5. No new features or APIs? **PASS** — only calls existing recovery.
6. Can apply to the local tree? **PASS** — htt_rx.c and
   `ath10k_core_start_recovery()` match; this tree is 7.3-rc4.

**Step 9.3: EXCEPTION CATEGORIES**
Record: None (not a device ID/quirk/DT/build/doc). Qualifies as a normal
bugfix.

**Step 9.4: DECISION**
This tree has the ath10k RX confused paths and the recovery helper.
Leaving `rx_confused` set without restart makes the radio unusable;
kicking `ath10k_core_start_recovery()` is the same response already used
for firmware crash and is safe from NAPI. That is a contained, tested
hang fix appropriate for this tree.

---

## What the commit solves for this tree

When htt RX pop/extract fails, ath10k previously set `rx_confused` and
discarded all later RX until a full Wi-Fi cycle. Users see a dead
receive path. The patch queues the existing hardware restart so
`ath10k_htt_rx_alloc()` clears the flag and the device can RX again.

It meets stable rules: obviously correct, real hang, ~3 lines, no new
API. Benefit is restoring Wi-Fi after ring confusion; risk is a restart
of an already-stuck device.

---

## Verification

- **[Phase 1]** Tags: Tested-on ×3, Reviewed-by ×2, Link msgid; no
  Fixes/Reported-by/Cc:stable.
- **[Phase 2]** `git show --stat f78210dd4bea0`: htt_rx.c +3/-3; three
  `ath10k_core_start_recovery()` calls on error paths; FIXME removed.
- **[Phase 2]** Read `ath10k_core_start_recovery()` at core.c:2534 —
  `queue_work` only.
- **[Phase 2]** Read restart path: `ath10k_core_restart` →
  `ieee80211_restart_hw` → `ath10k_start` → `ath10k_core_start` →
  `ath10k_htt_rx_alloc()` sets `rx_confused = false` (htt_rx.c:796).
- **[Phase 3]** `git log -S` / `git describe --contains e0bd7513bbc85`:
  FIXME from v3.19-rc1.
- **[Phase 3]** `ath10k_core_start_recovery` added in `5dadbe4e3718`
  (v5.11-rc1); ancestor of HEAD.
- **[Phase 3]** `git merge-base --is-ancestor` for f35a07a4842a8,
  5dadbe4e3718, c545070e404bf, e0bd7513bbc85: all 0.
- **[Phase 3]** Related leak commit `7393878255e49` is a separate patch,
  not a prerequisite.
- **[Phase 4]** `b4 dig -c f78210dd4bea0`: msgid
  20260710060406.3323260-1.
- **[Phase 4]** `b4 dig -a`: v1 only.
- **[Phase 4]** `b4 dig -w`: linux-wireless + ath10k lists.
- **[Phase 4]** `b4 dig -m`: Baochen/Rameshkumar Reviewed-by; Jeff
  Johnson applied; no NAK; no Cc:stable in thread.
- **[Phase 4]** WebFetch lore.kernel.org: 403. UNVERIFIED via HTTP;
  thread obtained via b4.
- **[Phase 5]** Callers: `ath10k_htt_txrx_compl_task`
  (htt_rx.c:4382–4395).
- **[Phase 5]** Grep: all three `rx_confused = true` sites got recovery;
  other start_recovery users are pci/wmi/sdio/snoc/debug.
- **[Phase 6]** `git describe HEAD`: v7.3-rc4-27-gf0100363d8c37; `make
  kernelversion`: 7.3.0-rc4.
- **[Phase 6]** `git merge-base --is-ancestor f78210dd4bea0 HEAD`: 0
  (commit is in this tree’s history).
- **[Phase 7]** MAINTAINERS: ATH10K Supported, Jeff Johnson.
- **[Phase 8]** Failure mode: RX hung until iface toggle; recovery
  already rate-limited to WEDGED.
- **UNVERIFIED:** linux-stable mailing list (HTTP 403); no public non-
  Qualcomm reproducer.

The fix is small, surgical, and meets the stable criteria for this
7.3-rc4 tree.

**YES**

 drivers/net/wireless/ath/ath10k/htt_rx.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index d7e429041065a..e4162d2faae66 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -2345,10 +2345,8 @@ static int ath10k_htt_rx_handle_amsdu(struct ath10k_htt *htt)
 	if (ret < 0) {
 		ath10k_warn(ar, "rx ring became corrupted: %d\n", ret);
 		__skb_queue_purge(&amsdu);
-		/* FIXME: It's probably a good idea to reboot the
-		 * device instead of leaving it inoperable.
-		 */
 		htt->rx_confused = true;
+		ath10k_core_start_recovery(ar);
 		return ret;
 	}
 
@@ -3313,6 +3311,7 @@ static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb)
 	if (ret < 0) {
 		ath10k_warn(ar, "failed to pop paddr list: %d\n", ret);
 		htt->rx_confused = true;
+		ath10k_core_start_recovery(ar);
 		return -EIO;
 	}
 
@@ -3346,6 +3345,7 @@ static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb)
 			ath10k_warn(ar, "failed to extract amsdu: %d\n", ret);
 			htt->rx_confused = true;
 			__skb_queue_purge(&list);
+			ath10k_core_start_recovery(ar);
 			return -EIO;
 		}
 	}
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18] wifi: mt76: wed: fix kernel panic on non-DBDC MT7986
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (8 preceding siblings ...)
  2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.10] wifi: ath10k: trigger hardware recovery upon rx failures Sasha Levin
@ 2026-10-19 13:46 ` Sasha Levin
  2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-6.12] wifi: rtw89: wow: add QoS control field to WoWLAN ARP response for MLO Sasha Levin
                   ` (30 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:46 UTC (permalink / raw)
  To: patches, stable
  Cc: Zhi-Jun You, Felix Fietkau, Sasha Levin, lorenzo, ryder.lee,
	matthias.bgg, angelogioacchino.delregno, linux-wireless,
	linux-kernel, linux-arm-kernel, linux-mediatek

From: Zhi-Jun You <hujy652@gmail.com>

[ Upstream commit 8a177dabeeead47dda4d4f91331282790eed0097 ]

In mt76_wed_init_rx_buf, it's hardcoded to use MT_RXQ_MAIN.
But for non-DBDC MT7986 MT_RXQ_BAND1 is used for RX data queue which
leads to kernel panic when attaching WED.

Use the correct RX queue by checking WED version and band_idx.

v2 and band 1 -> MT_RXQ_BAND1
Others -> MT_RXQ_MAIN

Kernel panic:

Unable to handle kernel access to user memory outside uaccess routines at virtual address 0000000000000000
Mem abort info:
  ESR = 0x0000000096000005
  EC = 0x25: DABT (current EL), IL = 32 bits
  SET = 0, FnV = 0
  EA = 0, S1PTW = 0
  FSC = 0x05: level 1 translation fault
Data abort info:
  ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000
  CM = 0, WnR = 0, TnD = 0, TagAccess = 0
  GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
Internal error: Oops: 0000000096000005 [#1]  SMP
CPU: 1 UID: 0 PID: 925 Comm: kmodloader Tainted: G           O        6.18.26 #0 NONE
Tainted: [O]=OOT_MODULE
Hardware name: Acer Connect Vero W6m (DT)
pstate: 40400005 (nZcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : page_pool_alloc_frag_netmem+0x1c/0x1bc
lr : page_pool_alloc_frag+0xc/0x34
sp : ffffffc081dab660
x29: ffffffc081dab660 x28: ffffffc081dabc60 x27: ffffff80091af040
x26: 0000008000000000 x25: ffffff80091a8898 x24: ffffff80091a5440
x23: 0000000000001000 x22: 0000000140000000 x21: ffffff80091a2040
x20: ffffff8003f1d780 x19: 0000000000000000 x18: 0000000000000020
x17: ffffffbfbf0ac000 x16: ffffffc080ee0000 x15: ffffff80049d47ca
x14: 000000000000037b x13: 000000000000037b x12: 0000000000000001
x11: 0000000000000000 x10: 0000000000000000 x9 : 0000000000000000
x8 : ffffff8003f1d7c0 x7 : 0000000000000000 x6 : ffffff8003f1d780
x5 : 0000000000000680 x4 : 0000000000000000 x3 : 0000000000002824
x2 : 0000000000000000 x1 : ffffffc081dab71c x0 : 0000000000000000
Call trace:
 page_pool_alloc_frag_netmem+0x1c/0x1bc (P)
 page_pool_alloc_frag+0xc/0x34
 mt76_wed_init_rx_buf+0xf8/0x2ac [mt76]
 mtk_wed_start+0x79c/0x12ac
 mt7915_dma_start+0x274/0x63c [mt7915e]
 mt7915_dma_start+0x5b4/0x63c [mt7915e]
 mt7915_dma_init+0x49c/0x81c [mt7915e]
 mt7915_register_device+0x24c/0x530 [mt7915e]
 mt7915_mmio_probe+0x91c/0x1980 [mt7915e]
 platform_probe+0x58/0xa0
 really_probe+0xb8/0x2a8
 __driver_probe_device+0x74/0x118
 driver_probe_device+0x3c/0xe0
 __driver_attach+0x88/0x154
 bus_for_each_dev+0x60/0xb0
 driver_attach+0x20/0x28
 bus_add_driver+0xdc/0x200
 driver_register+0x64/0x118
 __platform_driver_register+0x20/0x30
 init_module+0x74/0x1000 [mt7915e]
 do_one_initcall+0x4c/0x1f8
 do_init_module+0x50/0x210
 load_module+0x15f8/0x1b10
 __do_sys_init_module+0x1a8/0x260
 __arm64_sys_init_module+0x18/0x20
 invoke_syscall.constprop.0+0x4c/0xd0
 do_el0_svc+0x3c/0xd0
 el0_svc+0x18/0x60
 el0t_64_sync_handler+0x98/0xdc
 el0t_64_sync+0x158/0x15c
Code: aa0003f3 a9025bf5 a90363f7 d2820017 (b9400000)

Signed-off-by: Zhi-Jun You <hujy652@gmail.com>
Link: https://patch.msgid.link/20260715152113.553-1-hujy652@gmail.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

This tree is **6.6.157** (`pending-6.6`). The panic is real here, but
the mainline patch has to be rewritten onto `mt7915/mmio.c` because
`wed.c` does not exist yet.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

**Step 1.1: PARSE THE SUBJECT LINE**
Record: `[wifi: mt76: wed:] [fix] [kernel panic on non-DBDC MT7986 when
attaching WED because RX buf init used the wrong queue]`

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- `Signed-off-by: Zhi-Jun You <hujy652@gmail.com>` (author)
- `Link:
  https://patch.msgid.link/20260715152113.553-1-hujy652@gmail.com` (v2
  1/2 of a 2-patch series)
- `Signed-off-by: Felix Fietkau <nbd@nbd.name>` (mt76 maintainer)
- No `Fixes:` tag (expected for this review)
- No `Cc: stable@vger.kernel.org` (expected)
- No `Reported-by:` / `Tested-by:` / `Reviewed-by:` / `Acked-by:`
- Sibling patch 2/2 has the same msgid stem `20260715152113.553-2` and
  **is already in this 6.6 tree** as `8eae5e5aa09da` (`wifi: mt76:
  mt7915: fix net_fill_forward_path for non-DBDC mt7986`)

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** `mt76_wed_init_rx_buf` always uses `MT_RXQ_MAIN`. Non-DBDC
  MT7986 uses `MT_RXQ_BAND1` for the RX data queue.
- **Symptom:** NULL deref oops while attaching WED, in
  `page_pool_alloc_frag_netmem`. Full oops from **Acer Connect Vero
  W6m**, kernel 6.18.26, PID `kmodloader` during `mt7915e` probe.
- **Root cause:** wrong RX queue → uninitialized `page_pool` (NULL) →
  fault at `page_pool_alloc_frag*`.
- **Fix:** `wed->version == 2 && dev->phy.band_idx` → `MT_RXQ_BAND1`,
  else `MT_RXQ_MAIN`.
- Crash taint includes `O` (OOT module), but the call trace is in-tree
  `mt76` / `mt7915e` / `mtk_wed_start`.

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not hidden. Explicit panic fix with a stack trace. Not
cleanup/refactor.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `drivers/net/wireless/mediatek/mt76/wed.c` (+6 / −1)
- Function: `mt76_wed_init_rx_buf`
- Scope: single-file, surgical (~5 lines of logic)

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:
- **Before:** `q = &dev->q_rx[MT_RXQ_MAIN]` always, then
  `mt76_get_page_pool_buf(q, ...)`.
- **After:** pick `MT_RXQ_BAND1` for WED v2 + band 1; otherwise
  `MT_RXQ_MAIN`.
- Path: WED RX buffer init during `mtk_wed_start` from
  `mt7915_dma_start` (probe / DMA start), not a rare error path.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record:
- Category: **NULL pointer dereference** (memory safety) from **wrong-
  queue logic**.
- Mechanism: for non-DBDC MT7986, `mt7915_band_config` sets `band_idx =
  1` and DMA only allocates `q_rx[MT_RXQ_BAND1]`. `MT_RXQ_MAIN` is left
  with `page_pool == NULL`. `mt76_get_page_pool_buf` →
  `page_pool_dev_alloc_frag(NULL)` → oops.

**Step 2.4: ASSESS THE FIX QUALITY**
Record:
- Obviously correct given DMA queue allocation in `mt7915/dma.c`.
- Minimal; no API/locking/refcount changes.
- Regression risk low: DBDC and band-0 devices still use `MT_RXQ_MAIN`.
- Backport caveat: in 6.6 the same logic lives in
  `mt7915_mmio_wed_init_rx_buf` (`dev` is `struct mt7915_dev *`), so the
  condition must use `dev->mt76.phy.band_idx` (or
  `dev->phy.mt76->band_idx`), not `dev->phy.band_idx`.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

**Step 3.1: BLAME THE CHANGED LINES**
Record:
- Hardcoded `MT_RXQ_MAIN` in 6.6: `mt7915/mmio.c:635`, from
  `2f5c3c77fc9b6` (`wifi: mt76: switch to page_pool allocator`,
  2023-02-03). Present in this tree.
- WED RX itself: `4f831d18d12da` (`wifi: mt76: mt7915: enable WED RX
  support`, 2022-12-01). Present.
- MT7986 one-A-die `band_idx = 1`: `mt7915_band_config` in `init.c`.
  Present.

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No `Fixes:` tag. Bug is the hardcoded MAIN queue vs MT7986
band-1 mapping, present since WED RX + page_pool.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record:
- `wed.c` added later by `8a7386e787ef4` (`wifi: mt76: move wed common
  utilities in wed.c`, 2024-02-22). **Not in pending-6.6** (`git merge-
  base --is-ancestor` → not ancestor).
- Related 6.6 history: WED enable for MT7986, WED RX, page_pool switch,
  several WED robustness fixes.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record:
- Author is not the mt76 maintainer; maintainer Felix Fietkau signed
  off.
- Same author, same series date: `8eae5e5aa09da` already on pending-6.6
  (patch 2/2).
- Felix has many mt7915/WED fixes on this branch.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record:
- Standalone logic; does **not** need the `wed.c` move.
- Needed in 6.6: `wed->version` (exists, `u8 version` in
  `mtk_wed_device`), `phy.band_idx`, `MT_RXQ_BAND1`, page_pool RX — all
  present.
- Series 1/2; 2/2 is independent (forward-path queue) and already
  applied.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- `b4 dig` on sibling `8eae5e5aa09da` matched msgid
  `20260715152113.553-*`.
- RFC (2026-06-13): “single band MT7986”
- v1 (2026-06-30):
  https://patch.msgid.link/20260630150649.1629-1-hujy652@gmail.com (and
  1629-2)
- v2 (2026-07-15, applied):
  https://patch.msgid.link/20260715152113.553-1-hujy652@gmail.com
- v2 1/2 is the committed version. Change vs RFC: “single band” → “non-
  DBDC”.
- lore.kernel.org fetches returned 403; thread text confirmed via
  ratatoskr mirrors.
- No NAK found. Merged by Felix Fietkau (2026-07-31) as `8a177dabeeead`.

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record (`b4 dig -w` on sibling): Zhi-Jun You; Felix Fietkau
(`nbd@nbd.name`); Lorenzo Bianconi; Ryder Lee / Shayne Chen / Sean Wang
(MediaTek); `linux-wireless`; `linux-mediatek`; Benjamin Larsson
(Suggested-by on 2/2). Maintainer merged it.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: No syzbot/bugzilla. Concrete oops from Acer Connect Vero W6m
(MT7986). Real hardware, probe-time crash with WED.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: 2-patch v2 series. 1/2 = this panic. 2/2 =
`net_fill_forward_path` wrong WDMA queue; already in 6.6. Independent;
1/2 is the crash fix.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: lore.kernel.org/stable returned 403. **UNVERIFIED** whether
anyone mailed stable@. 2/2 of the same series is already in this 6.6
tree, so the series is treated as 6.6-relevant.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

**Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF**
Record: Mainline `mt76_wed_init_rx_buf`. In this tree:
`mt7915_mmio_wed_init_rx_buf`.

**Step 5.2: TRACE CALLERS**
Record:
- Assigned as `wed->wlan.init_rx_buf` in `mt7915_mmio_wed_init`.
- Called from `mtk_wed_rx_buffer_alloc` → `dev->wlan.init_rx_buf(dev,
  dev->wlan.rx_npkt)` (`mtk_wed.c`).
- That runs from `mtk_wed_start` ← `mt7915_dma_start` ←
  `mt7915_dma_init` ← `mt7915_register_device` ← probe.
- Reachable on device probe when WED is attached (`wed_enable` module
  param).

**Step 5.3: TRACE CALLEES**
Record: `mt76_get_rxwi`, `mt76_get_page_pool_buf` →
`page_pool_dev_alloc_frag(q->page_pool)`, `mt76_rx_token_consume`. First
page_pool alloc is the crash site.

**Step 5.4: FOLLOW THE CALL CHAIN**
Record:
```
module load mt7915e
  → mt7915_mmio_probe / register_device
  → mt7915_dma_init → mt7915_dma_start
  → mtk_wed_device_start → mtk_wed_rx_buffer_alloc
  → mt7915_mmio_wed_init_rx_buf
  → mt76_get_page_pool_buf(uninitialized MT_RXQ_MAIN)
  → oops
```
Userspace-reachable via loading the driver (typically root). Not a
syscall fuzz path; it is a boot/probe crash on affected hardware.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: `mt7915/testmode.c` already uses `q = phy->mt76->band_idx ?
MT_RXQ_BAND1 : MT_RXQ_MAIN`. DMA init uses the same band_idx split. Same
author’s 2/2 fixes the matching forward-path mistake.

===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: **Yes.** Tree is 6.6.157 (`pending-6.6`). `wed.c` is absent.
Equivalent bug:

```
mt7915_mmio_wed_init_rx_buf:
    q = &dev->mt76.q_rx[MT_RXQ_MAIN];   /* mmio.c:635 */
```

`mt7915_dma.c`: allocate `MT_RXQ_MAIN` only if
`!dev->phy.mt76->band_idx`; allocate `MT_RXQ_BAND1` if `dbdc_support ||
band_idx`. `mt7915_band_config` sets `band_idx = 1` for MT7986 one-A-die
(non-DBDC). Introduced with WED RX + page_pool (2022–2023), well before
6.6.

`git merge-base --is-ancestor 8a177dabeeead pending-6.6` → **not
present**.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: **Needs a small backport**, not a clean apply. Same if/else in
`mt7915/mmio.c`, with `dev->mt76.phy.band_idx` /
`dev->phy.mt76->band_idx`. `wed->version` exists and is set to 2 for
non-netsys-v1 (MT7986) in `mtk_wed.c`. Minor conflict, not a rewrite.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: No equivalent RX-buf queue selection. 2/2 (`8eae5e5aa09da`) is
here and addresses the same hardware mapping, not this NULL deref.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: `drivers/net/wireless/mediatek/mt76` + MediaTek WED.
**IMPORTANT** (common Filogic/MT7986 WiFi, OpenWrt/embedded), not core
mm/VFS.

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: Mature and actively fixed on 6.6 (WED null-ptr, register
mapping, MT7981, chainmask for non-DBDC band 1).

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: Driver-specific: MT7986 (and similar mt798x) **non-DBDC**
(single A-die) with `CONFIG_NET_MEDIATEK_SOC_WED` and `wed_enable`. Real
product: Acer Connect Vero W6m. Default `wed_enable` is false, but WED
is used on these SoCs.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record: Every probe with WED attached on that SKU. Not a race. Needs
privilege to load the module; typical as a platform driver at boot.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record: Kernel oops/panic on WiFi/WED attach. **CRITICAL** for those
devices (WiFi unusable; can panic the box).

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record:
- **Benefit:** high for MT7986 non-DBDC + WED (prevents probe oops).
- **Risk:** low (5-line queue index; other SKUs unchanged).
- **Ratio:** benefit ≫ risk. Backport must retarget `mmio.c`.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

**Step 9.1: COMPILE THE EVIDENCE**

FOR:
- Documented oops: NULL `page_pool` in WED RX init.
- Same bug in this tree (`mt7915_mmio_wed_init_rx_buf` + DMA not
  allocating MAIN when `band_idx == 1`).
- Small, obviously correct queue selection.
- mt76 maintainer signed off; RFC → v1 → v2.
- Sibling 2/2 already on 6.6.
- MT7986 + WED RX + page_pool all exist here.
- `wed->version` and `band_idx` exist.

AGAINST:
- Patch file `wed.c` is not in 6.6 (moved in 6.8-era `8a7386e787ef4`).
- Needs a few-line context backport.
- WED off by default; subset of MT7986 boards.
- Crash log tainted OOT; still in-tree frames.

UNRESOLVED:
- Stable ML discussion (lore/stable 403).
- Whether every reviewer asked for Cc: stable (not seen on v2 1/2).

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — matches DMA allocation;
   maintainer merged; oops on real HW.
2. Fixes a real bug that affects users? **PASS** — probe oops on non-
   DBDC MT7986 + WED.
3. Important issue? **PASS** — kernel oops, severity CRITICAL for that
   hardware.
4. Small and contained? **PASS** — ~5 lines, one function.
5. No new features or APIs? **PASS**.
6. Can apply to the local tree? **PASS** with a backport to
   `mt7915/mmio.c` (stable rule: apply cleanly **or come with a
   backport**). Not a missing-feature case.

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: None (not a device ID/quirk/DT/build/doc). Ordinary crash fix.

**Step 9.4: MAKE YOUR DECISION**
The 6.6 tree has the same panic path under a pre-`wed.c` name. Selecting
this for 6.6 is justified; apply the same `version == 2 && band_idx`
check in `mt7915_mmio_wed_init_rx_buf`.

---

**What the commit solves for this tree:** On non-DBDC MT7986, the main
phy is band 1, so only `MT_RXQ_BAND1` is allocated. WED RX init still
pulls from `MT_RXQ_MAIN`, whose `page_pool` is NULL, and the kernel
oopses in `page_pool_alloc_frag` during `mt7915e` probe. That mapping is
already in 6.6 `init.c`/`dma.c`; only the RX-buf picker is wrong.

**Stable rules:** Real, important crash; tiny logic fix; no new API.
File path changed after 6.6, so it needs a short backport, not a NAK.

**Risk vs benefit:** Low risk, high benefit on Filogic devices that
enable WED (including the reported Acer Vero W6m class).

**Concerns:** Must edit
`drivers/net/wireless/mediatek/mt76/mt7915/mmio.c` and use
`dev->mt76.phy.band_idx` (or `dev->phy.mt76->band_idx`) because `dev` is
`struct mt7915_dev *` here. Do not require `8a7386e787ef4`.

Verification:
- [Phase 1] Subject/tags: fix panic; SOB Zhi-Jun You + Felix Fietkau;
  Link `20260715152113.553-1`; no Fixes/Cc-stable
- [Phase 1] Series: v2 1/2; 2/2 already `8eae5e5aa09da` on pending-6.6
- [Phase 2] Diff: 6 insertions in `mt76_wed_init_rx_buf`; queue MAIN vs
  BAND1
- [Phase 3] Blame on 6.6: `q = &dev->mt76.q_rx[MT_RXQ_MAIN]` from
  `2f5c3c77fc9b6` (page_pool); present
- [Phase 3] `8a7386e787ef4` (wed.c split) **not** ancestor of
  pending-6.6
- [Phase 3] Fix `8a177dabeeead` **not** ancestor of pending-6.6
- [Phase 4] b4 dig: RFC → v1 → v2; applied v2; Felix merged 2026-07-31
- [Phase 4] Recipients: mt76 maintainers + linux-wireless/mediatek
- [Phase 4] UNVERIFIED: lore.kernel.org and lore.kernel.org/stable HTTP
  403; used ratatoskr mirrors
- [Phase 5] Caller: `mtk_wed_rx_buffer_alloc` → `wlan.init_rx_buf` from
  `mtk_wed_start` / probe
- [Phase 6] `git show pending-6.6:Makefile`: VERSION 6 / PATCHLEVEL 6 /
  SUBLEVEL 157
- [Phase 6] `git cat-file` pending-6.6 `wed.c`: path does not exist
- [Phase 6] pending-6.6 `mmio.c:635`: hardcoded `MT_RXQ_MAIN`; `init.c`
  sets `band_idx = 1` for one-A-die MT7986
- [Phase 6] DMA: MAIN allocated only if `!band_idx`; BAND1 if
  `dbdc_support || band_idx`
- [Phase 6] `wed->version` exists; set to 2 for MT7986-class WED
- [Phase 8] Failure: NULL page_pool deref → oops; CRITICAL for that
  SKU+WED
- UNVERIFIED: whether an out-of-tree module contributed besides in-tree
  frames (taint `O`)

**YES**

 drivers/net/wireless/mediatek/mt76/wed.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/wed.c b/drivers/net/wireless/mediatek/mt76/wed.c
index fbd7e59c73aaf..2ebf4edc689e9 100644
--- a/drivers/net/wireless/mediatek/mt76/wed.c
+++ b/drivers/net/wireless/mediatek/mt76/wed.c
@@ -33,10 +33,15 @@ u32 mt76_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
 {
 	struct mtk_wed_bm_desc *desc = wed->rx_buf_ring.desc;
 	struct mt76_dev *dev = mt76_wed_to_dev(wed);
-	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
 	struct mt76_txwi_cache *t = NULL;
+	struct mt76_queue *q;
 	int i;
 
+	if (wed->version == 2 && dev->phy.band_idx)
+		q = &dev->q_rx[MT_RXQ_BAND1];
+	else
+		q = &dev->q_rx[MT_RXQ_MAIN];
+
 	for (i = 0; i < size; i++) {
 		dma_addr_t addr;
 		u32 offset;
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18-6.12] wifi: rtw89: wow: add QoS control field to WoWLAN ARP response for MLO
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (9 preceding siblings ...)
  2026-10-19 13:46 ` [PATCH AUTOSEL 6.18] wifi: mt76: wed: fix kernel panic on non-DBDC MT7986 Sasha Levin
@ 2026-10-19 13:47 ` Sasha Levin
  2026-10-19 13:47 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: mld: validate D3_END notif size Sasha Levin
                   ` (29 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:47 UTC (permalink / raw)
  To: patches, stable
  Cc: Chin-Yen Lee, Ping-Ke Shih, Sasha Levin, linux-wireless,
	linux-kernel

From: Chin-Yen Lee <timlee@realtek.com>

[ Upstream commit 03a963f4aeda538acad50806e94ef25d95b78743 ]

Some MLO APs expect WoWLAN ARP response frames to be transmitted as
QoS data frames and may discard frames that do not contain a QoS
Control field.

Add a QoS Control field and use the QoS Data subtype when generating
WoWLAN ARP responses for MLD vifs. Keep the existing frame format
unchanged for non-MLO connections.

This allows WoWLAN ARP responses to be accepted by MLO APs while
preserving compatibility with legacy APs.

Signed-off-by: Chin-Yen Lee <timlee@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260625061545.44808-10-pkshih@realtek.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## Phase 1: Commit message forensics

**Step 1.1: Subject line**
Record: **[wifi: rtw89: wow:] [add] [QoS Control field on WoWLAN ARP
responses for MLO]**
Subsystem is Realtek rtw89 WoWLAN. The verb is “add”, but the body is
interoperability: MLO APs drop ARP frames that are not QoS Data.

**Step 1.2: Tags**
Record:
- Signed-off-by: Chin-Yen Lee \<timlee@realtek.com\> (author)
- Signed-off-by: Ping-Ke Shih \<pkshih@realtek.com\> (rtw89 maintainer)
- Link:
  https://patch.msgid.link/20260625061545.44808-10-pkshih@realtek.com
  (msgid `…44808-10…` → patch 09/10 of a 10-patch `rtw-next` series;
  1-based msgid index)
- No Fixes:, Reported-by:, Tested-by:, Reviewed-by:, Acked-by:, or Cc:
  stable (absence is expected here)
- Ignore pipeline SOBs such as Sasha Levin (none on the real commit)

**Step 1.3: Body**
Record:
- **Bug:** Some MLO APs require WoWLAN ARP responses as QoS Data and
  discard frames without a QoS Control field.
- **Symptom:** ARP keep-alive / ARP offload during WoWLAN is ignored →
  AP can drop the STA while suspend/WoWLAN is active.
- **Root cause:** `rtw89_arp_response_get()` always built a non-QoS Data
  3-address frame.
- **Fix:** For MLD vifs, set `IEEE80211_STYPE_QOS_DATA` and insert a
  2-byte QoS Control field; leave non-MLO frames unchanged.
- **Versions:** none named in the message.

**Step 1.4: Hidden bug fix?**
Record: Yes. “Add QoS control field” is a protocol-format fix for an
existing WoWLAN ARP template, not a new userspace API. Cover letter
language (“support WoWLAN with MLO AP”) is feature-ish, but the driver
already had MLO WoWLAN and ARP offload/keep-alive; this corrects the
template those paths upload.

---

## Phase 2: Diff analysis

**Step 2.1: Inventory**
Record:
- File: `drivers/net/wireless/realtek/rtw89/fw.c` (+24 / −7; `git show
  --stat` matches)
- Function: `rtw89_arp_response_get()` only
- Scope: single-file, single-function, surgical

**Step 2.2: Control flow**
Record (before → after):
- Allocate skb sized for 3-addr header + security header + ARP body →
  also reserve 2 bytes when `ieee80211_vif_is_mld(vif)`.
- Frame control: Data+ToDS (+Protected if PTK) → same, plus QoS Data
  subtype for MLO, Data subtype for legacy.
- Always `skb_put_zero(sec_hdr_len)` → insert QoS Control (zeros) before
  IV if MLO; skip security bytes when `sec_hdr_len == 0` (equivalent to
  `skb_put_zero(0)`).
- Debug print via `str_yes_no(with_qos)`.

802.11 order is correct: 3-addr MAC header, QoS Control, IV, LLC+ARP.
QoS Control of 0 is TID 0 / normal ACK, which is appropriate for ARP.

**Step 2.3: Bug mechanism**
Record: **Logic / protocol correctness + hardware interoperability.**
MLO (802.11be) APs expect QoS Data; non-QoS keep-alive/offload templates
are discarded. Not UAF, leak, race, or NULL deref.

**Step 2.4: Fix quality**
Record: Obviously correct and minimal. Non-MLO path is unchanged in
substance (`IEEE80211_STYPE_DATA` is 0). Regression risk is low and
confined to MLO WoWLAN ARP: a wrong QoS field could still be dropped,
but zeroed QoS Control is the standard default. No public API or struct
layout change.

---

## Phase 3: Git history

**Step 3.1: Blame**
Record:
- Function introduced in `58ed86e1666b3` (“wifi: rtw89: wow: add ARP
  offload feature”, 2024-05-02) — contained in `v6.11-rc1` era (`git
  describe --contains` → `x86_boot_for_v6.11_rc1~…`).
- Link-aware `rtwvif_link` args: `2f7dae17c48cd1` (2024-09).
- Security header: `0065199f4303bc` (2024-06).
- Keep-alive uses this template: `dcf5c7262bffa` (2026-05-25, in
  **v7.2-rc1**).
- MLD MAC in ARP: parent `76edcedda6437` (same series 08/10).
- This commit: `03a963f4aeda5`, **contained in v7.3-rc1**.

**Step 3.2: Fixes: tag**
Record: None. Buggy behavior is the original ARP template never emitting
QoS Data for MLD vifs after MLO WoWLAN existed.

**Step 3.3: Related file history**
Record: Same-day series (msgid `20260625061545.44808-*`):
1. MAC finish active TX
2. pass chip version to FW
3. lower UDM1 debug level
4. drop pkt offload on H2C failure
5. disable sniffer RX filter (Wi-Fi 7)
6. PCI phy error / refclk
7. LPS MLO link ID fix
8. **MLD address in WoWLAN ARP** (parent)
9. **this patch**
10. RF init only on Wi-Fi 6 in WoW

This patch does not call or require patches 1–8/10. 08/10 only changes
ARP hw addresses; 09/10 only changes frame control + QoS bytes.
Standalone at the code level.

**Step 3.4: Author**
Record: Chin-Yen Lee (Realtek); maintainer Ping-Ke Shih signed off and
applied the whole series to `rtw-next`. Nearby author work is other
rtw89 WoWLAN/MLO fixes.

**Step 3.5: Prerequisites in this tree**
Record: Present here:
- `rtwvif_to_vif()` in `core.h`
- `ieee80211_vif_is_mld()` in `include/net/mac80211.h`
- `str_yes_no()` in `include/linux/string_choices.h`
- ARP offload + keep-alive both call `rtw89_fw_h2c_add_general_pkt(…,
  RTW89_PKT_OFLD_TYPE_ARP_RSP, …)`
Can apply standalone on this tree.

---

## Phase 4: Mailing list / external

**Step 4.1: b4 dig**
Record:
- Lore/msgid:
  https://patch.msgid.link/20260625061545.44808-10-pkshih@realtek.com
- Subject: `[PATCH rtw-next 09/10] wifi: rtw89: wow: add QoS control
  field to WoWLAN ARP response for MLO`
- Series: v1 only (`b4 dig -a`); no v2/v3.
- Cover letter (`00/10`): “update some MAC, FW and WoWLAN settings”;
  “The last three patches are related to WoWLAN, and the first two are
  to support WoWLAN with MLO AP that uses MLD address.”
- Only reply in the saved mbox: Ping-Ke applying all 10 to `rtw-next`
  (no NAK, no reviewer comments on 09/10).
- No Cc: stable in the thread.

**Step 4.2: Recipients (`b4 dig -w`)**
Record: Ping-Ke Shih, linux-wireless, gary.chang@realtek.com,
timlee@realtek.com, dian_syuan0116@realtek.com, kevin_yang@realtek.com.
Maintainer was To/Cc and applied it. No external review tags.

**Step 4.3: Bug report**
Record: No Reported-by, bugzilla, or syzbot. Vendor-described AP
behavior only. Specific AP models for *this* QoS issue are not named
(keep-alive predecessor named TP-Link Archer BE800).

**Step 4.4: Series**
Record: Mixed MAC/FW/WoW settings. 09/10 is self-contained; 08/10 is a
related but independent MLO ARP address fix.

**Step 4.5: stable@**
Record: **UNVERIFIED** (lore.kernel.org/stable blocked by Anubis).
Thread mbox has no stable discussion.

WebFetch of lore/msgid also returned 403; discussion was recovered via
`b4 dig -m`.

---

## Phase 5: Semantic / call graph

**Step 5.1: Functions**
Record: `rtw89_arp_response_get()` only.

**Step 5.2: Callers**
Record:
- `rtw89_fw_h2c_add_general_pkt()` → `RTW89_PKT_OFLD_TYPE_ARP_RSP`
- `rtw89_fw_h2c_keep_alive()` (WoW keep-alive enable)
- `rtw89_fw_h2c_arp_offload()` (WoW ARP offload enable)
- `rtw89_wow_fw_start()` in `wow.c` enables both when the interface is
  linked

Path is WoWLAN firmware start on suspend (`CONFIG_PM`), not a syscall
hot path.

**Step 5.3: Callees**
Record: `rtwvif_to_vif`, `ieee80211_vif_is_mld`,
`rtw89_wow_get_sec_hdr_len`, `dev_alloc_skb`, `skb_put_zero`,
`cpu_to_le16`, `ether_addr_copy`, `str_yes_no` (debug only).

**Step 5.4: Reachability**
Record: Userspace-reachable via suspend with WoWLAN on an rtw89 STA
associated as an MLD. Not unprivileged kernel-memory corruption; it is a
normal power-management / offload path.

**Step 5.5: Similar patterns**
Record: `rtw89_sa_query_get()` still builds a non-QoS mgmt action frame
(correct for SA Query). No sibling ARP builders. Keep-alive commit
`dcf5c7262bffa` is the same interoperability class (APs ignoring Null
keep-alives).

---

## Phase 6: This checkout

**Step 6.1: Local tree and whether the bug exists**
Record:
- `git describe HEAD`: **v7.3-rc4-27-gf0100363d8c37**
- `make kernelversion`: **7.3.0-rc4**
- `rtw89_arp_response_get()` exists; MLO (`ieee80211_vif_is_mld`), WoW
  keep-alive, and ARP offload all exist.
- Without this change, MLO ARP templates are non-QoS Data. That is the
  bug this tree’s rtw89 WoW+MLO users hit.
- Commit `03a963f4aeda5` is an ancestor of HEAD (`git merge-base --is-
  ancestor` → yes) because it landed in **v7.3-rc1**. That is not used
  as “already selected for stable”; it only confirms the code and
  helpers are in this series.

**Step 6.2: Backport difficulty**
Record: Clean apply on this tree (hunk matches current `fw.c`). No
refactor blocking it.

**Step 6.3: Other fixes here**
Record: No later follow-up rewriting this QoS logic (`git log` after the
commit on this function is unrelated fw/coex/scan work). Parent MLD-
address fix is already here and independent.

---

## Phase 7: Subsystem context

**Step 7.1**
Record: **drivers/net/wireless/realtek/rtw89** — important (common Wi-Fi
6/7 laptops), not core mm/fs. WoWLAN is `CONFIG_PM`.

**Step 7.2**
Record: Very active (frequent coex/MLO/WoW commits). This is a late
correction to existing MLO WoW, not a brand-new subsystem.

---

## Phase 8: Impact and risk

**Step 8.1: Who**
Record: Driver-specific + config-specific: rtw89, MLO association,
WoWLAN/suspend. Not universal.

**Step 8.2: Trigger**
Record: Suspend with WoWLAN while associated to an MLO AP that rejects
non-QoS Data. Common for Wi-Fi 7 + lid-close. Unprivileged in the sense
of normal laptop suspend, not an exploit primitive.

**Step 8.3: Failure mode**
Record: AP discards keep-alive and/or ARP offload → association can drop
in suspend. **Severity: MEDIUM** (connectivity / suspend Wi-Fi, not
oops/corruption). Matches stable-rules “hardware quirk” / “oh, that’s
not good”, not crash/UAF.

**Step 8.4: Risk–benefit**
Record:
- Benefit: MLO WoWLAN keep-alive and ARP offload actually accepted;
  avoids silent disconnect on suspend for Wi-Fi 7 rtw89.
- Risk: ~24 lines, MLO-only, no locking/API. Low.
- Ratio: favorable for this tree, which already has MLO WoW + ARP
  templates.

---

## Phase 9: Synthesis

**Step 9.1: Evidence**

For:
- Real interoperability bug on an existing path (WoW ARP template), not
  a new driver or API.
- This 7.3 tree has MLO, `rtw89_arp_response_get()`, keep-alive, and ARP
  offload.
- Small, obviously correct, non-MLO behavior preserved.
- Maintainer SOB + applied to rtw.git.
- Official stable rules allow hardware quirks and “oh, that’s not good”
  issues; this is AP-side discard of malformed/non-QoS MLO data.
- Suspend/WoWLAN disconnect is user-visible on shipping Realtek Wi-Fi 7
  hardware.

Against:
- Not oops/deadlock/corruption/security.
- `rtw-next` series titled “update some MAC, FW and WoWLAN settings”;
  cover letter says “support WoWLAN with MLO AP”.
- No external reporters, Tested-by, or Fixes: tag.
- Affects only MLO + WoWLAN.

Unresolved:
- Stable-list history (lore bot wall).
- Which exact APs need QoS (commit says “some MLO APs”).

**Step 9.2: Stable rules checklist** (`Documentation/process/stable-
kernel-rules.rst`)
1. Obviously correct and tested? **PASS** — vendor + maintainer, tiny,
   protocol order verified in tree.
2. Real bug that bothers users? **PASS** — WoWLAN ARP ignored, possible
   disconnect in suspend on MLO.
3. Important (crash/security/corruption/deadlock **or** quirk / “oh
   that’s not good”)? **PASS** — quirk / connectivity, not CRITICAL
   crash.
4. Small and contained? **PASS** — one function, well under 100 lines.
5. No new features/APIs? **PASS** — frame format fix for existing
   offload, no new uAPI.
6. Applies to this tree? **PASS** — helpers and callers exist; hunk
   matches `fw.c`.

**Step 9.3: Exception category**
Record: Hardware/protocol quirk (MLO APs dropping non-QoS WoW ARP),
analogous to other driver workarounds. Not a device-ID one-liner, but
the same class.

**Step 9.4: Decision**
This tree is **7.3.0-rc4**. rtw89 already implements MLO WoWLAN and
uploads ARP templates for keep-alive and ARP offload. Sending those as
non-QoS Data is wrong for MLO APs and can drop the link in suspend. The
patch is a small, MLO-only frame-format fix with low regression risk and
no extra series dependencies. That is appropriate to have in this tree’s
stable line.

### What it solves for users of this tree
WoWLAN keep-alive and ARP offload on rtw89 MLD vifs were built as
ordinary Data frames. Some MLO APs drop those, so the AP may age out the
STA during suspend. Adding QoS Control + QoS Data subtype makes those
firmware-transmitted frames acceptable while leaving legacy associations
unchanged.

### Risk vs benefit
Benefit is restoring Wi-Fi 7 WoWLAN connectivity on Realtek rtw89. Risk
is a 2-byte header on the MLO path only. Non-MLO frame control stays
Data+ToDS.

### Concerns
Cover letter frames this as MLO WoW “support” in a mixed `rtw-next`
series, and there is no public reproducer. On this 7.3 tree those
features already exist, so this is a contained correctness fix, not a
new subsystem.

---

Verification:
- [Phase 1] Parsed subject/tags/body from `git log -1 --format=fuller
  03a963f4aeda5`; msgid is 09/10 of `20260625061545.44808`.
- [Phase 2] Diff vs current `fw.c` `rtw89_arp_response_get()`; +24/−7 in
  one function; QoS inserted after 3-addr header, before IV.
- [Phase 3] `git merge-base --is-ancestor 03a963f4aeda5 HEAD` → yes;
  `git describe --contains` → `v7.3-rc1~…`; blame shows intro
  `58ed86e1666b3`; parent `76edcedda6437` is address-only.
- [Phase 3] `git log --oneline --grep=20260625061545.44808 --
  drivers/net/wireless/realtek/rtw89/` listed all 10 series commits.
- [Phase 4] `b4 dig -c/-a/-w/-m`: v1 `rtw-next` 10-patch series; applied
  by Ping-Ke; no NAK; no stable Cc. WebFetch lore 403; curl stable list
  Anubis-blocked.
- [Phase 5] Grep: ARP_RSP used from keep-alive and ARP offload;
  `rtw89_wow_fw_start()` enables both.
- [Phase 6] `git describe HEAD` = v7.3-rc4-27-g…; `VERSION/PATCHLEVEL`
  7.3.0-rc4; MLO/WoW/ARP code present.
- [Phase 7] rtw89 Wi-Fi 6/7 driver, active history on `fw.c`.
- [Phase 8] Failure mode: AP drops WoW ARP → disconnect in suspend; not
  a kernel oops.
- [Phase 9] Checked `Documentation/process/stable-kernel-rules.rst`
  (quirk / “oh that’s not good”, ≤100 lines).
- UNVERIFIED: lore.kernel.org/stable archives (bot challenge).
- UNVERIFIED: exact AP models for the QoS requirement (not named in
  commit or mbox).

**YES**

 drivers/net/wireless/realtek/rtw89/fw.c | 31 +++++++++++++++++++------
 1 file changed, 24 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index c6533a085c7fe..299526220380f 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -2701,6 +2701,7 @@ static struct sk_buff *rtw89_sa_query_get(struct rtw89_dev *rtwdev,
 static struct sk_buff *rtw89_arp_response_get(struct rtw89_dev *rtwdev,
 					      struct rtw89_vif_link *rtwvif_link)
 {
+	struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link->rtwvif);
 	struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
 	u8 sec_hdr_len = rtw89_wow_get_sec_hdr_len(rtwdev);
 	struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
@@ -2708,26 +2709,42 @@ static struct sk_buff *rtw89_arp_response_get(struct rtw89_dev *rtwdev,
 	struct rtw89_arp_rsp *arp_skb;
 	struct arphdr *arp_hdr;
 	struct sk_buff *skb;
-	__le16 fc;
+	bool with_qos;
+	u16 fc;
 
-	skb = dev_alloc_skb(sizeof(*hdr) + sec_hdr_len + sizeof(*arp_skb));
+	with_qos = ieee80211_vif_is_mld(vif);
+
+	rtw89_debug(rtwdev, RTW89_DBG_WOW, "[arp_reply] with qos field: %s\n",
+		    str_yes_no(with_qos));
+
+	skb = dev_alloc_skb(sizeof(*hdr) + sec_hdr_len + sizeof(*arp_skb) +
+			    (with_qos ? 2 : 0));
 	if (!skb)
 		return NULL;
 
 	hdr = skb_put_zero(skb, sizeof(*hdr));
 
+	fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS;
+
 	if (rtw_wow->ptk_alg)
-		fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS |
-				 IEEE80211_FCTL_PROTECTED);
+		fc |= IEEE80211_FCTL_PROTECTED;
+
+	if (with_qos)
+		fc |= IEEE80211_STYPE_QOS_DATA;
 	else
-		fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS);
+		fc |= IEEE80211_STYPE_DATA;
+
+	hdr->frame_control = cpu_to_le16(fc);
 
-	hdr->frame_control = fc;
 	ether_addr_copy(hdr->addr1, rtwvif_link->bssid);
 	ether_addr_copy(hdr->addr2, rtwvif_link->mac_addr);
 	ether_addr_copy(hdr->addr3, rtwvif_link->bssid);
 
-	skb_put_zero(skb, sec_hdr_len);
+	if (with_qos)
+		skb_put_zero(skb, sizeof(__le16));
+
+	if (sec_hdr_len)
+		skb_put_zero(skb, sec_hdr_len);
 
 	arp_skb = skb_put_zero(skb, sizeof(*arp_skb));
 	memcpy(arp_skb->llc_hdr, rfc1042_header, sizeof(rfc1042_header));
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18] wifi: iwlwifi: mld: validate D3_END notif size
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (10 preceding siblings ...)
  2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-6.12] wifi: rtw89: wow: add QoS control field to WoWLAN ARP response for MLO Sasha Levin
@ 2026-10-19 13:47 ` Sasha Levin
  2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-5.15] wifi: mt76: mt7603: free beacon SKB on error Sasha Levin
                   ` (28 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:47 UTC (permalink / raw)
  To: patches, stable
  Cc: Emmanuel Grumbach, Miri Korenblit, Sasha Levin, linux-wireless,
	linux-kernel

From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>

[ Upstream commit 4e777dcdfe70d9b3ddf38cb49de9e30306889b18 ]

Check D3_END_NOTIFICATION payload length before reading notif->flags.
On short payloads, mark notif handling as failed.
Avoid out-of-bounds reads from malformed notifications.

Assisted-by: GitHubCopilot:gpt-5.3-codex
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Link: https://patch.msgid.link/20260714165826.db2df8b6b6bb.I6163bbdf433379bf1dbf9eb46fb9562892217bd7@changeid
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

Local tree is **Linux 7.3.0-rc4** (`v7.3-rc4-27-gf0100363d8c37`). The
iwlwifi MLD D3 resume path is present here, and this is a small bounds
check that stops an out-of-bounds read of firmware notification data.

## Phase 1: Commit message forensics

**Step 1.1 — Subject**
Record: **[iwlwifi/mld]** **[validate]** Check `D3_END_NOTIFICATION`
payload size before reading `notif->flags`.

**Step 1.2 — Tags**
Record:
- `Assisted-by: GitHubCopilot:gpt-5.3-codex`
- `Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>`
  (author)
- `Link: https://patch.msgid.link/20260714165826.db2df8b6b6bb.I6163bbdf4
  33379bf1dbf9eb46fb9562892217bd7@changeid`
- `Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>`
  (iwlwifi maintainer)
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Cc:
  stable` (absence of Fixes/Cc-stable is expected for this review)
- Sasha Levin SOB ignored per pipeline rules

**Step 1.3 — Body**
Record: Firmware `D3_END_NOTIFICATION` payload length is not checked
before `le32_to_cpu(notif->flags)`. A short payload is an out-of-bounds
read. On failure, handling is marked failed (`notif_handling_err`).
Symptom: OOB read of firmware RX data during D3/WoWLAN resume. No stack
trace, reproducer, or version range in the message. Root cause: missing
length check vs `sizeof(struct iwl_d3_end_notif)`.

**Step 1.4 — Hidden bug fix?**
Record: Not hidden. The subject/body state a bounds check to avoid OOB
reads. Copilot assistance does not change that.

## Phase 2: Diff analysis

**Step 2.1 — Inventory**
Record:
- File: `drivers/net/wireless/intel/iwlwifi/mld/d3.c` (+9 / −1)
- Function: `iwl_mld_handle_d3_notif()`
- Scope: single-file, one `switch` case (`WIDE_ID(PROT_OFFLOAD_GROUP,
  D3_END_NOTIFICATION)`)

**Step 2.2 — Control flow**
Record: Before, the handler always did `resume_data->d3_end_flags =
le32_to_cpu(notif->flags)` from `pkt->data` with no length check, then
set `IWL_D3_NOTIF_D3_END_NOTIF`. After, it computes `len =
iwl_rx_packet_payload_len(pkt)` and uses `IWL_FW_CHECK(mld, len <
sizeof(*notif), ...)`. Short payload: log, set `notif_handling_err =
true`, skip the flags read. Valid payload: same flags assignment as
before. In both cases it still sets `IWL_D3_NOTIF_D3_END_NOTIF` so the
wait completes. Error path only for truncated firmware notifications.

**Step 2.3 — Bug mechanism**
Record: **Memory safety / out-of-bounds read.** `struct
iwl_d3_end_notif` is a packed `__le32 flags` (4 bytes). Reading
`notif->flags` when `payload_len < 4` reads past the declared RX
payload. Same class of check already used in `mvm/d3.c`.

**Step 2.4 — Fix quality**
Record: Obviously correct: compare payload length to `sizeof(*notif)`
before dereference, using existing `IWL_FW_CHECK` /
`iwl_rx_packet_payload_len`. Surgical, no API change. Regression risk is
low: valid 4-byte notifications behave as before. Truncated ones fail
resume with `-EIO` via `notif_handling_err` instead of using garbage
`d3_end_flags` (which can spuriously set or miss
`IWL_D0I3_RESET_REQUIRE`). The API struct always includes `flags`; MVM
already rejects short D3_END payloads, so empty notifications are not a
valid firmware contract.

## Phase 3: Git history

**Step 3.1 — Blame**
Record: Unchecked `notif->flags` read was introduced with
`d1e879ec600f9` (`wifi: iwlwifi: add iwlmld sub-driver`, 2025-02-16).
`git describe --tags d1e879ec600f9` → `v6.14-rc4-1062-gd1e879ec600f9`
(iwlmld landed for ~6.15). The bug has been in this driver since it was
added.

**Step 3.2 — Fixes: tag**
Record: No `Fixes:` tag. Introducing commit is `d1e879ec600f9`, which
**is** an ancestor of this tree (`git merge-base --is-ancestor`
succeeded).

**Step 3.3 — Related file history**
Record: Same-day MVM sibling `c1a1dc162870a` (`wifi: iwlwifi: mvm: d3:
validate D3 resume notification payloads`) documents “buffer underread
on malformed or truncated notifications.” Later MLD D3 checks (`validate
WoWLAN notif header`, wake-packet reads) are independent siblings, not
prerequisites. Follow-up `4f5384b58b483` disconnects on D3 resume
failure; this patch does not depend on it.

**Step 3.4 — Author**
Record: Emmanuel Grumbach is a long-time iwlwifi developer. Applied by
maintainer Miri Korenblit. Same author wrote the MVM D3 payload
validation.

**Step 3.5 — Dependencies**
Record: Standalone. Uses existing `iwl_rx_packet_payload_len` (`iwl-
trans.h`), `IWL_FW_CHECK` (`fw/dbg.h`, included by `d3.c`; macro since
`568db7fd27fad` / ~v6.5), `notif_handling_err`, and `struct
iwl_d3_end_notif`. No new helpers. It was **09/15** in an iwlwifi-next
bundle of mixed fixes/features; this hunk has no code dependency on the
other 14 patches.

## Phase 4: Mailing list / external research

**Step 4.1 — Original discussion**
Record: `b4 dig -c 4e777dcdfe70d` → https://patch.msgid.link/20260714165
826.db2df8b6b6bb.I6163bbdf433379bf1dbf9eb46fb9562892217bd7@changeid
`b4 dig -a`: v1 and **v2**; applied version is **v2** `[PATCH v2
iwlwifi-next 09/15]`. Cover letter: “Usual fixed, cleanups and features
from our internal tree.” v2 only resends after `iwlwifi-next` contained
an unrelated compile-time hcmd-size check. No NAK, no reviewer concern,
no `Cc: stable` on this patch. Direct lore.kernel.org fetch returned
**403**; thread recovered via `b4 dig -m`.

**Step 4.2 — Recipients (`b4 dig -w`)**
Record: To Johannes Berg (`johannes@sipsolutions.net`); Cc `linux-
wireless@vger.kernel.org`, Emmanuel Grumbach. Correct wireless/iwlwifi
audience. This patch itself has no extra `Reviewed-by` (unlike some
series mates). Maintainer SOB is present.

**Step 4.3 — Bug report**
Record: No `Reported-by`, syzbot, or bugzilla. Firmware-malformed-
notification hardening, not a user crash report.

**Step 4.4 — Series**
Record: 15-patch iwlwifi-next dump. This patch is an isolated length
check in one case of `iwl_mld_handle_d3_notif`. Other patches add device
IDs, LARI v14, TCM removal, etc. Not a multi-step refactor of this
function.

**Step 4.5 — Stable list**
Record: lore.kernel.org/stable WebFetch returned **403**. No stable
discussion in the saved mbox. **UNVERIFIED:** whether anyone already
nominated this on stable@.

## Phase 5: Code semantic analysis

**Step 5.1 — Functions**
Record: `iwl_mld_handle_d3_notif()` only.

**Step 5.2 — Callers**
Record: Registered as the notification-wait callback from
`iwl_mld_wait_d3_notif()`, itself called by:
- `iwl_mld_no_wowlan_resume()` → `iwl_mld_mac80211_start()` when
  `fw_status.in_d3` (`mac80211.c`)
- `iwl_mld_wowlan_resume()` → `iwl_mld_resume()` mac80211 resume op

Context: process context, suspend/resume, `CONFIG_PM_SLEEP`
(`mld/Makefile`: `iwlmld-$(CONFIG_PM_SLEEP) += d3.o`).

**Step 5.3 — Callees**
Record: `iwl_rx_packet_payload_len()`, `IWL_FW_CHECK` → `IWL_ERR_LIMIT`,
`le32_to_cpu()`. No allocation, no new locks.

**Step 5.4 — Reachability**
Record: Yes, from userspace via suspend/resume (S3/WoWLAN) on Intel Wi-
Fi 7 / MLD (`CONFIG_IWLMLD`). Unprivileged users typically cannot inject
firmware RX payloads; trigger is firmware (or a compromised device).
Still a real kernel OOB if firmware truncates the notif.

**Step 5.5 — Similar patterns**
Record: MVM `iwl_mvm_wait_d3_notif` already checks `len <
sizeof(*notif)` before `notif->flags`. Other iwlwifi handlers use
`IWL_FW_CHECK(..., pkt_len < sizeof(...))`. This closes a gap in the
newer MLD copy of D3 resume.

## Phase 6: Local tree (7.3.0-rc4)

**Step 6.1 — Buggy code here?**
Record: Yes. `drivers/net/wireless/intel/iwlwifi/mld/d3.c` exists;
`iwl_mld_handle_d3_notif` handles `D3_END_NOTIFICATION`. Pre-patch
parent shows the unguarded `le32_to_cpu(notif->flags)`. Bug introduced
with iwlmld (`d1e879ec600f9`), ancestor of HEAD.

**Step 6.2 — Backport difficulty**
Record: Clean apply. Surrounding case statement matches the candidate
diff. `IWL_FW_CHECK` and `notif_handling_err` are already in this tree.

**Step 6.3 — Related fixes already here?**
Record: No earlier MLD D3_END size check. MVM has its own check
(`c1a1dc162870a`); that does not cover MLD.

## Phase 7: Subsystem / maintainer

**Step 7.1**
Record: **iwlwifi MLD** (`drivers/net/wireless/intel/iwlwifi/mld/`).
**IMPORTANT** (not core mm/fs, but a widely used Intel Wi-Fi driver on
current hardware). D3.c is only built with `CONFIG_PM_SLEEP`.

**Step 7.2**
Record: Active (frequent iwlwifi-next dumps). D3_END handling itself has
been stable since the sub-driver was added.

## Phase 8: Impact and risk

**Step 8.1 — Who is affected**
Record: Users of Intel Wi-Fi MLD (`CONFIG_IWLMLD`) who suspend/resume or
use WoWLAN. Driver- and config-specific, not universal.

**Step 8.2 — Trigger**
Record: D3 resume when firmware delivers `D3_END_NOTIFICATION` with
payload &lt; 4 bytes. Uncommon if firmware is healthy; realistic on
firmware bugs. Not a normal userspace syscall; firmware-sourced.

**Step 8.3 — Failure mode**
Record: Out-of-bounds read of RX buffer / declared payload. Can be KASAN
OOB, garbage `d3_end_flags` (wrong reset-on-resume), or a crash if the
buffer is tightly sized. **Severity: HIGH** (OOB; resume correctness).
Not a guaranteed panic on every resume.

**Step 8.4 — Risk vs benefit**
Record: **Benefit: high** for MLD laptop suspend/resume — prevents OOB
and acting on garbage reset flags. **Risk: very low** — 9 lines, error
path only, same pattern as MVM. Ratio favors backport.

## Phase 9: Synthesis

**Step 9.1 — Evidence**

For:
- Real OOB read of firmware notification payload
- Small, obviously correct check (`len < sizeof(*notif)`)
- Matches established iwlwifi/`IWL_FW_CHECK` and MVM D3 handler
- D3/WoWLAN resume is a common path on laptops
- Garbage flags can mis-handle `IWL_D0I3_RESET_REQUIRE`
- Maintainer-applied; Johannes/linux-wireless were CCed
- Applies cleanly; no prerequisites missing in 7.3-rc4
- iwlmld and the buggy handler exist in this tree

Against:
- No user/syzbot report; Copilot-assisted
- Trigger needs truncated firmware, not a normal station
- Mixed 15-patch “updates” series, not explicitly Cc: stable
- No extra `Reviewed-by` on this patch

Unresolved:
- lore.kernel.org HTTP 403; stable@ search not confirmed beyond the mbox

**Step 9.2 — Stable rules**
1. Obviously correct and tested? **PASS** — length check before
   dereference; applied to iwlwifi-next by the maintainer.
2. Real bug affecting users? **PASS** — OOB on truncated D3_END; MLD D3
   resume is a real path.
3. Important (crash/security/corruption/deadlock)? **PASS** — OOB read /
   possible bad resume flags; HIGH, not theoretical style-only.
4. Small and contained? **PASS** — +9/−1, one function, one case.
5. No new features/APIs? **PASS**.
6. Can apply to this tree? **PASS** — files, macros, and structures
   exist.

**Step 9.3 — Exceptions**
Record: Not a device-ID/quirk/DT/build/docs exception. It is a
straightforward memory-safety fix.

**Step 9.4 — Decision**
This tree is 7.3-rc4 and contains iwlmld D3 resume. The patch is a
9-line firmware notification bounds check that stops an OOB read and
avoids using garbage `d3_end_flags`. It meets stable criteria for this
checkout.

### What it solves for this tree
On Intel MLD Wi-Fi, D3/WoWLAN resume handled `D3_END_NOTIFICATION` by
reading a 4-byte `flags` field without checking payload length. A short
firmware notification reads past valid RX data and can drive wrong
reset-on-resume behavior. The fix logs via `IWL_FW_CHECK`, sets
`notif_handling_err` (resume returns `-EIO`), and only then skips the
flags read.

### Risk vs benefit
Benefit is preventing OOB and incorrect D3 resume on `CONFIG_IWLMLD` +
`CONFIG_PM_SLEEP`. Risk is negligible: valid notifications are
unchanged.

## Verification
- [Phase 1] Parsed tags: author Grumbach, maintainer Korenblit SOB,
  msgid.link; no Fixes/Reported-by/Cc-stable
- [Phase 2] Diff: +9/−1 in `iwl_mld_handle_d3_notif` D3_END case; length
  check then optional `le32_to_cpu(notif->flags)`
- [Phase 2] `struct iwl_d3_end_notif` is `__le32 flags` only
  (`fw/api/d3.h`)
- [Phase 2] `IWL_FW_CHECK` defined in `fw/dbg.h`; included from
  `mld/d3.c`
- [Phase 2] `notif_handling_err` forces `ret = -EIO` in
  `iwl_mld_wait_d3_notif`
- [Phase 2] `d3_end_flags & IWL_D0I3_RESET_REQUIRE` used in no-wowlan
  and wowlan resume
- [Phase 3] `git describe HEAD` / `make kernelversion`: **7.3.0-rc4**
- [Phase 3] Blame: unguarded read from `d1e879ec600f9` (iwlmld add,
  ~v6.15)
- [Phase 3] `git merge-base --is-ancestor d1e879ec600f9 HEAD`: yes
- [Phase 3] Pre-patch: `git show 4e777dcdfe70d^:.../mld/d3.c` shows
  unguarded flags read
- [Phase 3] MVM sibling `c1a1dc162870a` same-day D3 payload validation
- [Phase 3] `IWL_FW_CHECK` from `568db7fd27fad` (~v6.5)
- [Phase 4] `b4 dig -c/-a/-w/-m`: v2 09/15, linux-wireless + Johannes;
  no NAK in mbox
- [Phase 4] Cover letter: mixed iwlwifi-next updates; this patch listed
  under Grumbach fixes
- [Phase 4] UNVERIFIED: lore.kernel.org and stable@ HTTP 403
- [Phase 5] Callers: `iwl_mld_no_wowlan_resume` /
  `iwl_mld_wowlan_resume` from mac80211 start/resume
- [Phase 5] `mld/Makefile`: `d3.o` only with `CONFIG_PM_SLEEP`;
  `CONFIG_IWLMLD`
- [Phase 6] Buggy handler present; apply would be clean
- [Phase 8] Failure mode: OOB read of D3_END payload / garbage reset
  flags, severity HIGH

**YES**

 drivers/net/wireless/intel/iwlwifi/mld/d3.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/d3.c b/drivers/net/wireless/intel/iwlwifi/mld/d3.c
index 0cb7bfcd6420e..73fd4c69357ca 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/d3.c
@@ -1326,8 +1326,16 @@ static bool iwl_mld_handle_d3_notif(struct iwl_notif_wait_data *notif_wait,
 	}
 	case WIDE_ID(PROT_OFFLOAD_GROUP, D3_END_NOTIFICATION): {
 		struct iwl_d3_end_notif *notif = (void *)pkt->data;
+		u32 len = iwl_rx_packet_payload_len(pkt);
+
+		if (IWL_FW_CHECK(mld, len < sizeof(*notif),
+				 "Invalid D3_END notification (expected=%zu got=%u)\n",
+				 sizeof(*notif), len)) {
+			resume_data->notif_handling_err = true;
+		} else {
+			resume_data->d3_end_flags = le32_to_cpu(notif->flags);
+		}
 
-		resume_data->d3_end_flags = le32_to_cpu(notif->flags);
 		resume_data->notifs_received |= IWL_D3_NOTIF_D3_END_NOTIF;
 		break;
 	}
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18-5.15] wifi: mt76: mt7603: free beacon SKB on error
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (11 preceding siblings ...)
  2026-10-19 13:47 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: mld: validate D3_END notif size Sasha Levin
@ 2026-10-19 13:47 ` Sasha Levin
  2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7915: configure noise floor reporting on reset Sasha Levin
                   ` (27 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:47 UTC (permalink / raw)
  To: patches, stable
  Cc: David Bauer, Felix Fietkau, Sasha Levin, lorenzo, ryder.lee,
	matthias.bgg, angelogioacchino.delregno, linux-wireless,
	linux-kernel, linux-arm-kernel, linux-mediatek

From: David Bauer <mail@david-bauer.net>

[ Upstream commit 965cbdbdfbd37a659a05ff88e49c216975bd9d2e ]

The SKB containing the generated beacon is not freed when the beacon
queue is deected stuck and scheduled for recovery.

Fixes potential memory leaks in case the beacon queue is detected stuck.

Signed-off-by: David Bauer <mail@david-bauer.net>
Link: https://patch.msgid.link/20260611215658.259324-1-mail@david-bauer.net
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **6.6.157** (`pending-6.6`). The two-line SKB leak is
present here, was introduced by a commit already in this tree, and
applies cleanly.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

**Step 1.1: PARSE THE SUBJECT LINE**

Record: **[wifi: mt76: mt7603]** **[free]** **[free the generated beacon
SKB when queue-stuck recovery bails out]**

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**

Record:
- **Fixes:** none (expected for this pipeline)
- **Reported-by:** none
- **Tested-by:** none
- **Reviewed-by:** none
- **Acked-by:** none
- **Link:**
  `https://patch.msgid.link/20260611215658.259324-1-mail@david-
  bauer.net`
- **Cc: stable:** none (expected)
- **Signed-off-by:** David Bauer (author); Felix Fietkau (mt76
  maintainer). Ignore any Sasha Levin SOB if present in candidate
  wrapping.

Mainline SHA (from `origin/master`):
`965cbdbdfbd37a659a05ff88e49c216975bd9d2e`
AuthorDate: 2026-06-11; applied by Felix Fietkau 2026-07-31.

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**

Record:
- **Bug:** After `ieee80211_beacon_get()`, if `mt76_poll()` times out on
  `MT_DMA_FQCR0` (beacon/BMC queue flush stuck), the function `goto out`
  without freeing the SKB.
- **Symptom:** SKB leak whenever the beacon queue is detected stuck and
  recovery is scheduled. Commit message typo: “deected”.
- **Version info:** none in the message.
- **Root cause (author):** beacon SKB not freed on the stuck-queue error
  path.

**Step 1.4: DETECT HIDDEN BUG FIXES**

Record: Not a disguised cleanup. Explicit leak fix: two
`dev_kfree_skb(skb)` calls on error paths.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

**Step 2.1: INVENTORY THE CHANGES**

Record:
- File: `drivers/net/wireless/mediatek/mt76/mt7603/beacon.c` (**+2 /
  -0**)
- Function: `mt7603_update_beacon_iter()`
- Scope: **single-file surgical fix**

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**

Record (both hunks, same pattern):

Before: `ieee80211_beacon_get()` allocates `skb`. Flush BCN or BMC via
`MT_DMA_FQCR0`. If poll times out: set `dev->beacon_check =
MT7603_WATCHDOG_TIMEOUT` and `goto out`. Unlock. **SKB never queued and
never freed.**

After: same, but `dev_kfree_skb(skb)` before `goto out`.

Success path unchanged: `mt76_tx_queue_skb()` still takes ownership.

**Step 2.3: IDENTIFY THE BUG MECHANISM**

Record:
- **Category:** error-path resource leak (SKB)
- **Mechanism:** mac80211 docs: *“The driver is responsible for freeing
  the returned skb.”* Error `goto` skipped both queueing and free. Fix
  adds the missing free.

**Step 2.4: ASSESS THE FIX QUALITY**

Record:
- Obviously correct; only the two error returns; no API/lock/structure
  change.
- **Regression risk:** very low. Success path still hands the SKB to
  DMA. `dev_kfree_skb` is `consume_skb` (stats slightly less precise
  than `kfree_skb` on a drop); maintainer accepted it. No double-free:
  frees only happen before queueing.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

**Step 3.1: BLAME THE CHANGED LINES**

Record:
- Leak `goto out` introduced by **`8caa9dd3d1a7c9`** “wifi: mt76:
  mt7603: improve stuck beacon handling” (Greg KH, 2023-11-20), stable
  rewrite of upstream **`3176205933494`** (Felix Fietkau, 2023-07-28).
- `ieee80211_beacon_get(..., 0)` from `6e8912a503759` (MLO 3-arg API);
  already in this tree.
- Driver added in `c8846e1015022` (2018). Pre-2023 code queued the SKB
  even if poll failed; the 2023 change moved queueing after the polls
  and added the leaky `goto`.

**Step 3.2: FOLLOW THE FIXES: TAG**

Record: No Fixes: tag. Buggy commit in **this** tree is `8caa9dd3d1a7c9`
(`git merge-base --is-ancestor` = yes). Upstream `3176205933494` is not
an ancestor (stable SHA rewrite). No later origin/master commits touch
this file after `965cbdbdfbd37`.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**

Record (this tree, path-limited): last functional change on this file is
the stuck-beacon commit itself. Standalone; not patch X/Y.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**

Record: David Bauer already has mt76 commits in this tree (including
mt7603 EEPROM ID). Felix Fietkau is listed maintainer and applied the
patch.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**

Record: None. Same function, same `ieee80211_beacon_get(hw, vif, 0)`,
same poll/`goto out`. `git apply --check` of `965cbdbdfbd37` succeeded.
Standalone.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**

Record:
- `b4 dig -c 965cbdbdfbd37` →
  https://patch.msgid.link/20260611215658.259324-1-mail@david-bauer.net
- `b4 dig -a`: **v1 only**
- Thread mbox: patch only, **no replies**, no NAK, no reviewer Cc:
  stable
- lore.kernel.org WebFetch: **403** (used b4 + openwall/patchew mirrors)

**Step 4.2: CHECK WHO REVIEWED THE PATCH**

Record (`b4 dig -w`): To/Cc included Felix Fietkau, Lorenzo Bianconi,
MediaTek mt76 reviewers, linux-wireless. Applied by Felix with his SOB.
No Reviewed-by.

**Step 4.3: SEARCH FOR THE BUG REPORT**

Record: No Reported-by, syzbot, or bugzilla. Author-found leak on code
inspection. Openwall/Ratatoskr confirm the same v1 text, no discussion.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**

Record: Standalone `[PATCH mt76]`. No series. No follow-up on
`origin/master` for this file.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**

Record: lore.kernel.org/stable WebFetch **403**. No stable discussion in
the saved thread. UNVERIFIED whether anyone already asked stable@;
absence is not a negative signal.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

semcode MCP: **not available**. Used grep/read.

**Step 5.1: IDENTIFY KEY FUNCTIONS**

Record: `mt7603_update_beacon_iter()` only.

**Step 5.2: TRACE CALLERS**

Record:
- Called from `mt7603_pre_tbtt_tasklet()` via
  `ieee80211_iterate_active_interfaces_atomic()`.
- Tasklet scheduled from `mt7603_irq_handler()` on
  `MT_HW_INT3_PRE_TBTT0`.
- Reachable whenever the device is an AP with beacons enabled
  (`beacon_mask`).

**Step 5.3: TRACE CALLEES**

Record: `ieee80211_beacon_get` (driver owns SKB), `mt76_poll`/`mt76_wr`,
`mt76_tx_queue_skb` → `mt76_dma_tx_queue_skb` (takes SKB; error path
uses `ieee80211_tx_status_ext`).

**Step 5.4: FOLLOW THE CALL CHAIN**

Record: userspace/AP stack enables beaconing → hardware pre-TBTT IRQ →
tasklet → iterator. Unprivileged clients do not trigger it directly;
**any AP/router using this chip in AP mode can**. Stuck DMA/FQCR0 is the
error trigger. `mac_work` runs every `MT7603_WATCHDOG_TIME` (100 ms) and
treats `beacon_check >= 10` as `RESET_CAUSE_BEACON_STUCK`.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**

Record: Other mt76 chips use `ieee80211_beacon_get_template` /
`mt76x02_mac_set_beacon` and do not share this FQCR0 poll/`goto out`
pattern. mt76x02 has no equivalent leak.

===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**

Record: **Yes.** `drivers/net/wireless/mediatek/mt76/mt7603/beacon.c`
lines 57–66: poll timeout → set watchdog → `goto out` with no free.
Local: `git describe` → `p-6.6-3-g04810563abb71`, `make kernelversion` →
**6.6.157**. Bug since 8caa9dd3d1a7c9 (stuck-beacon handling). Candidate
`965cbdbdfbd37` is **not** an ancestor of HEAD.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**

Record: **Clean apply** (`git show 965cbdbdfbd37 | git apply --check`).
Surrounding function matches mainline hunks.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**

Record: No other “free beacon SKB” commit. Other mt76 leak fixes
(`ec4a608bca405` probe leak, etc.) are unrelated.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**

Record: **wifi / mt76 / mt7603** (`CONFIG_MT7603E`: MT7603E PCIe and
MT7628/MT7688 SoC WLAN). **IMPORTANT** for those devices (common OpenWrt
APs), not CORE for every 6.6 user.

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**

Record: Mature driver (2018); this file is quiet. Bug is old (2023
stuck-beacon change), not a new-feature side effect.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

**Step 8.1: DETERMINE WHO IS AFFECTED**

Record: **Driver-specific / config-specific:** `CONFIG_MT7603E`,
AP/beaconing. MT7628/MT7688 SoCs are widely deployed in consumer
routers.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**

Record:
- Trigger: FQCR0 poll timeout (5 ms) while updating beacons — the same
  stuck-beacon condition this driver already recovers from.
- Frequency: pre-TBTT (~beacon interval, typically ~100 ms) per AP vif
  (up to 4). Watchdog work every 100 ms usually resets after one such
  event, so **~1 SKB per vif per stuck incident** if recovery works;
  **recurring** if the MAC stays stuck.
- Unprivileged trigger: no (AP beacon path).

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**

Record: **SKB leak**, not oops/UAF/corruption. **MEDIUM** (HIGH only if
stuck-beacon storms on a low-RAM AP). Still a real leak on a path
already considered serious enough to backport.

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**

Record:
- **Benefit:** stops leaking beacon frames on a known hardware-stuck
  path.
- **Risk:** very low (2 lines, error path only, clean apply).
- **Ratio:** favor backport.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

**Step 9.1: COMPILE THE EVIDENCE**

FOR:
- Confirmed leak vs mac80211 SKB ownership.
- Buggy code is in this 6.6.157 tree (`8caa9dd3d1a7c9`).
- +2 lines, obviously correct, clean apply, no deps.
- Maintainer-applied.
- Same recovery path that already justified a stable backport.
- MT7603/MT76x8 used on production APs.

AGAINST:
- Error-path leak; volume per incident is small if watchdog resets.
- No crash/CVE/syzbot/user report.
- No Reviewed-by; mailing list silent.
- Not a core-kernel path.

UNRESOLVED:
- lore.kernel.org HTTP 403; stable@ search not fetched (b4/mbox used
  instead).
- Exact leak rate if reset fails repeatedly: not measured on hardware.

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**

1. Obviously correct and tested? **PASS** — ownership is documented;
   maintainer applied. No extra Tested-by.
2. Fixes a real bug that affects users? **PASS** — SKB leak on stuck-
   beacon recovery.
3. Important issue? **PASS** — resource leak on a periodic AP path (not
   a one-shot init leak). Severity medium, not a panic.
4. Small and contained? **PASS** — 2 lines, one function.
5. No new features or APIs? **PASS**.
6. Can apply to the local tree? **PASS** — verified with `git apply
   --check`.

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**

Record: Not a device-ID/quirk/DT/build/docs exception. Ordinary small
leak fix.

**Step 9.4: MAKE YOUR DECISION**

This is a two-line error-path `kfree` for a leak that exists in 6.6.157,
introduced by a stuck-beacon change already on this branch. Risk is
negligible; benefit is stopping SKB leaks on MT7603/MT76x8 APs when the
beacon DMA path wedges. That meets stable rules for this tree.

------------------------------------------------
What the commit solves for this tree
------------------------------------------------

In `mt7603_update_beacon_iter()`, `ieee80211_beacon_get()` returns an
SKB the driver must free. On FQCR0 poll timeout the function sets the
beacon watchdog and returns without queueing or freeing. That path is
the stuck-beacon recovery added in `8caa9dd3d1a7c9`, which is already
here. Each timeout leaks one beacon SKB per AP interface. The patch only
adds `dev_kfree_skb(skb)` on those two returns.

Risk vs benefit: almost no regression surface; the leak is real whenever
that recovery runs.

------------------------------------------------
Verification
------------------------------------------------

- [Phase 1] Tags: Link msgid `20260611215658.259324-1-mail@david-
  bauer.net`; SOBs David Bauer + Felix Fietkau; no Fixes/Reported-
  by/Cc:stable.
- [Phase 1] Mainline commit `965cbdbdfbd37` on `origin/master`.
- [Phase 2] Diff: +2 `dev_kfree_skb(skb)` in `mt7603_update_beacon_iter`
  poll-fail paths; success path still `mt76_tx_queue_skb`.
- [Phase 2] `include/net/mac80211.h`: “The driver is responsible for
  freeing the returned skb.”
- [Phase 2] `dev_kfree_skb` → `consume_skb` in `include/linux/skbuff.h`.
- [Phase 3] `git blame`: leaky `goto out` from `8caa9dd3d1a7c9` (stable
  form of `3176205933494`).
- [Phase 3] `git merge-base --is-ancestor 8caa9dd3d1a7c9 HEAD` → yes;
  `965cbdbdfbd37` → no; `3176205933494` → no (rewritten).
- [Phase 3] `git show 8caa9dd3d1a7c9`: moved `mt76_tx_queue_skb` after
  polls and added `goto out` without free.
- [Phase 4] `b4 dig -c 965cbdbdfbd37`: v1 only; no replies in mbox.
- [Phase 4] `b4 dig -w`: mt76 maintainers + linux-wireless on To/Cc.
- [Phase 4] lore WebFetch 403; openwall/patchew/ratatoskr match v1, no
  review replies.
- [Phase 5] Caller: `mt7603_pre_tbtt_tasklet` ← `mt7603_irq_handler`
  PRE_TBTT0.
- [Phase 5] Watchdog: `MT7603_WATCHDOG_TIME` 100 ms, timeout 10;
  `mt7603_mac_work` uses `beacon_check` with `check == NULL`.
- [Phase 6] `git describe HEAD` → `p-6.6-3-g04810563abb71`; `make
  kernelversion` → 6.6.157.
- [Phase 6] Local `beacon.c` still missing the kfrees (lines 57–66).
- [Phase 6] `git apply --check` of `965cbdbdfbd37` succeeded.
- [Phase 7] `CONFIG_MT7603E`; MAINTAINERS: Felix Fietkau.
- [Phase 8] Failure mode: SKB leak on stuck-beacon recovery; severity
  MEDIUM.
- UNVERIFIED: stable@ mailing-list archive (HTTP 403); hardware leak
  rate if reset keeps failing.

**YES**

 drivers/net/wireless/mediatek/mt76/mt7603/beacon.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c b/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c
index 6457ee06bb5a1..62e8de6949d1a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c
@@ -56,6 +56,7 @@ mt7603_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
 		FIELD_PREP(MT_DMA_FQCR0_TARGET_QID, MT_TX_HW_QUEUE_BCN));
 	if (!mt76_poll(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY, 0, 5000)) {
 		dev->beacon_check = MT7603_WATCHDOG_TIMEOUT;
+		dev_kfree_skb(skb);
 		goto out;
 	}
 
@@ -63,6 +64,7 @@ mt7603_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
 		FIELD_PREP(MT_DMA_FQCR0_TARGET_QID, MT_TX_HW_QUEUE_BMC));
 	if (!mt76_poll(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY, 0, 5000)) {
 		dev->beacon_check = MT7603_WATCHDOG_TIMEOUT;
+		dev_kfree_skb(skb);
 		goto out;
 	}
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7915: configure noise floor reporting on reset
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (12 preceding siblings ...)
  2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-5.15] wifi: mt76: mt7603: free beacon SKB on error Sasha Levin
@ 2026-10-19 13:47 ` Sasha Levin
  2026-10-19 13:48 ` [PATCH AUTOSEL 6.18-6.6] wifi: mt76: mt7603: file buffered frames under the TID reported to mac80211 Sasha Levin
                   ` (26 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:47 UTC (permalink / raw)
  To: patches, stable
  Cc: David Bauer, Felix Fietkau, Sasha Levin, lorenzo, ryder.lee,
	matthias.bgg, angelogioacchino.delregno, linux-wireless,
	linux-kernel, linux-arm-kernel, linux-mediatek

From: David Bauer <mail@david-bauer.net>

[ Upstream commit a92cd5dd792a63a5d8a72142835382d4edbe9933 ]

When performing a full system recovery of the MCU on a dual-phy
platform, band 0 (usually 2.4GHz) stops reading correct noise floor
data.

This is due to noise floor reporting only being configured correctly
for the second device PHY.

Configure the respective registers correctly after restarting the MCU
firmware to fix reported noise-floor values.

Signed-off-by: David Bauer <mail@david-bauer.net>
Link: https://patch.msgid.link/20260516144944.2574053-1-mail@david-bauer.net
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **6.6.157** (`pending-6.6`). The buggy dual-PHY
restart path is present here, and this commit should be backported.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

**Step 1.1: PARSE THE SUBJECT LINE**
Record: **[wifi: mt76: mt7915]** **[configure]** configure noise floor
reporting after MCU reset on dual-PHY platforms. “Configure” here is
restoring register state that recovery currently skips, not a new
feature.

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- Signed-off-by: David Bauer &lt;mail@david-bauer.net&gt; (author)
- Link: https://patch.msgid.link/20260516144944.2574053-1-mail@david-
  bauer.net
- Signed-off-by: Felix Fietkau &lt;nbd@nbd.name&gt; (mt76 maintainer)
- No Fixes:, Reported-by:, Tested-by:, Reviewed-by:, Acked-by:, or Cc:
  stable (absence is expected)
- Ignored: any pipeline “Upstream commit” / Sasha Levin SOB markers

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** After full MCU recovery on a dual-PHY (DBDC) device, band 0
  (usually 2.4 GHz) stops reporting correct noise floor.
- **Symptom:** Wrong NF / survey noise on the primary PHY; the second
  PHY is configured correctly.
- **Root cause (author):** NF enable is only applied for the second PHY
  after firmware restart.
- **Version info:** none in the message. The restart path has been in
  this tree since before v6.6.

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not disguised cleanup. It is an explicit hardware-init fix. The
mechanism (clear `MT76_STATE_RUNNING` before `mt7915_run()`) also re-
runs the primary PHY’s PM/MAC init that the same `if (!running)` guard
skips, not only NF.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `drivers/net/wireless/mediatek/mt76/mt7915/mac.c` only
- Scope: ~+6/−2 in `mt7915_mac_restart()` (surgical, single function)
- Adds `bool run_main, run_ext`
- Replaces `test_bit(MT76_STATE_RUNNING)` with `test_and_clear_bit`,
  then uses those saved flags to decide whether to call `mt7915_run()`

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:
- **Before:** After firmware reload, `mt7915_run()` is called while both
  PHYs still have `MT76_STATE_RUNNING`. `mt7915_dev_running()` is
  therefore true.
- In this tree, `mt7915_run()` only programs primary-PHY PM/MAC/NF when
  `!running`:

```32:58:drivers/net/wireless/mediatek/mt76/mt7915/main.c
        if (!running) {
                ret = mt76_connac_mcu_set_pm(&dev->mt76,
                                             dev->phy.mt76->band_idx,
0);
                ...
                mt7915_mac_enable_nf(dev, dev->phy.mt76->band_idx);
        }

        if (phy != &dev->phy) {
                ...
                mt7915_mac_enable_nf(dev, phy->mt76->band_idx);
        }
```

- Primary `mt7915_run()` therefore skips band-0 NF. Ext `mt7915_run()`
  still hits `phy != &dev->phy` and enables band-1 NF. That matches the
  commit message.
- `ieee80211_restart_hw()` after full reset does not repair this:
  starting the main PHY while the ext PHY still has `MT76_STATE_RUNNING`
  keeps `running == true`, so band 0 is skipped again; starting the ext
  PHY then enables only the ext PHY’s NF.
- **After:** bits are cleared first, so the first `mt7915_run()` sees
  `running == false` and programs band 0. Saved flags still prevent
  starting a PHY that was never up.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record: **Logic / hardware-init.** After MCU reload, IPI/NF registers
(`mt7915_mac_enable_nf`: `MT_WF_PHY_RXTD12_*` and
`MT_WF_PHY_RX_CTRL1_IPI_EN`) are not programmed for band 0.
`mt7915_mac_init_band()` does not enable NF; only `mt7915_run()` does.

**Step 2.4: ASSESS THE FIX QUALITY**
Record: Obviously correct. Same approach the mt76 maintainer asked for
on-list. Minimal. Mutex is already held in `mt7915_mac_full_reset()`;
`MT76_RESET` is already set. Risk is low: if `mt7915_run()` fails, the
RUNNING bits stay clear, but full reset retries and then calls
`ieee80211_restart_hw()`, which stop/start and restores them.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

**Step 3.1: BLAME THE CHANGED LINES**
Record: The `test_bit` + `mt7915_run()` sequence was introduced in
`8a55712d124fd8` (“wifi: mt76: mt7915: enable full system reset
support”, Bo Jiao / Ryder Lee, 2022). `git describe --contains` →
`v6.2-rc1~...`. Present in this 6.6 tree (`git merge-base --is-ancestor
8a55712d124fd8 HEAD` succeeded).

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No Fixes: tag. Not applicable. The introducing commit is in this
tree.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record: Related reset work already in this tree:
- `c71d2db21f153` improve hardware restart reliability
- `1e474cbe5db60` fix omac index assignment after hardware reset
- `72eabd4c1986b` firmware restart on devices with a second PCIe link
This patch is standalone; it does not depend on those.
`test_and_clear_bit(MT76_STATE_RUNNING)` is **not** in this tree (`git
grep` found no matches).

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: David Bauer is an OpenWrt/wireless contributor; in this tree he
already has `b6c39aaa85c4e` (mt7915 MCU re-init). Felix Fietkau (mt76
maintainer) signed off and designed the committed approach.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: No functional prerequisites. Surrounding `mt7915_init_txpower()`
signature and `napi_enable` placement differ from later mainline; those
are context only. The `run_main`/`run_ext` change applies with a small
context tweak.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record: `b4 dig -c` was not usable (commit SHA not in this checkout’s
master). `b4 mbox` on msgid `20260516144944.2574053-1-mail@david-
bauer.net` saved a 4-message thread.
- v1 (16 May 2026): 4-line change in `mt7915_run()`: `if (!running ||
  (reset && phy == &dev->phy))`
- Felix (27 May): asked to clear `MT76_STATE_RUNNING` in
  `mt7915_mac_restart` instead
- David: explained the per-PHY RUNNING guard (don’t start a PHY that was
  never up)
- Felix (1 Jun): proposed exactly the committed `test_and_clear_bit`
  pattern
No NAK. No reviewer `Cc: stable`. Committed diff is the maintainer
rewrite, still linked to the v1 msgid.

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record: Recipients included Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
Shayne Chen, Sean Wang, linux-wireless, linux-mediatek. Felix both
reviewed and applied.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: No syzbot/bugzilla. Author describes a real dual-PHY MCU
recovery failure. That is a field observation, not a theoretical report.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: Single patch, not N/M. v1 vs committed is a maintainer rewrite
of the same fix, not a multi-patch series.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: No useful stable-list hit for this subject. No recorded reason
to keep it out of stable.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

**Step 5.1: IDENTIFY KEY FUNCTIONS**
Record: Modified: `mt7915_mac_restart()`. Behavior depends on
`mt7915_run()`, `mt7915_dev_running()`, `mt7915_mac_enable_nf()`.

**Step 5.2: TRACE CALLERS**
Record:
- `mt7915_mac_restart()` ← `mt7915_mac_full_reset()` (only caller in
  this tree)
- `mt7915_mac_full_reset()` ← `mt7915_mac_reset_work()` when
  `dev->recovery.restart`
- `recovery.restart` set in `mt7915_reset()` on WA/WM watchdog
  (`MT_MCU_CMD_WDT_MASK`), which logs “firmware crash, attempting
  recovery”
- `mt7915_run()` also from `mt7915_start()` (normal iface start); this
  patch does not change that path

**Step 5.3: TRACE CALLEES**
Record: After firmware load: `mt7915_mcu_init_firmware`,
`mt7915_mcu_set_eeprom`, `mt7915_mac_init`, txpower/txbf, then
`mt7915_run()` (PM, `mt7915_mcu_set_mac`, `mt7915_mac_enable_nf`,
thermal, RTS, SKU, RX path).

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: Triggered by firmware watchdog recovery on `CONFIG_MT7915E`
dual-PHY (mt7915/mt7916/mt798x DBDC), common on APs/routers. Not a
generic syscall crash path. Userspace sees bad survey noise
(`mt76_get_survey` → `SURVEY_INFO_NOISE_DBM`) and ACS can use it.
Debugfs can also force full reset (`b662b71`).

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: No `test_and_clear_bit(MT76_STATE_RUNNING)` in this tree’s mt76.
Sibling chips (mt7615/mt7996) have similar NF helpers; this fix is
mt7915-restart-specific.

===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: Yes. `mt7915_mac_restart()` at
`drivers/net/wireless/mediatek/mt76/mt7915/mac.c:1397-1407` still uses
`test_bit` without clearing. Introduced v6.2-era (`8a55712d124fd8`),
present since this 6.6 branch.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: **Minor context.** Mainline hunk context uses
`mt7915_init_txpower(&dev->phy)` / `mt7915_init_txpower(phy2)`; this
tree still has `mt7915_init_txpower(dev, &dev->mphy.sband_* )`.
`napi_enable` vs `local_bh_disable` order in the `out:` path also
differs. The RUNNING-bit change itself matches this tree. Easy manual
backport; not a rewrite.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: Reset reliability/omac-after-reset fixes are here. This NF re-
init after MCU recovery is not.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: **wifi / mt76 mt7915**
(`drivers/net/wireless/mediatek/mt76/mt7915/`). **IMPORTANT** for users
of these radios (filogic/mt7915 DBDC APs), not core mm/net. Not staging.

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: Mature driver, still getting reset-path fixes in this 6.6 tree.
Not a newly added subsystem.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: Driver-specific, dual-PHY `CONFIG_MT7915E` after full MCU
recovery. Widely used on embedded/AP hardware.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record: Firmware WA/WM watchdog → full recovery. Unprivileged users
cannot trigger it directly. Timing is the recovery path, not a race.
Debugfs reset can also hit it.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record: Wrong band-0 noise floor / survey after recovery; ACS can pick a
worse channel. Not an oops, deadlock, or corruption. Connectivity was
not reported broken; `mac_init` still runs, so MAC datapath likely
survives. **Severity: MEDIUM.**

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record:
- **Benefit:** Medium. Restores intended PHY register state on a
  recovery path this tree already treats as backport-worthy.
- **Risk:** Low. ~8 lines, one function, maintainer-specified, under
  existing reset mutex.
- **Ratio:** Favorable.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

**Step 9.1: COMPILE THE EVIDENCE**

FOR:
- Real dual-PHY bug after MCU full recovery; primary PHY NF registers
  never reprogrammed
- Code and introducing commit are in 6.6.157
- Small, obviously correct, maintainer-directed
- Same `!running` skip also omits band-0 `set_pm`/`set_mac` on that path
- This tree already backported other mt7915 reset corrections
- Dual-PHY mt7915/mt798x is common production AP hardware

AGAINST:
- Not a crash, UAF, deadlock, or security issue
- Trigger is firmware watchdog recovery, not a hot path
- User-visible effect is mainly survey/ACS noise, not a reported outage
- Apply needs a trivial context adjustment

UNRESOLVED:
- Upstream SHA is not on this checkout’s `master`, so `b4 dig -c <sha>`
  was not run (thread retrieved via msgid instead)
- No independent confirmation that band-0 MAC/PM skip causes traffic
  loss (author only reported NF)

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — logic matches
   `mt7915_run()`; maintainer specified this form
2. Fixes a real bug that affects users? **PASS** — wrong NF after
   recovery on dual-PHY
3. Important issue? **PASS** (medium) — recovery leaves hardware
   misconfigured; not a panic, but it is a real functional failure of
   SER
4. Small and contained? **PASS** — one function, few lines
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — buggy code present; minor
   context only

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: Not a new device ID/API. Closest class is hardware re-init after
reset (quirk-like). Qualifies on technical merit, not only via an
exception.

**Step 9.4: MAKE YOUR DECISION**
Backport. The 6.6 tree has the bug, the fix is surgical, and leaving MCU
recovery with band 0 NF unprogrammed is a real driver bug on hardware
this series already ships.

Verification:
- [Phase 1] Parsed tags: author David Bauer, Link to msgid, SOB Felix
  Fietkau; no Fixes/Cc stable/Reported-by
- [Phase 1] Body: dual-PHY MCU recovery → band 0 NF wrong because only
  PHY1 is configured
- [Phase 2] Diff: `mt7915_mac_restart()` saves/clears RUNNING then calls
  `mt7915_run()`
- [Phase 2] Local `mt7915_run()`: primary NF only if
  `!mt7915_dev_running()`; ext NF if `phy != &dev->phy`
- [Phase 2] `mt7915_mac_init_band()` does not set IPI/NF; only
  `mt7915_mac_enable_nf()` does
- [Phase 3] `git blame` `mac.c:1397-1407` → `8a55712d124fd8` (v6.2-rc1);
  ancestor of HEAD
- [Phase 3] `git grep test_and_clear_bit(MT76_STATE_RUNNING)` → no hits
  in this tree
- [Phase 3] Related reset fixes already here (`c71d2db21f153`,
  `1e474cbe5db60`); this NF fix is not
- [Phase 4] `b4 mbox` msgid → 4-message thread; Felix requested the
  committed approach; no NAK
- [Phase 4] lore.kernel.org WebFetch returned 403; used b4 mbox +
  openwall/ratatoskr instead
- [Phase 4] No meaningful stable-list discussion found
- [Phase 5] Call chain: WDT → `mt7915_reset()` → dump_work →
  `mt7915_mac_reset_work()` → `mt7915_mac_full_reset()` →
  `mt7915_mac_restart()`
- [Phase 5] Survey path: `mt7915_update_channel()` → `state->noise` →
  `mt76_get_survey()`
- [Phase 6] `git describe HEAD` / `make kernelversion` → p-6.6-3 /
  **6.6.157**
- [Phase 6] Local `mt7915_init_txpower()` signature differs from patch
  context; RUNNING change still maps 1:1
- [Phase 8] Failure mode: incorrect band-0 noise after firmware crash
  recovery; severity MEDIUM
- UNVERIFIED: exact upstream SHA (not on this `master`); whether band-0
  `set_mac` skip also breaks traffic (not claimed by author)

The patch is a small, maintainer-reviewed correction of MCU recovery on
dual-PHY mt7915, and the buggy code is in this 6.6 tree.

**YES**

 drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index dda4e7d179536..55d2553addb13 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -1292,6 +1292,7 @@ mt7915_mac_restart(struct mt7915_dev *dev)
 	struct mt7915_phy *phy2;
 	struct mt76_phy *ext_phy;
 	struct mt76_dev *mdev = &dev->mt76;
+	bool run_main, run_ext;
 	int i, ret;
 
 	ext_phy = dev->mt76.phys[MT_BAND1];
@@ -1387,13 +1388,17 @@ mt7915_mac_restart(struct mt7915_dev *dev)
 	mt7915_init_txpower(phy2);
 	ret = mt7915_txbf_init(dev);
 
-	if (test_bit(MT76_STATE_RUNNING, &dev->mphy.state)) {
+	run_main = test_and_clear_bit(MT76_STATE_RUNNING, &dev->mphy.state);
+	run_ext = ext_phy &&
+		  test_and_clear_bit(MT76_STATE_RUNNING, &ext_phy->state);
+
+	if (run_main) {
 		ret = mt7915_run(dev->mphy.hw);
 		if (ret)
 			goto out;
 	}
 
-	if (ext_phy && test_bit(MT76_STATE_RUNNING, &ext_phy->state)) {
+	if (run_ext) {
 		ret = mt7915_run(ext_phy->hw);
 		if (ret)
 			goto out;
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18-6.6] wifi: mt76: mt7603: file buffered frames under the TID reported to mac80211
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (13 preceding siblings ...)
  2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7915: configure noise floor reporting on reset Sasha Levin
@ 2026-10-19 13:48 ` Sasha Levin
  2026-10-19 13:48 ` [PATCH AUTOSEL 6.18-5.10] wifi: mt76: mt7603: fix U-APSD service period termination Sasha Levin
                   ` (25 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:48 UTC (permalink / raw)
  To: patches, stable
  Cc: Felix Fietkau, Sasha Levin, lorenzo, ryder.lee, matthias.bgg,
	angelogioacchino.delregno, linux-wireless, linux-kernel,
	linux-arm-kernel, linux-mediatek

From: Felix Fietkau <nbd@nbd.name>

[ Upstream commit 0bbd6c52dfff62b319963f54cd9370f9486e59d2 ]

The PS queue filed redirected frames under the TID taken from the TXD,
while mac80211 was told about the TID taken from the QoS header, or TID 0
for anything that is not a QoS data frame. When the two disagree,
mt7603_release_buffered_frames() skips the frame because it does not
match the requested TIDs, so it stays in the PS queue until the station
wakes up. Buffered MMPDUs hit this whenever they were sent on a
non-zero TID.

Use one TID for both.

Link: https://patch.msgid.link/20260801145334.1166751-8-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

This tree is **6.12.111** (`p-6.12-2`). The mt7603 PS-queue TID mismatch
is present here, the two-line fix applies cleanly, and it is a real AP-
mode buffering bug.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

**Step 1.1: PARSE THE SUBJECT LINE**
Record: **[wifi: mt76: mt7603]** **[file]** buffered frames under the
TID reported to mac80211. “File” here means enqueue/classify; the body
is a correctness fix so mac80211 and the driver PS queue use the same
TID.

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- **Link:**
  `https://patch.msgid.link/20260801145334.1166751-8-nbd@nbd.name`
  (patch 08/10)
- **Signed-off-by:** Felix Fietkau (mt76 maintainer; ignore any Sasha
  Levin SOB)
- **No Fixes:, Reported-by:, Tested-by:, Reviewed-by:, Acked-by:, or Cc:
  stable** (absence expected for this review)

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** Redirected PS frames are queued under the TXD TID, while
  `ieee80211_sta_set_buffered()` is told the QoS-header TID, or TID 0
  for non-QoS data / MMPDUs.
- **Symptom:** `mt7603_release_buffered_frames()` skips the skb (`tids &
  BIT(skb->priority)` fails). The frame sits in `msta->psq` until the
  station fully wakes (`mt7603_sta_ps()` splices the whole queue).
  Buffered MMPDUs hit this whenever the TXD TID is non-zero.
- **Root cause:** Two different TID sources for the same frame.
- **Fix:** Use the same `tid` for both `skb->priority` and
  `ieee80211_sta_set_buffered()`.

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not a disguised cleanup. It is an explicit protocol/correctness
fix.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

**Step 2.1: INVENTORY THE CHANGES**
Record:
- **File:** `drivers/net/wireless/mediatek/mt76/mt7603/dma.c` (+1 / −1)
- **Function:** `mt7603_rx_loopback_skb()`
- **Scope:** single-file surgical fix

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:
- **Before:** `skb->priority = FIELD_GET(MT_TXD1_TID, val)` (3-bit TXD
  field), then later `ieee80211_sta_set_buffered(sta, tid, true)` with
  `tid` from the QoS header or 0.
- **After:** `skb->priority = tid` after that classification.
- **Path:** hardware PS redirect → MCU RX loopback → driver PS queue.
  Not an init-only path.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record: **Logic / correctness.** Enqueue key (`skb->priority`) and
mac80211 TIM/TID bitmap disagree, so `release_buffered_frames` never
dequeues those skbs during PS-Poll/U-APSD.

**Step 2.4: ASSESS THE FIX QUALITY**
Record: Obviously correct and minimal. `tid` is already 0–7
(`IEEE80211_QOS_CTL_TAG1D_MASK` or 0). No new locks, APIs, or data
structures. Regression risk is very low: release matching becomes
consistent with what mac80211 was already told.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

**Step 3.1: BLAME THE CHANGED LINES**
Record:
- `skb->priority = FIELD_GET(MT_TXD1_TID, val)` comes from the original
  driver (`c8846e1015022`, 2018).
- Split vs mac80211 TID: `e004b700660025` (2019,
  `ieee80211_sta_set_buffered`) and `d55aa5e17461b8` (2019, QoS-only
  TID, default 0).
- Current if/else (QoS / data / bufferable MMPDU) is `b473c0e47f04d`
  (2024, “fix tx queue of loopback packets”), **already in this 6.12
  tree**.

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No Fixes: tag. Buggy split has been in the driver since 2019;
MMPDU TID-0 reporting since `d55aa5e17461b8` / `b473c0e47f04d`.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record: Recent `dma.c` history includes `b473c0e47f04d` and
`9b8d932053b8b`. This commit is **not** in HEAD (`git merge-base --is-
ancestor 0bbd6c52dfff62b319963f54cd9370f9486e59d2 HEAD` → not ancestor).
Standalone vs later 2026 PS series (see 3.5).

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Felix Fietkau is the mt76 maintainer. Nearby author work on this
driver is unrelated (chainmask, EEPROM, WPDMA EOF). Same 10-patch series
contains other mt7603 PS fixes he wrote.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: Upstream SHA `0bbd6c52dfff62b319963f54cd9370f9486e59d2`. Series
08/10. Needed context `b473c0e47f04d` **is** in this tree. Later series
patches are **not** in this tree and are **not** required for this two-
line change:
- `697badc27a9b3` U-APSD EOSP
- `d5001f493fefd` clear buffered-TID when psq empty
- `636a883e2feef` re-arm HW PS after service period
Those fix other PS bugs; this patch only aligns enqueue TID with
`ieee80211_sta_set_buffered()`. It can apply standalone.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- `b4 dig -c 0bbd6c52dfff6` →
  https://patch.msgid.link/20260801145334.1166751-8-nbd@nbd.name
- Single series revision (v1 only; `-a` showed only this series)
- Thread: 11 messages = 10 patches + kernel test robot on **patch 10
  only** (mt7996 OOB, unrelated)
- No NAK, no reviewer risk comments, no Cc: stable on this patch

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record: `b4 dig -w`: To `linux-wireless@vger.kernel.org`, From Felix
Fietkau. No extra Reviewed-by. Author is the subsystem maintainer and
applied it himself.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: No Reported-by / bugzilla / syzbot. Failure mode is code-
derived. Related series patch 07 mentions U-APSD retry storms/packet
loss; that is a **different** bug.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: `[PATCH 01/10]` adds `MT_DRV_HW_PS_BUFFERING` for firmware-TIM
chips (mt7915/mt7996), not mt7603 loopback. mt7603 patches 05–07 are
sibling PS fixes, not semantic prerequisites of 08.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: No useful stable-list hit for this subject (lore.kernel.org
fetch 403; web search returned unrelated archives). UNVERIFIED that
anyone already requested/rejected it for stable.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

**Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF**
Record: `mt7603_rx_loopback_skb()` only.

**Step 5.2: TRACE CALLERS**
Record:
- Called only from `mt7603_queue_rx_skb()` when `q == MT_RXQ_MCU` and
  the packet is not `PKT_TYPE_RX_EVENT` (HW-redirected TX).
- `mt7603_queue_rx_skb` is `.rx_skb` in
  `drivers/net/wireless/mediatek/mt76/mt7603/init.c`.
- Release path: mac80211 `drv_release_buffered_frames` →
  `mt7603_release_buffered_frames()` which filters on
  `BIT(skb->priority)` (verified at `main.c:458`).

**Step 5.3: TRACE CALLEES**
Record: `ieee80211_is_data_qos` / `ieee80211_is_data` /
`ieee80211_is_bufferable_mmpdu(skb)` (present in this tree’s
`ieee80211.h`), `ieee80211_sta_set_buffered`, `skb_queue` under
`ps_lock`.

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: Reachable in AP mode when a station is in PS and the PSE
redirects TX. Userspace/network traffic plus sleeping clients trigger
it. Not a syscall crash path; it is a common AP operation on this
hardware.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: Other mt76 chips use `mt76_release_buffered_frames()`; mt7603
has its own `psq`. No duplicate of this exact TXD-vs-QoS TID split
elsewhere in this driver.

===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: **Yes.** `dma.c` still has:

```42:75:drivers/net/wireless/mediatek/mt76/mt7603/dma.c
        skb->priority = FIELD_GET(MT_TXD1_TID, val);
        ...
        ieee80211_sta_set_buffered(sta, tid, true);
```

`MT_TXD1_TID` is `GENMASK(22, 20)`. `mt7603_release_buffered_frames()`
still skips on `!(tids & BIT(skb->priority))`. Bug introduced 2019;
still here in 6.12.111. Upstream commit is **not** an ancestor of HEAD.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: **Clean apply.** `git apply --check` of `0bbd6c52dfff6`
succeeded. This tree still uses `rcu_dereference(dev->mt76.wcid[idx])`
rather than `mt76_wcid_ptr()`; that is unused context, not a conflict.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: No equivalent TID alignment. `git log --grep='buffered frames
under the TID'` on this path is empty. Sibling 2026 PS series patches
are not in this tree.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: **wifi / mt76 / mt7603** (`CONFIG_MT7603E`: MT7603E PCIe and
MT7628/MT7688 SoC WLAN). **IMPORTANT** (widely used AP/router silicon),
not core mm/net.

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: Mature driver, still receiving maintainer fixes. Not staging.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: **Driver-specific:** AP (and any PS-buffering) users of
MT7603/MT7628/MT7688. Not universal.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record: Station in power-save; HW redirects frames into the driver PS
queue; mac80211 later releases by TID (PS-Poll / U-APSD). Common on APs
with phones/IoT clients. Unprivileged Wi-Fi clients can trigger it by
sleeping. MMPDUs with non-zero TXD TID are the documented always-hit
case.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record: Frames are not released during the service period. They wait
until the station leaves PS, or they can be dropped if `psq` hits 64.
That delays bufferable management (deauth/disassoc/action) and
mismatched-TID data. **Severity: HIGH** for AP connectivity; not a
kernel oops.

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record: **Benefit: high** for this hardware (PS buffering actually works
for the TIDs mac80211 asked for). **Risk: very low** (2 lines, no
locking/API change, applies cleanly). Ratio strongly favors backport.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

**Step 9.1: COMPILE THE EVIDENCE**

FOR:
- Real, explained bug; mechanism confirmed in this tree’s `dma.c` and
  `main.c`
- User-visible AP PS failure (stuck/delayed frames, possible psq
  overflow drops)
- 2-line, obviously correct, maintainer-authored
- Applies cleanly to 6.12.111
- Prerequisite loopback-queue rewrite (`b473c0e47f04d`) already present
- Does not need the rest of the 10-patch series

AGAINST:
- Not a crash, UAF, or CVE
- No reporter / Tested-by / Fixes tag
- Other mt7603 PS bugs in the same series remain unfixed here (does not
  make this patch wrong)

UNRESOLVED:
- No stable-list discussion found (lore 403 / search noise)
- No independent user report for this exact TID mismatch

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — two-line alignment; in
   mainline from the maintainer
2. Real bug affecting users? **PASS** — PS-buffered frames not released
   until wake
3. Important issue? **PASS** — AP power-save correctness / delayed
   MMPDUs; HIGH not panic
4. Small and contained? **PASS** — 2 lines, one function
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — clean apply on 6.12.111

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: None (not a device ID / quirk / DT / build / docs exception).
Qualifies as a normal contained bugfix.

**Step 9.4: MAKE YOUR DECISION**
Backport. This 6.12 tree has the exact buggy split, the fix is surgical,
and it restores mac80211-driven release of buffered frames (especially
MMPDUs) for a still-deployed wireless SoC.

------------------------------------------------
What the commit solves for stable users
------------------------------------------------
On MT7603/MT7628 APs, hardware-redirected PS frames are advertised to
mac80211 under one TID and stored under another. Service-period release
then skips them, so management and some data stay in the driver queue
until the client fully wakes (or the 64-entry queue drops them). Using
one TID for both makes `release_buffered_frames` find those skbs.

Risk vs benefit: two lines, no API/locking change, clean apply; benefit
is correct PS delivery on real AP hardware.

Concerns: sibling U-APSD/PS-rearm fixes are separate commits and not
required. No backport rewrite needed on this tree.

===============================================================
Verification
===============================================================
- [Phase 1] Tags: Link msgid `20260801145334.1166751-8-nbd@nbd.name`;
  SOB Felix Fietkau; no Fixes/Reported-by/Cc stable
- [Phase 2] Diff: move `skb->priority` from `MT_TXD1_TID` to classified
  `tid` in `mt7603_rx_loopback_skb` (+1/−1)
- [Phase 3] `git describe` / Makefile: **6.12.111**
  (`p-6.12-2-gd38d58a4e0359`)
- [Phase 3] Blame/history: TXD priority from `c8846e1015022`; mac80211
  TID from `e004b700660025` / `d55aa5e17461b8`; MMPDU/queue split
  `b473c0e47f04d` **is** ancestor of HEAD
- [Phase 3] `git merge-base --is-ancestor
  0bbd6c52dfff62b319963f54cd9370f9486e59d2 HEAD` → not present
- [Phase 3] Related series SHAs `697badc27a9b3`, `d5001f493fefd`,
  `636a883e2feef` → not in HEAD; not required
- [Phase 4] `b4 dig -c 0bbd6c52dfff6`: lore match, v1 only; `-w`: linux-
  wireless + author; robot reply only on patch 10
- [Phase 4] UNVERIFIED: stable@ discussion (lore 403)
- [Phase 5] Caller: `mt7603_queue_rx_skb` MCU loopback; release uses
  `BIT(skb->priority)` at `main.c:458`
- [Phase 6] Local `dma.c:42` still assigns priority from TXD; `git apply
  --check` of upstream diff **exit 0**
- [Phase 8] Failure mode: PS frames skipped until wake / possible psq
  drop; HIGH connectivity, not oops

**YES**

 drivers/net/wireless/mediatek/mt76/mt7603/dma.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/dma.c b/drivers/net/wireless/mediatek/mt76/mt7603/dma.c
index e26cc78fff949..25009e49e7771 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/dma.c
@@ -39,7 +39,6 @@ mt7603_rx_loopback_skb(struct mt7603_dev *dev, struct sk_buff *skb)
 
 	val = le32_to_cpu(txd[1]);
 	idx = FIELD_GET(MT_TXD1_WLAN_IDX, val);
-	skb->priority = FIELD_GET(MT_TXD1_TID, val);
 
 	if (idx >= MT7603_WTBL_STA - 1)
 		goto free;
@@ -72,6 +71,7 @@ mt7603_rx_loopback_skb(struct mt7603_dev *dev, struct sk_buff *skb)
 		hwq = MT_TX_HW_QUEUE_MGMT;
 	}
 
+	skb->priority = tid;
 	ieee80211_sta_set_buffered(sta, tid, true);
 
 	val = le32_to_cpu(txd[0]);
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] wifi: mt76: mt7603: fix U-APSD service period termination
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (14 preceding siblings ...)
  2026-10-19 13:48 ` [PATCH AUTOSEL 6.18-6.6] wifi: mt76: mt7603: file buffered frames under the TID reported to mac80211 Sasha Levin
@ 2026-10-19 13:48 ` Sasha Levin
  2026-10-19 13:48 ` [PATCH AUTOSEL 6.18-6.6] wifi: ath12k: fix scan command endianness on big endian Sasha Levin
                   ` (24 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:48 UTC (permalink / raw)
  To: patches, stable
  Cc: Felix Fietkau, Sasha Levin, lorenzo, ryder.lee, matthias.bgg,
	angelogioacchino.delregno, linux-wireless, linux-kernel,
	linux-arm-kernel, linux-mediatek

From: Felix Fietkau <nbd@nbd.name>

[ Upstream commit 697badc27a9b3b2a8d86092abeed767714f735a2 ]

Frames released from the driver PS queue were all tagged with MORE_DATA
and none of them ever carried the EOSP bit, so from the client's point of
view a U-APSD service period was started but never finished. Clients that
keep their receiver on until EOSP arrives stop sending trigger frames,
and all downlink traffic for that station stalls until they give up.
ieee80211_sta_eosp() only cleared the service period state inside
mac80211, which is why the mismatch went unnoticed.

Assign MORE_DATA per frame and set the wire EOSP bit on the last one. If
the last released frame is a bufferable MMPDU it has no QoS control field
to carry EOSP, so let mac80211 append a QoS-Null frame instead.

Also stop handing the remaining frame budget to
mt76_release_buffered_frames() once frames have been released from the PS
queue: both would signal the end of the same service period. Releasing
fewer frames than requested is allowed, and MORE_DATA tells the client to
trigger again.

Link: https://patch.msgid.link/20260801145334.1166751-5-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **5.15.221** (`pending-5.15`). The buggy mt7603 U-APSD
path is present here and matches mainline before `697badc27a9b3`. This
is a real protocol fix for a stall, and it should be backported.

---

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: PARSE THE SUBJECT LINE**
Record: **[wifi/mt76/mt7603] [fix] [U-APSD service period never ends on
the wire]**

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- `Link: https://patch.msgid.link/20260801145334.1166751-5-nbd@nbd.name`
  — patch **05/10** of Felix Fietkau’s series
- `Signed-off-by: Felix Fietkau <nbd@nbd.name>` (mt76 maintainer)
- No `Fixes:`, no `Reported-by:`, no `Tested-by:`, no `Reviewed-by:`, no
  `Cc: stable` (absence of the last two is expected in this pipeline)
- Ignore any `Signed-off-by: Sasha Levin` / `[Upstream commit ...]` if
  present; they are candidate-prep markers

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** Frames pulled from the driver PS queue all get `MORE_DATA`
  and never `EOSP`. A U-APSD SP starts and never ends on the air.
- **Symptom:** Clients that stay awake until EOSP stop sending trigger
  frames; **all downlink traffic for that STA stalls** until they give
  up.
- **Root cause:** `ieee80211_sta_eosp()` only clears mac80211’s
  `WLAN_STA_SP`. mac80211 documents that a driver implementing
  `.release_buffered_frames` must set the **wire** EOSP bit itself.
- **Second bug in the same function:** leftover `nframes` is handed to
  `mt76_release_buffered_frames()`, which ends the **same** SP a second
  time.
- **Fix:** assign `MORE_DATA`/`EOSP` per frame; QoS-Null via
  `ieee80211_send_eosp_nullfunc()` if the last frame is a bufferable
  MMPDU; do not forward leftover budget once PS-queue frames were
  released.

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: **Not hidden.** Subject and body describe a concrete protocol
failure with a user-visible stall.

---

## PHASE 2: DIFF ANALYSIS

**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `drivers/net/wireless/mediatek/mt76/mt7603/main.c` (**+63 /
  −11**)
- Functions: `mt7603_ps_skb_hdr()` (new), `mt7603_ps_set_more_data` →
  `mt7603_ps_set_flags`, `mt7603_release_buffered_frames`
- Scope: **single-file surgical fix**

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:
- **Before:** every released PS-queue frame unconditionally ORs
  `IEEE80211_FCTL_MOREDATA`; never sets/clears EOSP;
  `ieee80211_sta_eosp()` is called if the list is non-empty, then
  leftover `nframes` still go to `mt76_release_buffered_frames()`.
- **After:**
  1. Walk remaining PS queue under `ps_lock` and build a pending-TID
     bitmap.
  2. If nothing was dequeued, fall through to
     `mt76_release_buffered_frames()` (unchanged).
  3. If anything was dequeued, **do not** also release from mac80211
     TXQs.
  4. `MORE_DATA` = not-last **or** more frames remain (mac80211
     `more_data` or pending matching TIDs).
  5. Wire `EOSP` only on the last frame and only for
     `IEEE80211_FRAME_RELEASE_UAPSD`.
  6. Last frame not QoS data → `ieee80211_send_eosp_nullfunc()`; else
     `ieee80211_sta_eosp()`.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record:
- **Category:** protocol / correctness (U-APSD SP termination), not
  UAF/leak/race.
- **Mechanism:** driver never put EOSP on the air; clients that wait for
  EOSP stop triggering; downlink stalls.
- Also: `MORE_DATA` was only set, never cleared. Recycled frames from
  `mt7603_filter_tx()` can keep a stale bit; the new helper assigns both
  bits.

**Step 2.4: ASSESS THE FIX QUALITY**
Record:
- Matches mac80211’s `.release_buffered_frames` contract
  (`include/net/mac80211.h`: driver must set EOSP in the QoS header;
  sending fewer frames than requested is allowed).
- `IEEE80211_QOS_CTL_EOSP` (0x0010) on the first QoS-control byte is the
  correct on-wire bit.
- `ieee80211_send_eosp_nullfunc()` uses `IEEE80211_TX_STATUS_EOSP` on
  the NDP; TX status then clears `WLAN_STA_SP`. iwlwifi already calls
  this from BH/TX context; `.release_buffered_frames` must be atomic,
  and `ieee80211_send_null_response()` uses `dev_alloc_skb` (GFP_ATOMIC)
  + `ieee80211_xmit`.
- Regression risk: **low–medium**. Logic is contained; PS-Poll does not
  set wire EOSP (`uapsd` is false). Companion series patches 06–08 make
  TIM / HW buffering / TID filing more complete but are not required for
  this EOSP fix to compile or to be correct on its own.

---

## PHASE 3: GIT HISTORY INVESTIGATION

**Step 3.1: BLAME THE CHANGED LINES**
Record:
- `mt7603_release_buffered_frames`: `c8846e101502` (2018-11, **mt76: add
  driver for MT7603E and MT7628/7688**)
- Unconditional MORE_DATA: `b126c8897435` (2019-03)
- `ieee80211_sta_eosp()` without wire EOSP: `b7001f46085e` (2019-03)
- All three are ancestors of this 5.15 tree.

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: **No `Fixes:` tag.** Buggy behavior dates to driver introduction
/ 2019 PS-queue helpers, all in this tree.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record: Mainline follow-ups on the same function (not in this tree):
- `d5001f493fef` — tell mac80211 when the PS queue is empty
  (`ieee80211_sta_set_buffered(..., false)`)
- `636a883e2feef` — restore hardware PS buffering after an SP
These are related U-APSD bugs, not prerequisites for this diff.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Felix Fietkau is the mt76 maintainer and original author of this
driver. This is a maintainer fix.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: Patch **05/10**. Patches 01–03/09–10 target mt7915/mt7996 / MLO
/ new HW TIM — **not needed**. Patch 04 sets wire EOSP in generic
`mt76_release_buffered_frames()` (`tx.c`); mt7603 has its **own**
`.release_buffered_frames` and only calls the generic helper when the
driver PS queue is empty. This patch does not use new APIs or struct
fields. **Can apply standalone.**

---

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- `b4 dig -c 697badc27a9b3` →
  https://patch.msgid.link/20260801145334.1166751-5-nbd@nbd.name
- **v1 only** (no v2/v3)
- Thread is the 10-patch series plus a kernel-test-robot mail
- Robot error is on **patch 10 / patch 1** (`ieee80211_txq_aql_pending`
  missing) — **unrelated** to this patch
- No NAKs, no reviewer risk flags, no `Cc: stable` suggestion in the
  thread

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record: `b4 dig -w`: To/Cc were **Felix Fietkau** and **linux-
wireless@**. No extra reviewer SOB. Maintainer self-applied into
wireless-next (listed in the 2026-08-06 wireless-next pull).

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: OpenWrt mt76 users reported U-APSD stalls / **iPhone freezes**
on MT7603 APs (openwrt/mt76#1080 / PR #1084). Testers said an EOSP-
related change made iPhone freezes go away; remaining TX-retry/loss is
the separate HW-buffering bug (series patch 07).

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: Series 01–10 as above. This commit is self-contained. Patch 06
should be considered as a follow-up candidate (TIM never cleared); it is
not required for this hunk.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: No evidence this fix was discussed on stable@ or previously
rejected. UNVERIFIED that every stable archive was searchable
(lore.kernel.org returned 403 for some URLs); `b4`/openwall/syzbot CI
were used instead.

---

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1: IDENTIFY KEY FUNCTIONS**
Record: `mt7603_release_buffered_frames`, `mt7603_ps_set_flags`,
`mt7603_ps_skb_hdr`

**Step 5.2: TRACE CALLERS**
Record: Assigned as `ieee80211_ops.release_buffered_frames` in this
file. mac80211 calls it for **PS-Poll and U-APSD** from the RX/PS path
(atomic). Reachable whenever an AP-mode STA uses power save.

**Step 5.3: TRACE CALLEES**
Record: `mt7603_wtbl_set_ps`, `mt7603_ps_tx_list` /
`mt76_tx_queue_skb_raw`, `mt76_release_buffered_frames` (empty-PS-queue
only), `ieee80211_sta_eosp`, `ieee80211_send_eosp_nullfunc` — all exist
in this tree.

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: Client trigger (QoS-Null/PS-Poll) → mac80211 →
`mt7603_release_buffered_frames`. **Yes, userspace/STA traffic triggers
it.** Typical clients: phones with U-APSD.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: Generic `mt76_queue_ps_skb()` in this tree still only sets
`IEEE80211_TX_STATUS_EOSP` + MORE_DATA, not wire EOSP (mainline patch
04). `mt7603_rx_loopback_skb()` sets `ieee80211_sta_set_buffered(...,
true)` and never clears it (mainline patch 06). Same U-APSD family,
different bugs.

---

## PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: **Yes.** `mt7603_ps_set_more_data` and
`mt7603_release_buffered_frames` in
`drivers/net/wireless/mediatek/mt76/mt7603/main.c` are **byte-for-byte
identical** to the parent of `697badc27a9b3`. Bug since ~2018/2019.

Local tree: `p-5.15-2-g6703e5d2f3a29`, **5.15.221**. `git merge-base
--is-ancestor 697badc27a9b3 HEAD` → **not in this tree**.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: **Clean apply.** Same function bodies; needed APIs
(`ieee80211_send_eosp_nullfunc`, `ieee80211_get_qos_ctl`,
`IEEE80211_QOS_CTL_EOSP`, `IEEE80211_FRAME_RELEASE_UAPSD`) are in 5.15.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: No related U-APSD EOSP/TIM/HW-rearm fixes on this file in this
tree.

---

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: **wifi / mt76 / mt7603** (`CONFIG_MT7603E`). Criticality:
**IMPORTANT** for users of that hardware (MT7603E / MT7628/MT7688 APs —
very common home routers), not core mm/net.

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: Mature driver (since 5.0-era). This is a long-standing bug, not
a regression in new code.

---

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: **Driver-specific:** AP (or GO) mode on MT7603/MT7628 with
U-APSD (or PS-Poll) clients.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record: STA enters power save; hardware redirects frames into
`msta->psq`; STA sends a U-APSD trigger. Common for phones. Unprivileged
wireless clients can trigger it.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record: **Downlink stall / client freeze** until the STA gives up
(disconnect/retry). Not a kernel oops. Severity: **HIGH** for affected
APs (connectivity loss), not CRITICAL kernel crash.

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record:
- **Benefit:** high for MT7603 AP users — restores U-APSD SP completion
  so phones keep triggering.
- **Risk:** low–medium (contained ~50-line logic in one ops callback; no
  API/lock/core changes).
- **Ratio:** benefit outweighs risk.

---

## PHASE 9: FINAL SYNTHESIS

**Step 9.1: COMPILE THE EVIDENCE**

**FOR:**
- Real, user-visible stall (U-APSD SP never ends on the air)
- Matches mac80211 driver contract
- Present in this 5.15 tree since driver introduction
- Functions identical to mainline parent → clean apply
- Small, one file, no new APIs
- Maintainer-authored, merged to mainline as `697badc27a9b3`
- Corroborated by OpenWrt MT7603/iPhone freeze reports

**AGAINST:**
- Not crash/UAF/security
- Series 05/10 (other patches are separate bugs/chips)
- Follow-ups 06–08 still missing here (incomplete *overall* U-APSD, but
  this patch is a complete EOSP fix)
- No extra reviewer tags

**UNRESOLVED:**
- Direct lore.kernel.org HTTP often 403; thread recovered via `b4`
- No explicit stable@ discussion found

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — protocol-correct; maintainer
   merged; consistent with mac80211 docs and iwlwifi’s
   `ieee80211_send_eosp_nullfunc` usage
2. Fixes a real bug that affects users? **PASS** — stall / client freeze
   on common AP chipsets
3. Important issue? **PASS** — serious connectivity failure for U-APSD
   STAs (not a panic, but production-breaking for those devices)
4. Small and contained? **PASS** — one file, +63/−11
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — clean; APIs present

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: Not a device-ID/quirk/DT/build/docs exception. It is a **driver
protocol bugfix**.

**Step 9.4: DECISION**
Backport to this 5.15 tree. The bug exists here; the fix is self-
contained and applies cleanly. Companion commits `d5001f493fef` and
`636a883e2feef` are worth later evaluation but are not required for this
one.

---

### What the commit solves, and why it matters here

mt7603 implements its own `.release_buffered_frames` because hardware
redirects frames into a driver PS queue. That path tagged every frame
with `MORE_DATA` and never set EOSP on the air. mac80211 only saw
`ieee80211_sta_eosp()`, so the stack thought the SP ended while phones
waiting for EOSP stopped triggering. On 5.15 APs using `CONFIG_MT7603E`,
that is a real stall, not a cleanup.

### Stable rules / risk vs benefit

Surgical, obviously correct vs the documented U-APSD contract, no new
APIs, clean apply. Risk is limited to this driver’s PS release path.
Benefit is restoring downlink for power-save clients on a widely
deployed chipset.

### Concerns

Patches 06–08 (TIM clear, HW PS re-arm, TID filing) address **other**
remaining PS bugs. They are not compile or semantic prerequisites for
this hunk. Patch 04 is the analogous EOSP fix for chips that use generic
`mt76_release_buffered_frames`; mt7603 only hits that when its PS queue
is empty.

---

Verification:
- [Phase 1] Parsed subject/body/tags: Link is 05/10; author Felix
  Fietkau; no Fixes/Reported-by/Cc stable
- [Phase 2] Diff: +63/−11 in `mt7603_release_buffered_frames`;
  MORE_DATA+EOSP assignment; stop double SP end; QoS-Null for MMPDU
- [Phase 2] Confirmed `IEEE80211_QOS_CTL_EOSP` is 0x0010 and
  `ieee80211_get_qos_ctl()` returns `u8 *` to the first QoS byte
- [Phase 2] Confirmed `ieee80211_send_eosp_nullfunc()` in 5.15 sets
  `IEEE80211_TX_STATUS_EOSP` on the NDP; TX status clears `WLAN_STA_SP`
- [Phase 3] blame: `c8846e101502` / `b126c8897435` / `b7001f46085e`; all
  ancestors of HEAD
- [Phase 3] `git merge-base --is-ancestor 697badc27a9b3 HEAD` → not
  present
- [Phase 3] Follow-ups on origin/master: `d5001f493fef`, `636a883e2feef`
  only; no revert
- [Phase 4] `b4 dig -c 697badc27a9b3`: v1 series, msgid
  `20260801145334.1166751-5-nbd@nbd.name`
- [Phase 4] `b4 dig -w`: linux-wireless@ + author only
- [Phase 4] `b4 mbox`: 11 messages; robot fail is patch
  10/`ieee80211_txq_aql_pending`, unrelated
- [Phase 4] OpenWrt mt76#1084: EOSP-related change reported to stop
  iPhone freezes
- [Phase 5] ops hook `.release_buffered_frames =
  mt7603_release_buffered_frames`; callers are mac80211 PS-Poll/U-APSD
- [Phase 5] `ieee80211_send_eosp_nullfunc` exists and is exported in
  this tree; iwlwifi calls it from TX/BH
- [Phase 6] `make kernelversion` → 5.15.221; `git describe HEAD` →
  p-5.15-2-g6703e5d2f3a29
- [Phase 6] Byte-for-byte match of both functions vs `697badc27a9b3^`
- [Phase 7] `CONFIG_MT7603E` present for MT7603E/MT7628
- [Phase 8] Failure mode: downlink stall / client freeze, severity HIGH
  for that hardware
- UNVERIFIED: exhaustive stable@ archive search (lore HTTP 403); no
  evidence of a prior stable rejection

**YES**

 .../net/wireless/mediatek/mt76/mt7603/main.c  | 74 ++++++++++++++++---
 1 file changed, 63 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/main.c b/drivers/net/wireless/mediatek/mt76/mt7603/main.c
index 0d7c84941cd0a..f8a43d9f72f95 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/main.c
@@ -423,13 +423,33 @@ mt7603_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps)
 	mt7603_ps_tx_list(dev, &list);
 }
 
+static struct ieee80211_hdr *
+mt7603_ps_skb_hdr(struct sk_buff *skb)
+{
+	return (struct ieee80211_hdr *)&skb->data[MT_TXD_SIZE];
+}
+
+/*
+ * Buffered frames can be recycled into the PS queue by mt7603_filter_tx(), so
+ * both bits have to be assigned, not just set.
+ */
 static void
-mt7603_ps_set_more_data(struct sk_buff *skb)
+mt7603_ps_set_flags(struct sk_buff *skb, bool more_data, bool eosp)
 {
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr *hdr = mt7603_ps_skb_hdr(skb);
+
+	if (more_data)
+		hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
+	else
+		hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_MOREDATA);
+
+	if (!ieee80211_is_data_qos(hdr->frame_control))
+		return;
 
-	hdr = (struct ieee80211_hdr *)&skb->data[MT_TXD_SIZE];
-	hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
+	if (eosp)
+		*ieee80211_get_qos_ctl(hdr) |= IEEE80211_QOS_CTL_EOSP;
+	else
+		*ieee80211_get_qos_ctl(hdr) &= ~IEEE80211_QOS_CTL_EOSP;
 }
 
 static void
@@ -442,7 +462,10 @@ mt7603_release_buffered_frames(struct ieee80211_hw *hw,
 	struct mt7603_dev *dev = hw->priv;
 	struct mt7603_sta *msta = (struct mt7603_sta *)sta->drv_priv;
 	struct sk_buff_head list;
-	struct sk_buff *skb, *tmp;
+	struct sk_buff *skb, *tmp, *last;
+	bool eosp_null, uapsd;
+	u16 pending = 0;
+	u8 last_tid;
 
 	__skb_queue_head_init(&list);
 
@@ -458,20 +481,49 @@ mt7603_release_buffered_frames(struct ieee80211_hw *hw,
 
 		skb_set_queue_mapping(skb, MT_TXQ_PSD);
 		__skb_unlink(skb, &msta->psq);
-		mt7603_ps_set_more_data(skb);
 		__skb_queue_tail(&list, skb);
 		nframes--;
 	}
+
+	skb_queue_walk(&msta->psq, skb)
+		pending |= BIT(skb->priority);
 	spin_unlock_bh(&dev->ps_lock);
 
-	if (!skb_queue_empty(&list))
-		ieee80211_sta_eosp(sta);
+	last = skb_peek_tail(&list);
+	if (!last) {
+		mt76_release_buffered_frames(hw, sta, tids, nframes, reason,
+					     more_data);
+		return;
+	}
+
+	/*
+	 * End the service period here instead of passing the remaining frame
+	 * budget on to mt76_release_buffered_frames(), which would signal the
+	 * end of the same service period a second time.
+	 */
+	uapsd = reason == IEEE80211_FRAME_RELEASE_UAPSD;
+	more_data |= !!(pending & tids);
+
+	skb_queue_walk(&list, skb)
+		mt7603_ps_set_flags(skb, skb != last || more_data,
+				    skb == last && uapsd);
+
+	/*
+	 * EOSP lives in the QoS control field, so a bufferable MMPDU cannot
+	 * terminate a U-APSD service period on its own. In that case mac80211
+	 * has to append a QoS-Null frame, which ends the SP through its tx
+	 * status.
+	 */
+	eosp_null = uapsd &&
+		    !ieee80211_is_data_qos(mt7603_ps_skb_hdr(last)->frame_control);
+	last_tid = __fls(tids);
 
 	mt7603_ps_tx_list(dev, &list);
 
-	if (nframes)
-		mt76_release_buffered_frames(hw, sta, tids, nframes, reason,
-					     more_data);
+	if (eosp_null)
+		ieee80211_send_eosp_nullfunc(sta, last_tid);
+	else
+		ieee80211_sta_eosp(sta);
 }
 
 static int
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18-6.6] wifi: ath12k: fix scan command endianness on big endian
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (15 preceding siblings ...)
  2026-10-19 13:48 ` [PATCH AUTOSEL 6.18-5.10] wifi: mt76: mt7603: fix U-APSD service period termination Sasha Levin
@ 2026-10-19 13:48 ` Sasha Levin
  2026-10-19 13:48 ` [PATCH AUTOSEL 6.18-6.12] wifi: rtw89: wow: only WiFi 6 chips initialize RF registers in WoWLAN mode Sasha Levin
                   ` (23 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:48 UTC (permalink / raw)
  To: patches, stable
  Cc: Alexander Wilhelm, Rameshkumar Sundaram, Baochen Qiang,
	Jeff Johnson, Sasha Levin, jjohnson, linux-wireless, ath12k,
	linux-kernel

From: Alexander Wilhelm <alexander.wilhelm@westermo.com>

[ Upstream commit 6c90f68f97de591e0413f7d2de59449a0388bbab ]

ath12k_wmi_scan_req_arg stores scan parameters in CPU-native byte order,
while ath12k_wmi_send_scan_start_cmd() writes them into a WMI command
buffer whose contents must be in little-endian format. The existing code
copies the channel list and writes s_ssid and hint_bssid related values to
the command buffer without endian conversion. As a result, scan requests
contain invalid parameters on big-endian systems and fail.

Convert the channel list as well as the s_ssid and hint_bssid related
values to little-endian before writing them to the WMI command buffer. This
preserves the existing behaviour on little-endian systems while fixing scan
requests on big-endian architectures.

Signed-off-by: Alexander Wilhelm <alexander.wilhelm@westermo.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20260703-fix-channel-list-copy-v2-1-372c39306d79@westermo.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **v7.3-rc4** (mainline). The buggy ath12k scan path is
present here, and this is a small, real endianness fix for scan commands
on big-endian hosts.

---

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: PARSE THE SUBJECT LINE**
- Record: **[ath12k / wifi] [fix] [scan WMI command missing little-
  endian conversion on big-endian]**

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
- Record:
  - No `Fixes:` tag (expected for this review)
  - No `Reported-by:` / `Tested-by:` / `Cc: stable`
  - `Reviewed-by: Rameshkumar Sundaram
    <rameshkumar.sundaram@oss.qualcomm.com>` (Qualcomm ath12k)
  - `Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>`
    (Qualcomm ath12k)
  - `Link: https://patch.msgid.link/20260703-fix-channel-list-
    copy-v2-1-372c39306d79@westermo.com`
  - `Signed-off-by: Alexander Wilhelm <alexander.wilhelm@westermo.com>`
    (author; Westermo)
  - `Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>`
    (ath12k maintainer; applied)
  - Ignore pipeline-added Sasha Levin SOB if present (not on this
    commit)

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
- Record:
  - **Bug:** `ath12k_wmi_scan_req_arg` is CPU-endian; the WMI start-scan
    buffer must be little-endian. Channel list is `memcpy`'d; `s_ssid` /
    `hint_bssid` integers are assigned without `cpu_to_le32`.
  - **Symptom:** scan start commands carry invalid channel/hint values
    on big-endian; scans fail.
  - **Root cause:** missing endian conversion on those TLV payloads
    (other scalar fields in the same function already use
    `cpu_to_le32`).
  - **Version info:** none in the message. Buggy code dates to the
    original ath12k driver.

**Step 1.4: DETECT HIDDEN BUG FIXES**
- Record: **Not a hidden fix.** Subject and body state an endianness
  correctness bug. Not cleanup/refactor.

---

## PHASE 2: DIFF ANALYSIS

**Step 2.1: INVENTORY THE CHANGES**
- Record:
  - `drivers/net/wireless/ath/ath12k/wmi.c`: 20 insertions / 8 deletions
  - `drivers/net/wireless/ath/ath12k/wmi.h`: 10 insertions
  - **Net:** +22 / −8, two files
  - **Function:** `ath12k_wmi_send_scan_start_cmd()`
  - **Scope:** single-function surgical fix plus two local wire-format
    structs

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
- Record:
  - **Channel list:** `memcpy` of host `u32` channel frequencies → per-
    element `cpu_to_le32` into `__le32 *`.
  - **Hint short SSID:** raw `u32` assigns → `cpu_to_le32` into
    `ath12k_wmi_hint_short_ssid_params` (`__le32` fields).
  - **Hint BSSID:** `freq_flags` raw assign → `cpu_to_le32` into
    `ath12k_wmi_hint_bssid_params`.
  - **Normal path** (every scan start), not an error-only path. LE
    behavior unchanged (`cpu_to_le32` is identity on LE).

**Step 2.3: IDENTIFY THE BUG MECHANISM**
- Record: **[Type / endianness]** Host-endian `u32`s were placed in a LE
  WMI buffer. Firmware then sees swapped channel numbers (e.g. 2412 /
  `0x0000096c` becomes `0x6c090000`) and rejects or mis-handles the
  scan.

**Step 2.4: ASSESS THE FIX QUALITY**
- Record: **Obviously correct.** Same function already converts
  `num_chan`, dwell times, SSID length, etc. with `cpu_to_le32`. New
  `*_params` structs match existing `ath12k_wmi_ssid_params` (`__le32
  ssid_len`). **Regression risk: very low** on LE; no
  API/locking/refcount change. Review found a pre-existing swapped
  `ether_addr_copy` on hint BSSID; that was **not** mixed into this
  patch (separate commit `7b0bd40e97a00`).

---

## PHASE 3: GIT HISTORY INVESTIGATION

**Step 3.1: BLAME THE CHANGED LINES**
- Record: Buggy `memcpy(tmp_ptr, arg->chan_list, ...)` and hint field
  copies come from **`d889913205cf7` (“wifi: ath12k: driver for Qualcomm
  Wi-Fi 7 devices”)**, Kalle Valo, 2022-11-28. First appeared in
  **v6.3-rc1**. Long-lived, not recent churn.

**Step 3.2: FOLLOW THE FIXES: TAG**
- Record: **No `Fixes:` tag.** Introduction commit is `d889913205cf7`,
  ancestor of this HEAD (`git merge-base --is-ancestor` of the fix
  itself is true). This tree contains both the original driver and the
  fix.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
- Record:
  - Immediate predecessor on this function: `7b0bd40e97a00` “Correctly
    copy the hint BSSID in WMI scan request” (same day in the ath tree).
    Independent bug (copy direction).
  - Later `wmi.c` commits (`c42b27336eeff`, TLV/overread fixes) do
    **not** revert or rework this endian conversion.
  - Same author earlier: `9eb6f553026e1` “enforce CPU endian format for
    all QMI data” — same BE enablement effort.
  - **Standalone** for the endian bug; not patch N/M of a series (v2 of
    a single patch).

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
- Record: Alexander Wilhelm (Westermo) has ath12k BE work; not the
  subsystem maintainer. Applied by **Jeff Johnson** (Qualcomm ath12k
  maintainer) after Qualcomm reviews.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
- Record: No new helpers. Uses existing `cpu_to_le32`. Hint `*_params`
  structs are added in this patch. `7b0bd40e97a00` is **not** a semantic
  prerequisite for channel-list conversion; it only changes
  `ether_addr_copy` argument order. **Can apply standalone** (possible
  one-hunk context mismatch on trees that still have the swapped copy).

---

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
- Record:
  - Lore/msgid: `https://patch.msgid.link/20260703-fix-channel-list-
    copy-v2-1-372c39306d79@westermo.com`
  - **v1:** 2026-03-17? (msgid dated 2026-06-29) “fix channel list copy
    on big endian”
  - **v2:** 2026-07-03 “fix scan command endianness on big endian” —
    rebase; also convert `s_ssid` / `hint_bssid`; reworded message
  - Applied version is **v2** (latest).
  - **No NAK.** Baochen asked whether to also fix swapped
    `ether_addr_copy`; Jeff: **separate patch**. Rameshkumar and Baochen
    `Reviewed-by`. Jeff: “Applied, thanks!”
  - **No reviewer `Cc: stable`.**

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
- Record: Recipients: Jeff Johnson, Baochen Qiang, `linux-wireless`,
  `ath12k@lists.infradead.org`, `linux-kernel`. Right maintainers/lists.
  Two Qualcomm `Reviewed-by`s; maintainer applied it.

**Step 4.3: SEARCH FOR THE BUG REPORT**
- Record: No syzbot/bugzilla. Author is a vendor using BE + ath12k
  (consistent with their prior QMI endian patch). Failure mode described
  as scan failure, not a crash dump.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
- Record: Single-patch series. Related: `7b0bd40e97a00` (hint BSSID copy
  direction), prompted by Baochen on this thread. Not required for the
  channel-list endian fix.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
- Record: No stable-list discussion found for this subject. WebSearch on
  `lore.kernel.org/stable` did not return this patch. **UNVERIFIED**
  beyond that search (lore.kernel.org HTTP 403 from this environment).

---

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1: IDENTIFY KEY FUNCTIONS**
- Record: `ath12k_wmi_send_scan_start_cmd()` only. New structs:
  `ath12k_wmi_hint_short_ssid_params`, `ath12k_wmi_hint_bssid_params`.

**Step 5.2: TRACE CALLERS**
- Record:
  - `ath12k_wmi_send_scan_start_cmd` ← `ath12k_start_scan`
    (`mac.c:5407`)
  - `ath12k_start_scan` ← hw scan (`mac.c:5727`, fills `chan_list[i] =
    chan_list[i]->center_freq`)
  - `ath12k_start_scan` ← remain-on-channel (`mac.c:14062`,
    `chan_list[0] = chan->center_freq`)
  - **Userspace-reachable** via nl80211 scan / ROC. Not IRQ.

**Step 5.3: TRACE CALLEES**
- Record: Builds a WMI skb (`ath12k_wmi_alloc_skb`), fills TLVs,
  `ath12k_wmi_cmd_send(..., WMI_START_SCAN_CMDID)`. Firmware then runs
  the scan.

**Step 5.4: FOLLOW THE CALL CHAIN**
- Record: cfg80211/mac80211 scan or ROC → `ath12k_mac` → WMI start-scan.
  **Yes, userspace-triggerable.** Channel list is always filled on those
  paths. `num_hint_s_ssid` / `num_hint_bssid` are **never assigned** in
  this tree (stay 0 from `kzalloc`); hint conversions are still correct
  but not the live bug. **The live bug is the channel list on every
  scan/ROC.**

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
- Record: Other fields in the same command already use `cpu_to_le32`.
  `ath12k_wmi_ssid_params` already has `__le32 ssid_len`. Sibling ath11k
  `ath11k_wmi_send_scan_start_cmd` still copies `chan_list` as host
  `u32` without `cpu_to_le32` (ath11k WMI structs are less consistently
  `__le32`). Other ath12k endian fixes exist (`2adcddd8a316e` vdev
  create, `8f1a078842d4a` WMI service bits, `1cfa6d4e5bd9b` HAL TLV).

---

## PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
- Record: **Yes.** Tree is **v7.3-rc4** (`7.3.0-rc4`, HEAD
  `f0100363d8c37`). ath12k and `ath12k_wmi_send_scan_start_cmd` exist.
  Bug introduced **v6.3**; not after this branch. The fix commit
  `6c90f68f97de5` is already an ancestor of HEAD; current `wmi.c`
  already has the `cpu_to_le32` channel loop. Evaluating technical merit
  for this codebase, not “already queued.”

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
- Record: **Clean apply here** (already present). New structs are
  additive. On older stables without `7b0bd40e97a00`, one
  `ether_addr_copy` context hunk may need a trivial refresh; channel-
  list hunk is independent.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
- Record: This exact fix is in the tree. No alternate/earlier endian fix
  for this memcpy. No revert.

---

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
- Record: **wifi / ath12k (Qualcomm Wi-Fi 7)** — **IMPORTANT** (not
  mm/core; real devices and scan/ROC depend on it).

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
- Record: **Active** (frequent `wmi.c` fixes). This particular memcpy
  has been wrong since the driver landed in v6.3.

---

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: DETERMINE WHO IS AFFECTED**
- Record: **Driver-specific + endian-specific:** `CONFIG_ATH12K` on big-
  endian CPUs. LE ath12k (typical x86/ARM) unchanged. Author affiliation
  indicates real BE industrial use.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
- Record: **Any scan or remain-on-channel.** Common for Wi-Fi (network
  manager, `iw scan`, P2P/ROC). Unprivileged users can trigger scans
  depending on policy; not a UAF/crash primitive. Not a race.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
- Record: **Scan/ROC commands invalid on BE → scan fails / association
  cannot find APs.** Not oops/deadlock/corruption. **Severity: HIGH**
  for BE ath12k (driver largely unusable for STA), **LOW** for LE
  majority.

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
- Record:
  - **Benefit:** Restores scanning on BE ath12k; no-op on LE.
  - **Risk:** Very low (~22 lines, `cpu_to_le32` only, internal
    structs).
  - **Ratio:** Favorable. Classic endianness driver fix.

---

## PHASE 9: FINAL SYNTHESIS

**Step 9.1: COMPILE THE EVIDENCE**

**FOR backporting:**
- Real, user-visible bug: WMI scan channel list (and hint integers) not
  converted to LE.
- Hits every hw scan and ROC on BE; firmware gets garbage channel
  numbers.
- Small, matches existing conversions in the same function.
- Present since v6.3; this tree has the driver.
- Reviewed and applied by Qualcomm ath12k maintainers; v2 addressed
  review (hints + rebase).
- `cpu_to_le32` is identity on LE → negligible regression risk.
- Endianness/type bugs are a documented stable category.

**AGAINST:**
- Not crash/UAF/security/deadlock.
- BE + ath12k is a smaller population than x86/ARM LE.
- No `Fixes:` / `Cc: stable` / syzbot (absence expected; not a
  negative).
- Hint paths appear unused in this tree (still correct to convert).

**UNRESOLVED:**
- Full lore.kernel.org HTML was 403; thread recovered via `b4 dig -m`.
- No stable-list thread found.
- No in-tree test proving a specific BE board besides the author’s
  description.

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — same conversion pattern as
   the rest of the command; Qualcomm review + maintainer apply. Author
   exercised BE.
2. Fixes a real bug that affects users? **PASS** — scans fail on BE.
3. Important issue? **PASS** — Wi-Fi scan/ROC broken on affected systems
   (endianness correctness), not a style tweak.
4. Small and contained? **PASS** — two files, +22/−8, one function.
5. No new features or APIs? **PASS** — internal `__le32` wire structs
   only.
6. Can apply to the local tree? **PASS** — ath12k WMI scan path exists
   here; hunks match.

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
- Record: Not a device-ID/quirk/DT/build/docs exception. Standard
  correctness fix.

**Step 9.4: MAKE YOUR DECISION**
This tree has the ath12k scan WMI path introduced in v6.3. Missing
`cpu_to_le32` on the channel list makes scanning fail on big-endian; the
patch is small, matches existing WMI encoding, and is a no-op on little-
endian. It meets stable rules for this checkout.

---

## What the commit solves and why it matters

`ath12k_wmi_send_scan_start_cmd()` already converted scalar WMI fields
with `cpu_to_le32`, but copied `chan_list` with `memcpy` and assigned
hint integers in CPU order. On big-endian, firmware sees swapped
frequencies, so scan/ROC fail. Stable users of ath12k on BE cannot scan
or remain-on-channel without this. LE users see no behavior change.

## Risk vs benefit

Benefit is restoring a core Wi-Fi operation on BE. Risk is very low:
surgical conversions, no locking/API change, identity transform on LE.

## Concerns

No functional dependency on other patches for the channel-list fix. Hint
BSSID `ether_addr_copy` direction is a separate commit already in this
tree. Backport to older stables may need a one-line context tweak if
that copy-direction fix is absent.

---

## Verification
- [Phase 1] Parsed tags: two Qualcomm `Reviewed-by`; maintainer SOB;
  msgid.link; no Fixes/stable/syzbot
- [Phase 2] Diff: `wmi.c` + `wmi.h`, +22/−8; `memcpy` → `cpu_to_le32`
  loop; hint fields converted; two `__le32` structs added
- [Phase 3] `git describe HEAD`: `v7.3-rc4-27-gf0100363d8c37`; `make
  kernelversion`: `7.3.0-rc4`
- [Phase 3] `git merge-base --is-ancestor 6c90f68f97de5 HEAD`: yes (exit
  0)
- [Phase 3] `git blame` on parent: buggy memcpy/assigns from
  `d889913205cf7` (v6.3-rc1)
- [Phase 3] Related: `7b0bd40e97a00` hint BSSID copy; `9eb6f553026e1`
  QMI endian; no revert after this fix
- [Phase 4] `b4 dig -c 6c90f68f97de5`: v2 msgid `20260703-fix-channel-
  list-copy-v2-1-372c39306d79@westermo.com`
- [Phase 4] `b4 dig -a`: v1 channel-list-only → v2 also converts hints
- [Phase 4] `b4 dig -w`: Jeff Johnson, Baochen Qiang, linux-wireless,
  ath12k list
- [Phase 4] mbox: Baochen/Rameshkumar R-b; Jeff applied; swapped
  `ether_addr_copy` deferred to separate patch (no NAK of endian fix)
- [Phase 4] lore.kernel.org fetch: 403; used b4 mbox + mirrors
- [Phase 4] stable list search: no discussion found
- [Phase 5] Callers: `ath12k_start_scan` ← hw scan (`mac.c:5727`) and
  ROC (`mac.c:14062`); both write `chan_list` as `center_freq`
- [Phase 5] `num_hint_*` never assigned in ath12k (remain 0)
- [Phase 6] Current tree already contains the converted loop at
  `wmi.c:2739-2740`
- [Phase 8] Failure: invalid WMI scan params on BE → scan failure; not
  oops
- UNVERIFIED: specific BE board log beyond commit text; full lore HTML

**YES**

 drivers/net/wireless/ath/ath12k/wmi.c | 20 ++++++++++++--------
 drivers/net/wireless/ath/ath12k/wmi.h | 10 ++++++++++
 2 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index 39d5110eca901..91f293ab70137 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -2666,9 +2666,10 @@ int ath12k_wmi_send_scan_start_cmd(struct ath12k *ar,
 	struct wmi_tlv *tlv;
 	void *ptr;
 	int i, ret, len;
-	u32 *tmp_ptr, extraie_len_with_pad = 0;
-	struct ath12k_wmi_hint_short_ssid_arg *s_ssid = NULL;
-	struct ath12k_wmi_hint_bssid_arg *hint_bssid = NULL;
+	__le32 *tmp_ptr;
+	u32 extraie_len_with_pad = 0;
+	struct ath12k_wmi_hint_short_ssid_params *s_ssid = NULL;
+	struct ath12k_wmi_hint_bssid_params *hint_bssid = NULL;
 
 	len = sizeof(*cmd);
 
@@ -2751,9 +2752,10 @@ int ath12k_wmi_send_scan_start_cmd(struct ath12k *ar,
 	tlv = ptr;
 	tlv->header = ath12k_wmi_tlv_hdr(WMI_TAG_ARRAY_UINT32, len);
 	ptr += TLV_HDR_SIZE;
-	tmp_ptr = (u32 *)ptr;
+	tmp_ptr = (__le32 *)ptr;
 
-	memcpy(tmp_ptr, arg->chan_list, arg->num_chan * 4);
+	for (i = 0; i < arg->num_chan; i++)
+		tmp_ptr[i] = cpu_to_le32(arg->chan_list[i]);
 
 	ptr += len;
 
@@ -2809,8 +2811,10 @@ int ath12k_wmi_send_scan_start_cmd(struct ath12k *ar,
 		ptr += TLV_HDR_SIZE;
 		s_ssid = ptr;
 		for (i = 0; i < arg->num_hint_s_ssid; ++i) {
-			s_ssid->freq_flags = arg->hint_s_ssid[i].freq_flags;
-			s_ssid->short_ssid = arg->hint_s_ssid[i].short_ssid;
+			s_ssid->freq_flags =
+				cpu_to_le32(arg->hint_s_ssid[i].freq_flags);
+			s_ssid->short_ssid =
+				cpu_to_le32(arg->hint_s_ssid[i].short_ssid);
 			s_ssid++;
 		}
 		ptr += len;
@@ -2824,7 +2828,7 @@ int ath12k_wmi_send_scan_start_cmd(struct ath12k *ar,
 		hint_bssid = ptr;
 		for (i = 0; i < arg->num_hint_bssid; ++i) {
 			hint_bssid->freq_flags =
-				arg->hint_bssid[i].freq_flags;
+				cpu_to_le32(arg->hint_bssid[i].freq_flags);
 			ether_addr_copy(&hint_bssid->bssid.addr[0],
 					&arg->hint_bssid[i].bssid.addr[0]);
 			hint_bssid++;
diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h
index 6d9c645e3d5d0..6468d9738639e 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.h
+++ b/drivers/net/wireless/ath/ath12k/wmi.h
@@ -3504,6 +3504,16 @@ struct ath12k_wmi_hint_bssid_arg {
 	struct ath12k_wmi_mac_addr_params bssid;
 };
 
+struct ath12k_wmi_hint_short_ssid_params {
+	__le32 freq_flags;
+	__le32 short_ssid;
+};
+
+struct ath12k_wmi_hint_bssid_params {
+	__le32 freq_flags;
+	struct ath12k_wmi_mac_addr_params bssid;
+};
+
 struct ath12k_wmi_scan_req_arg {
 	u32 scan_id;
 	u32 scan_req_id;
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18-6.12] wifi: rtw89: wow: only WiFi 6 chips initialize RF registers in WoWLAN mode
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (16 preceding siblings ...)
  2026-10-19 13:48 ` [PATCH AUTOSEL 6.18-6.6] wifi: ath12k: fix scan command endianness on big endian Sasha Levin
@ 2026-10-19 13:48 ` Sasha Levin
  2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-5.15] wifi: mt76: mt7603: add 0x7592 EEPROM chip ID Sasha Levin
                   ` (22 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:48 UTC (permalink / raw)
  To: patches, stable
  Cc: Chih-Kang Chang, Ping-Ke Shih, Sasha Levin, linux-wireless,
	linux-kernel

From: Chih-Kang Chang <gary.chang@realtek.com>

[ Upstream commit dbff9040587e9bd6d3ee337315971957f9f76612 ]

Only the WiFi 6 chips need to initialize RF register when WoWLAN download
FW for some power save issue. Applying the same initialization flow to
WiFi 7 chips might trigger the error
'RF parameters exceed size. path=1, idx=1500.'.

This happens because normal mode uses rtw89_phy_config_rf_reg_v1(), which
skips registers with addresses below 0x100. However, WoWLAN mode uses
rtw89_phy_config_rf_reg_noio(), and WiFi 7 chips do not satisfy the
rtw89_chip_rf_v1() condition. As a result, more RF registers are
configured, causing the size overflow error.

Signed-off-by: Chih-Kang Chang <gary.chang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260625061545.44808-11-pkshih@realtek.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local checkout is **Linux 7.3.0-rc4** (`v7.3-rc4-27-gf0100363d8c37`,
`origin/master`). This tree already contains rtw89 WiFi 7
(RTL8922A/RTL8922D) with WoWLAN, which is the path the overflow hits.

---

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: PARSE THE SUBJECT LINE**
- Record: `[wifi: rtw89: wow] [only … initialize] [gate WoWLAN RF
  register init to WiFi 6 / CHIP_AX]`
- Subsystem: Realtek rtw89 WoWLAN. The verb is a restriction (“only …
  initialize”), i.e. stop a wrong flow on WiFi 7.

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
- Record:
  - `Signed-off-by: Chih-Kang Chang <gary.chang@realtek.com>` (author)
  - `Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>` (rtw89
    maintainer; applied to rtw-next)
  - `Link:
    https://patch.msgid.link/20260625061545.44808-11-pkshih@realtek.com`
  - No `Fixes:`, no `Reported-by:`, no `Tested-by:`, no `Reviewed-by:`,
    no `Cc: stable` (absence is expected)
  - Ignore pipeline `Signed-off-by: Sasha Levin` / `[Upstream commit …]`
    if present — not in the git object

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
- Record:
  - **Bug:** WoWLAN firmware swap always calls
    `rtw89_phy_init_rf_reg(rtwdev, true)`. That is needed only on WiFi 6
    (AX) for a power-save issue.
  - **Symptom:** On WiFi 7, `'RF parameters exceed size. path=1,
    idx=1500.'`
  - **Root cause:** Normal mode uses `rtw89_phy_config_rf_reg_v1()`,
    which skips RF addresses `< 0x100`. WoWLAN uses
    `rtw89_phy_config_rf_reg_noio()`, which skips `< 0x100` only when
    `rtw89_chip_rf_v1()` is true. WiFi 7 chips use `write_rf_v2`/`v3`,
    so they do not skip those registers, fill more than 1500 H2C slots,
    and hit the size cap.
  - **Version info:** none in the message.

**Step 1.4: DETECT HIDDEN BUG FIXES**
- Record: Not hidden. It is an explicit chip-generation bug fix (wrong
  RF init on BE causing H2C RF table overflow).

---

## PHASE 2: DIFF ANALYSIS

**Step 2.1: INVENTORY THE CHANGES**
- Record: `drivers/net/wireless/realtek/rtw89/wow.c` — 2 insertions, 1
  deletion. Function: `rtw89_wow_swap_fw()`. Scope: single-file, one-
  call gate.

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
- Record: After WoWLAN/normal FW download, the code **always** collected
  RF regs with `noio=true` and sent them via H2C. After the fix, that
  runs **only** if `chip->chip_gen == RTW89_CHIP_AX`. WiFi 7
  (`RTW89_CHIP_BE`) skips it. BE already has a separate restore:
  `rtw89_phy_rfk_pre_ntfy_and_wait()` later in the same function.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
- Record: **Logic / hardware-generation mismatch**, not a kernel buffer
  overwrite.
  - Store path in `rtw89_phy_cofig_rf_reg_store()`:
    - `RTW89_H2C_RF_PAGE_SIZE == 500`, `RTW89_H2C_RF_PAGE_NUM == 3` →
      cap **1500**
    - `idx=1500` ⇒ `page = 3 >= 3` → `rtw89_warn(...)` and **drop** the
      register (no OOB write)
  - Extra entries are dropped; 1500 params are still sent. Result:
    warning spam + incomplete RF programming of WoWLAN FW.
  - Category: hardware/chip-gen workaround + functional correctness of
    suspend/WoWLAN.

**Step 2.4: ASSESS THE FIX QUALITY**
- Record: Obviously correct. `chip` is already `rtwdev->chip` in this
  function; `RTW89_CHIP_AX` is the existing gen enum. AX still gets the
  power-save RF init; BE does not. Regression risk is low: BE never
  needed this path (vendor statement + separate RFK notify). No
  API/data-structure change.

---

## PHASE 3: GIT HISTORY INVESTIGATION

**Step 3.1: BLAME THE CHANGED LINES**
- Record: Unconditional `rtw89_phy_init_rf_reg(rtwdev, true)` came from
  `19e28c7fcc740` (“wifi: rtw89: add WoWLAN function support”,
  2022-10-27, in v6.2-rc1). The `noio` collector is `d9112042d994` (same
  era). The bug becomes real when WiFi 7 chips (empty `rf_table`,
  firmware `rf_radio[]` elements, `write_rf` not v1) run that WoWLAN
  path. RTL8922A chip info: `c0a04552e36e1` (~v6.8). RTL8922D is newer
  (2026).

**Step 3.2: FOLLOW THE FIXES: TAG**
- Record: No `Fixes:` tag. Not applicable.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
- Record: Nearby wow.c work is MLO ARP, 8922D interrupt disable, cipher
  messages — independent. This is **10/10** of a mixed rtw-next series,
  not a dependent chain. Cover letter: independent MAC/FW/PCI/WoWLAN
  items; this patch does not need 01–09.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
- Record: Chih-Kang Chang is a regular Realtek rtw89 contributor. Ping-
  Ke Shih is the **rtw89 maintainer** (MAINTAINERS) and applied the
  series to rtw-next.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
- Record: Standalone. Needs only `chip->chip_gen` / `RTW89_CHIP_AX`
  (present since `f698afa7ce374`, 2023) and `rtw89_phy_init_rf_reg()`.
  Both exist in this tree. No new helpers.

---

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
- Record: `b4 dig -c dbff9040587e9` →
  https://patch.msgid.link/20260625061545.44808-11-pkshih@realtek.com
  - Series: `[PATCH rtw-next 00/10] wifi: rtw89: update some MAC, FW and
    WoWLAN settings`
  - This commit is **10/10**. `b4 dig -a`: only **v1**.
  - Cover letter does not call out this patch as the headline fix (it
    highlights 4/10 scan and 7/10 typo). No reviewer NAK. Maintainer
    applied all 10 to rtw-next (mbox reply 2026-07-03).
  - No `Cc: stable` in the thread.

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
- Record: `b4 dig -w` To/Cc: Ping-Ke Shih, linux-wireless, gary.chang,
  timlee, dian_syuan0116, kevin_yang (all Realtek rtw89). No external
  Reviewed-by. Maintainer SOB + apply is the review signal.

**Step 4.3: SEARCH FOR THE BUG REPORT**
- Record: No public bugzilla/syzbot. The message quotes a concrete
  driver warning (`path=1, idx=1500`), which matches the H2C cap.
  Vendor-observed, not a user mailing-list report.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
- Record: Series mates (MAC TX complete, chip version to FW, UDM1 log
  level, packet offload drop, sniffer RX filter, PCI phy error, LPS MLO
  link ID, MLO ARP) are **not** prerequisites of this 2-line gate.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
- Record: **UNVERIFIED.** lore.kernel.org returned HTTP 403 for
  `/stable/` and thread HTML. mbox from `b4 dig -m` had no stable
  discussion.

---

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1: IDENTIFY KEY FUNCTIONS**
- Record: `rtw89_wow_swap_fw()`; callees of interest:
  `rtw89_phy_init_rf_reg()`, `rtw89_phy_config_rf_reg_noio()`,
  `rtw89_phy_cofig_rf_reg_store()`.

**Step 5.2: TRACE CALLERS**
- Record: `rtw89_wow_swap_fw()` is called from `rtw89_wow_enable()`
  (wow=true) and `rtw89_wow_disable()` (wow=false). Those are called
  from `rtw89_wow_suspend()` / resume. `rtw89_ops_suspend()` in
  `mac80211.c` is the mac80211 suspend op (`CONFIG_PM`). Reachable from
  userspace suspend with WoWLAN (NetworkManager magic-
  packet/disconnect/net-detect). Not a syscall crash path; it is a
  common laptop suspend path.

**Step 5.3: TRACE CALLEES**
- Record: `rtw89_phy_init_rf_reg(noio=true)` walks firmware or chip RF
  tables and stores H2C pages (no MMIO). Overflow is handled as
  warn+drop, then `rtw89_phy_config_rf_reg_fw()` still sends up to 1500
  entries.

**Step 5.4: FOLLOW THE CALL CHAIN**
- Record: userspace suspend → `ieee80211` suspend → `rtw89_ops_suspend`
  → `rtw89_wow_suspend` → `rtw89_wow_enable` → `rtw89_wow_swap_fw` → RF
  init. **Yes, reachable** on RTL8922A/D with WoWLAN enabled. Both chips
  have `wowlan_stub` in this tree.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
- Record: Same function already special-cases BE
  (`rtw89_phy_rfk_pre_ntfy_and_wait`) and AX (`disable_intr_for_dlfw`).
  This gate matches that pattern. `rtw89_chip_rf_v1()` is true only for
  8852B/BT/C and 8851B (`write_rf_v1`). 8852A is AX but not rf_v1 —
  still correctly keeps RF init because the new check is `CHIP_AX`, not
  `chip_rf_v1()`.

---

## PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
- Record: **Yes, the affected stack exists.** This tree has
  `RTW89_CHIP_BE` chips (`rtw8922a.c`, `rtw8922d.c`) with WoWLAN stubs,
  firmware `rf_radio[]` tables, `write_rf` v2/v3 (so
  `rtw89_chip_rf_v1()` is false), and `rtw89_wow_swap_fw()`.
- The **unconditional** call is already replaced here by commit
  `dbff9040587e9` (ancestor of HEAD). That is this tree’s current code,
  not a reason to treat the bug as fictional: without this change, BE
  WoWLAN still hits the 1500-entry cap.
- Bug introduced relative to this codebase: WoWLAN RF collect since
  v6.2; overflow on BE once WiFi 7 + firmware radio tables are used
  (8922A from ~6.8, 8922D in this 7.3 cycle).

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
- Record: On **this** 7.3-rc4 tree the hunk is already applied; a re-
  apply would be empty. Context (`chip`, `RTW89_CHIP_AX`,
  `rtw89_phy_init_rf_reg`) matches. Expected difficulty if it were
  missing: **clean apply**.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
- Record: This is the fix. Follow-ups on wow.c (`73aecc221e7df` cipher
  debug, `d946a4e031167` scan V3) do not replace it. No revert.

---

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
- Record: `[drivers/net/wireless/realtek/rtw89]` — **IMPORTANT**
  (shipping WiFi 6/7, not core mm/VFS). Not staging.

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
- Record: Actively developed (WiFi 7 8922D, MLO WoWLAN). Maintainer:
  Ping-Ke Shih. Mature AX WoWLAN plus newer BE support.

---

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: DETERMINE WHO IS AFFECTED**
- Record: **Driver-specific / config-specific:** `CONFIG_PM` + rtw89 +
  RTL8922A or RTL8922D (and any other BE chip using this wow path). AX
  users unchanged.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
- Record: Suspend/resume with WoWLAN (or wow FW swap on resume). Common
  on laptops. Unprivileged users cannot directly invoke it; suspend
  typically needs policy/login, but it is a normal user flow. Not a
  race.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
- Record: **MEDIUM (functional HIGH for affected NICs).** Not a
  KASAN/UAF/panic. Verified: no kernel OOB write. User-visible:
  `rtw89_warn` (can repeat per extra register) and truncated RF H2C, so
  WoWLAN/power-save RF state on WiFi 7 can be wrong (failed wake or bad
  RF after resume). That is a real suspend bug, not cosmetic-only.

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
- Record: **Benefit: high for BE WoWLAN users in this tree. Risk: very
  low** (2 lines, existing enum, AX path unchanged). Ratio favors
  applying it.

---

## PHASE 9: FINAL SYNTHESIS

**Step 9.1: COMPILE THE EVIDENCE**

FOR:
- Real, vendor-documented overflow of the 1500-slot RF H2C table on WiFi
  7 WoWLAN (`idx=1500` = `3*500`).
- This tree **has** BE chips with WoWLAN; the wrong `noio` path is used
  because they are not `rf_v1`.
- 2-line, obviously correct gen check; AX still initialized; BE already
  uses RFK pre-notify.
- Maintainer SOB and applied to rtw-next; self-contained despite 10/10
  series.
- Typical stable-class hardware/suspend workaround.

AGAINST:
- Not a crash, UAF, deadlock, or security bug.
- No `Fixes:` / public user reports / syzbot.
- Warning-and-drop, not memory corruption.
- Only rtw89 WiFi 7 + WoWLAN.

UNRESOLVED:
- lore `/stable/` search 403; no confirmation of prior stable
  discussion.
- Exact user-visible radio failure beyond the warning is vendor-
  described, not independently reproduced here.

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — mechanism matches code;
   maintainer applied.
2. Fixes a real bug that affects users? **PASS** — BE WoWLAN RF H2C
   overflow/truncation on suspend.
3. Important issue? **PASS** (medium-high functional / suspend) — not
   panic, but broken WoWLAN RF on shipping WiFi 7 is important for this
   tree.
4. Small and contained? **PASS** — 2 lines, one function.
5. No new features or APIs? **PASS**.
6. Can apply to the local tree? **PASS** — context exists; already
   present as `dbff9040587e9`.

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
- Record: Hardware workaround / chip-generation quirk (do not run AX-
  only RF init on BE). Qualifies under quirks/workarounds.

**Step 9.4: MAKE YOUR DECISION**
This tree is 7.3-rc4 with RTL8922A/8922D WoWLAN. The bug is real here:
firmware RF tables plus `rtw89_phy_config_rf_reg_noio()` without the v1
`< 0x100` skip overflow the 1500-entry H2C buffer and mis-init RF during
wow FW swap. The fix is a one-condition guard, no series dependency, no
new API. Benefit outweighs risk.

---

## What the commit solves for this tree

On WiFi 7 rtw89, WoWLAN firmware download used the WiFi 6 “collect RF
regs, no MMIO” path. BE chips are not `rf_v1`, so addresses `< 0x100`
were included, `curr_idx` hit 1500, and the driver warned and dropped
the rest. Suspend/WoWLAN RF programming was incomplete. Gating on
`RTW89_CHIP_AX` restores the intended split: AX keeps the power-save RF
init; BE keeps RFK notify only.

It meets stable rules: small, correct, no features, real user-facing
suspend bug on hardware this tree supports. Risk is negligible.

## Verification
- [Phase 1] Parsed git object `dbff9040587e9`: SOB Chang + Shih, Link
  msgid `…44808-11…`; no Fixes/Reported-by/Cc: stable
- [Phase 2] Diff: wow.c `rtw89_wow_swap_fw`: wrap
  `rtw89_phy_init_rf_reg(rtwdev, true)` in `chip->chip_gen ==
  RTW89_CHIP_AX`
- [Phase 2] `fw.h`: `RTW89_H2C_RF_PAGE_SIZE 500`, `PAGE_NUM 3` → 1500;
  `phy.c` warns at `page >= PAGE_NUM` without OOB store
- [Phase 2] `rtw89_chip_rf_v1()` is `write_rf == rtw89_phy_write_rf_v1`;
  8922A=`v2`, 8922D=`v3`; 8852B/C/BT/8851B=`v1`
- [Phase 3] blame: RF init from `19e28c7fcc740` (v6.2-rc1); chip_gen
  from `f698afa7ce374`; 8922A `c0a04552e36e1`
- [Phase 3] `git merge-base --is-ancestor dbff9040587e9 HEAD` → yes
  (already in this 7.3-rc4 tree)
- [Phase 3] Series 0819de0fd2906..dbff9040587e9 is 10 independent rtw-
  next patches; this one only touches wow.c
- [Phase 4] `b4 dig -c dbff9040587e9`: lore thread found; `-a` v1 only;
  `-w` linux-wireless + Realtek; `-m` 12 msgs, maintainer “10 patch(es)
  applied”
- [Phase 4] WebFetch lore HTML: 403; stable-list search UNVERIFIED
- [Phase 5] Call chain: `rtw89_ops_suspend` → `rtw89_wow_suspend` →
  `rtw89_wow_enable` → `rtw89_wow_swap_fw`; 8922A/D have `wowlan_stub`
- [Phase 5] BE path already calls `rtw89_phy_rfk_pre_ntfy_and_wait` in
  the same function
- [Phase 6] `git describe HEAD` = `v7.3-rc4-27-gf0100363d8c37`;
  `VERSION=7 PATCHLEVEL=3 EXTRAVERSION=-rc4`
- [Phase 6] Current wow.c already has the AX gate (this commit)
- [Phase 7] MAINTAINERS: Ping-Ke Shih maintains rtw89
- [Phase 8] Failure mode verified as warn+truncate, not kernel memory
  overflow; severity MEDIUM/HIGH functional for BE WoWLAN
- UNVERIFIED: independent reproduction of failed wake; stable@
  discussion (lore 403)

**YES**

 drivers/net/wireless/realtek/rtw89/wow.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c
index f6cdbc15dcc4a..90046d6f620ef 100644
--- a/drivers/net/wireless/realtek/rtw89/wow.c
+++ b/drivers/net/wireless/realtek/rtw89/wow.c
@@ -1299,7 +1299,8 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow)
 	if (disable_intr_for_dlfw)
 		rtw89_hci_enable_intr(rtwdev);
 
-	rtw89_phy_init_rf_reg(rtwdev, true);
+	if (chip->chip_gen == RTW89_CHIP_AX)
+		rtw89_phy_init_rf_reg(rtwdev, true);
 
 	ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, rtwsta_link,
 					 RTW89_ROLE_FW_RESTORE);
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18-5.15] wifi: mt76: mt7603: add 0x7592 EEPROM chip ID
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (17 preceding siblings ...)
  2026-10-19 13:48 ` [PATCH AUTOSEL 6.18-6.12] wifi: rtw89: wow: only WiFi 6 chips initialize RF registers in WoWLAN mode Sasha Levin
@ 2026-10-19 13:49 ` Sasha Levin
  2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7615: fix NULL deref in mt7615_mac_set_rates Sasha Levin
                   ` (21 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:49 UTC (permalink / raw)
  To: patches, stable
  Cc: Ahmed Naseef, Felix Fietkau, Sasha Levin, lorenzo, ryder.lee,
	matthias.bgg, angelogioacchino.delregno, linux-wireless,
	linux-kernel, linux-arm-kernel, linux-mediatek

From: Ahmed Naseef <naseefkm@gmail.com>

[ Upstream commit d16447d7470502e998d82e806ca7ed49d1baa853 ]

Some EcoNet based routers ship an on-flash EEPROM whose chip-id is
0x7592 instead of the expected 0x7603. The device probes as PCI
14c3:7603 and the hardware MT_HW_CHIPID register reports 0x7603,
independent of the EEPROM value.

This is seen across multiple EcoNet EN751221 and EN7528 based devices
(for example the Genexis Platinum 4410).

Signed-off-by: Ahmed Naseef <naseefkm@gmail.com>
Link: https://patch.msgid.link/20260719082530.3879831-1-naseefkm@gmail.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The evaluation target is **pending-6.6 (6.6.157)**. The mt7603 driver is
present; the 0x7592 EEPROM ID is not. This is a one-line ID addition to
an existing driver, which is a standard stable exception.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

Step 1.1: PARSE THE SUBJECT LINE
Record: [wifi: mt76: mt7603] [add] [accept EEPROM chip ID 0x7592 in
mt7603_check_eeprom]

Step 1.2: PARSE ALL COMMIT MESSAGE TAGS
Record:
- Signed-off-by: Ahmed Naseef \<naseefkm@gmail.com\> (author)
- Link:
  https://patch.msgid.link/20260719082530.3879831-1-naseefkm@gmail.com
- Signed-off-by: Felix Fietkau \<nbd@nbd.name\> (mt76 maintainer,
  applied the patch)
- No Fixes: tag (expected for this review queue)
- No Cc: stable (expected)
- No Reported-by / Tested-by / Reviewed-by / Acked-by
- No syzbot / KASAN tags
- Sasha Levin SOB not present on this commit

Step 1.3: ANALYZE THE COMMIT BODY TEXT
Record:
- Bug: EcoNet routers store chip-id 0x7592 in on-flash EEPROM instead of
  0x7603/0x7628/0x7600.
- Hardware identity is still MT7603: PCI 14c3:7603, and MT_HW_CHIPID
  reads 0x7603.
- Symptom: driver treats a valid factory EEPROM as invalid.
- Devices: EcoNet EN751221 and EN7528, e.g. Genexis Platinum 4410.
- No stack trace; this is hardware recognition, not a crash fix.
- Root cause: mt7603_check_eeprom() whitelist is incomplete.

Step 1.4: DETECT HIDDEN BUG FIXES
Record: Not a disguised cleanup. It is an explicit EEPROM ID addition.
When the ID is rejected and OTP exists, mt7603_eeprom_init() memcpy()s
OTP over the flash EEPROM, so MAC/calibration from flash are discarded.
That is a real functional bug for those boards, not a new API.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

Step 2.1: INVENTORY THE CHANGES
Record:
- File: drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c
- +1 line, 0 removed
- Function: mt7603_check_eeprom()
- Scope: single-file, one-line surgical change

Step 2.2: UNDERSTAND THE CODE FLOW CHANGE
Record:
- Before: switch accepts 0x7628, 0x7603, 0x7600; anything else returns
  -EINVAL.
- After: also accepts 0x7592.
- Path: probe → mt7603_register_device() → mt7603_init_hardware() →
  mt7603_eeprom_init().
- If check succeeds and OTP exists: apply cal-free OTP overlay onto
  flash EEPROM.
- If check fails and OTP exists: overwrite entire flash EEPROM with OTP
  (MAC, TX power, xtal data from flash lost).
- Probe does not fail on unknown EEPROM ID.

Step 2.3: IDENTIFY THE BUG MECHANISM
Record: [Hardware ID / quirk] [Whitelist used to decide whether on-flash
EEPROM is trusted. Missing 0x7592 caused valid EcoNet EEPROMs to be
discarded in favor of OTP.]

Step 2.4: ASSESS THE FIX QUALITY
Record:
- Obviously correct: same pattern as the existing 0x7600 case.
- Minimal: one case label.
- Regression risk: very low. A random EEPROM whose first LE16 is 0x7592
  would be trusted; that is the same risk as the existing IDs.
- No API or data-structure change.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

Step 3.1: BLAME THE CHANGED LINES
Record:
- mt7603_check_eeprom() introduced in c8846e1015022 ("mt76: add driver
  for MT7603E and MT7628/7688"), 2018, first released in v5.1-rc1.
- 0x7600 added by bf4a938ab2cf8 ("mt76: mt7603: add additional EEPROM
  chip ID"), 2020, same one-line pattern for TP-Link Archer C50 v4.
- Both commits are ancestors of pending-6.6.

Step 3.2: FOLLOW THE FIXES: TAG
Record: No Fixes: tag. Buggy whitelist dates to the original driver
(v5.1), which is in this tree.

Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES
Record:
- Related: bf4a938ab2cf8 already in 6.6 (precedent).
- Candidate d16447d747050 is not an ancestor of pending-6.6.
- Standalone; not patch X/Y.

Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS
Record:
- Author Ahmed Naseef has no other mt76 commits on pending-6.6.
- Applied by Felix Fietkau, listed maintainer of MEDIATEK MT76.

Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS
Record:
- No new helpers or struct fields.
- pending-6.6 vs patch parent only differs in SPDX and later
  chainmask/return of mt76_eeprom_override(); the switch hunk is
  identical.
- Can apply standalone with a clean hunk.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION
Record:
- b4 dig -c d16447d747050 →
  https://patch.msgid.link/20260719082530.3879831-1-naseefkm@gmail.com
- b4 dig -a: single v1 series, no v2/v3.
- Thread mbox is the patch only; no replies, no NAK, no Cc: stable in
  review.
- Included in wireless-next-2026-08-06 pull (Johannes Berg).
- Syzbot CI: build/boot passed; fuzz skipped.

Step 4.2: CHECK WHO REVIEWED THE PATCH
Record:
- b4 dig -w: Felix Fietkau, Lorenzo Bianconi, Ryder Lee, Shayne Chen,
  Sean Wang, linux-wireless, linux-mediatek, linux-kernel.
- Applied by Felix Fietkau (maintainer SOB). No separate Reviewed-by.

Step 4.3: SEARCH FOR THE BUG REPORT
Record:
- No bugzilla/syzbot link.
- Commit cites multiple EcoNet EN751221/EN7528 devices, example Genexis
  Platinum 4410.
- OpenWrt mt76 tree already contains case 0x7592.
- No independent public crash report found (UNVERIFIED beyond the commit
  text and OpenWrt tree).

Step 4.4: CHECK FOR RELATED PATCHES AND SERIES
Record: Standalone one-patch series. Same pattern as bf4a938ab2cf8.

Step 4.5: CHECK STABLE MAILING LIST HISTORY
Record: lore.kernel.org/stable returned 403. No stable discussion found
via b4/mbox. UNVERIFIED whether anyone requested/rejected this for
stable.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF
Record: mt7603_check_eeprom() only.

Step 5.2: TRACE CALLERS
Record:
- Only caller: mt7603_eeprom_init() (same file).
- mt7603_eeprom_init() ← mt7603_init_hardware() ←
  mt7603_register_device()
- mt7603_register_device() ← mt76pci_probe() (PCI 14c3:7603) and
  mt76_wmac_probe() (mediatek,mt7628-wmac).
- Probe/init path, not hot path or IRQ.

Step 5.3: TRACE CALLEES
Record: get_unaligned_le16() on eeprom.data[0]. No alloc, lock, or I/O
in the changed function.

Step 5.4: FOLLOW THE CALL CHAIN
Record:
- Reachable when an MT7603 PCI device or MT7628 WMAC probes with
  CONFIG_MT7603E.
- Not a syscall-triggered memory bug; firmware/EEPROM contents decide
  the branch.
- Unprivileged users cannot trigger it except by plugging/using the
  device.

Step 5.5: SEARCH FOR SIMILAR PATTERNS
Record:
- Sibling drivers use the same EEPROM-ID switch (mt7615, mt76x0,
  mt76x2).
- This tree already backported other mt76 ID adds, e.g. efd75512e38ac
  (mt76x2u TP-Link USB ID).

===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================

Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?
Record:
- Tree under evaluation: pending-6.6, 6.6.157 (git describe
  p-6.6-3-g04810563abb71).
- Yes. pending-6.6 eeprom.c switch has 0x7628/0x7603/0x7600 only.
- git merge-base --is-ancestor d16447d747050 pending-6.6 → not present.
- Bug present since v5.1 driver introduction.

Step 6.2: CHECK FOR BACKPORT COMPLICATIONS
Record: Clean apply. Switch context matches. Later chainmask/license
diffs are outside the hunk.

Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE
Record: 0x7600 ID is present. 0x7592 is not. No alternate fix.

Note: EcoNet SoC support landed in 6.16 (arch/mips/econet), not in 6.6.
That lowers vanilla-6.6 user count; it does not remove the driver or the
ID check. PCI 14c3:7603 still exists in this tree.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY
Record: [drivers/net/wireless/mediatek/mt76/mt7603] [IMPORTANT for
MT7603/MT7628 users; PERIPHERAL relative to core kernel]

Step 7.2: ASSESS SUBSYSTEM ACTIVITY
Record: Mature driver since v5.1. 6.6 still receives mt76 fixes.
Maintainer is Felix Fietkau.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

Step 8.1: DETERMINE WHO IS AFFECTED
Record: Driver-specific / config-specific (CONFIG_MT7603E). Documented
users are EcoNet EN751221/EN7528 routers with MT7603 PCI WiFi. Vanilla
6.6 cannot boot EcoNet SoCs; downstream 6.6 kernels and any other board
with this EEPROM still benefit.

Step 8.2: DETERMINE THE TRIGGER CONDITIONS
Record:
- Trigger: probe of MT7603 when flash EEPROM starts with 0x7592 and OTP
  is present.
- Every boot on those devices, not a race.
- Not exploitable by unprivileged software alone.

Step 8.3: DETERMINE THE FAILURE MODE SEVERITY
Record: [Wrong EEPROM source: factory MAC/calibration replaced by OTP]
[Severity: MEDIUM for those devices — broken/degraded WiFi or wrong MAC,
not oops/corruption]

Step 8.4: CALCULATE RISK-BENEFIT RATIO
Record:
- Benefit: medium for affected hardware (WiFi uses intended EEPROM);
  lower on vanilla 6.6 because EcoNet platform is later, but this is the
  usual device-ID case.
- Risk: very low (one case label, no locking/API).
- Ratio: favorable. Device-ID additions are accepted in stable for this
  reason.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

Step 9.1: COMPILE THE EVIDENCE
FOR:
- One-line EEPROM/chip ID addition to an existing driver (stable
  exception).
- Same pattern as 0x7600, already in 6.6.
- Real boards named; hardware already binds as PCI 14c3:7603.
- Without it, valid flash EEPROM is discarded for OTP (MAC/cal).
- Maintainer applied it; applies cleanly here; no new API.
- This tree already contains similar mt76 ID backports.

AGAINST:
- Not a crash/security/deadlock.
- No Tested-by/Reviewed-by; mailing list had no discussion.
- EcoNet platform is not in 6.6, so vanilla 6.6 user count is small.
- No Fixes:/Cc: stable (expected, not a negative).

UNRESOLVED:
- Could not search lore.kernel.org/stable (403).
- No independent public repro beyond the commit and OpenWrt mt76 tree.

Step 9.2: APPLY THE STABLE RULES CHECKLIST
1. Obviously correct and tested? PASS — one-line whitelist, maintainer-
   applied, syzbot CI build/boot passed.
2. Fixes a real bug that affects users? PASS — those boards trust OTP
   instead of factory EEPROM.
3. Important issue? PASS under the device-ID/quirk exception (functional
   WiFi/MAC on real hardware), even though not a panic.
4. Small and contained? PASS — +1 line, one file.
5. No new features or APIs? PASS — existing driver, additional ID only.
6. Can apply to the local tree? PASS — hunk matches pending-6.6.

Step 9.3: CHECK FOR EXCEPTION CATEGORIES
Record: Device ID addition to an existing driver (EEPROM chip ID,
analogous to PCI/USB ID). Also a hardware quirk for boards whose EEPROM
ID does not match MT_HW_CHIPID.

Step 9.4: MAKE YOUR DECISION
This belongs in 6.6.y. The driver and the incomplete whitelist are in
this tree; the fix is the standard one-line ID addition stable already
takes for mt76. EcoNet SoC support arriving later reduces vanilla-6.6
exposure but does not make the patch a new feature or a dependency-heavy
backport.

What it solves for stable users: MT7603 devices whose flash EEPROM ID is
0x7592 keep factory MAC and calibration instead of having them replaced
by OTP on probe.

Risk vs benefit: essentially no regression risk; benefit is enabling
correct EEPROM use on existing hardware.

Verification:
- [Phase 1] Tags: author SOB, Felix Fietkau SOB, msgid link; no Fixes/Cc
  stable/Reported-by
- [Phase 2] Diff: +1 `case 0x7592:` in mt7603_check_eeprom()
- [Phase 2] Confirmed eeprom_init: fail → memcpy OTP over flash; success
  → cal-free overlay only
- [Phase 3] blame: function from c8846e1015022 (v5.1); 0x7600 from
  bf4a938ab2cf8; both in pending-6.6
- [Phase 3] git merge-base --is-ancestor d16447d747050 pending-6.6 → not
  in 6.6
- [Phase 3] git diff pending-6.6 vs parent: switch identical; only
  SPDX/chainmask elsewhere
- [Phase 4] b4 dig -c d16447d747050: lore msgid
  20260719082530.3879831-1-naseefkm@gmail.com
- [Phase 4] b4 dig -a: v1 only; mbox has no replies
- [Phase 4] b4 dig -w: mt76 maintainers + linux-wireless CC'd; Felix
  applied
- [Phase 4] wireless-next-2026-08-06 pull lists this commit
- [Phase 5] callers: mt7603_eeprom_init → init_hardware →
  register_device → pci/soc probe
- [Phase 6] pending-6.6 Makefile 6.6.157; switch lacks 0x7592; would
  apply cleanly
- [Phase 6] EcoNet arch not in 6.6 (added ~6.16) — lowers vanilla user
  count, code still present
- [Phase 7] MAINTAINERS: Felix Fietkau maintains mt76
- [Phase 8] Failure: OTP replaces flash EEPROM (MAC/cal); not oops
- UNVERIFIED: stable@ lore search (HTTP 403); no independent field crash
  report

**YES**

 drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c
index 88382b537a33b..06f61988655e5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c
@@ -142,6 +142,7 @@ static int mt7603_check_eeprom(struct mt76_dev *dev)
 	case 0x7628:
 	case 0x7603:
 	case 0x7600:
+	case 0x7592:
 		return 0;
 	default:
 		return -EINVAL;
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7615: fix NULL deref in mt7615_mac_set_rates
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (18 preceding siblings ...)
  2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-5.15] wifi: mt76: mt7603: add 0x7592 EEPROM chip ID Sasha Levin
@ 2026-10-19 13:49 ` Sasha Levin
  2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-5.10] wifi: ath11k: validate regulatory capability phy_id Sasha Levin
                   ` (20 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:49 UTC (permalink / raw)
  To: patches, stable
  Cc: Felix Fietkau, Chad Monroe, Sasha Levin, lorenzo, ryder.lee,
	matthias.bgg, angelogioacchino.delregno, linux-wireless,
	linux-kernel, linux-arm-kernel, linux-mediatek

From: Felix Fietkau <nbd@nbd.name>

[ Upstream commit 98aff74779da9f417386c589c36848e9c568f0f9 ]

mt7615_tx() falls back to the vif BSS wcid when mac80211 hands a frame
over without a station, e.g. while a station is being torn down, and to
the global wcid when there is no vif either. Both tx_prepare_skb
implementations derive a mt7615_sta from that wcid unconditionally and,
if the rate control probe flag is set, pass it to mt7615_mac_set_rates(),
which dereferences the NULL vif backpointer of the per-vif embedded sta:

  Unable to handle kernel read from unreadable memory at virtual
  address 0000000000000002
  ...
  pc : mt7615_mac_set_rates
  lr : mt7615_tx_prepare_skb

Neither entry is rate controlled by mac80211: the embedded sta has an
empty rate set, and for the global wcid the container_of does not yield a
valid mt7615_sta at all. Only resolve the sta for wcids that belong to a
station.

Reported-by: Chad Monroe <chad@monroe.io>
Link: https://patch.msgid.link/20260724124813.3961474-23-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## Phase 1: Commit message forensics

**Step 1.1 — Subject**
Record: `[wifi: mt76: mt7615]` `[fix]` `[NULL deref in
mt7615_mac_set_rates when TX uses a non-station wcid]`

**Step 1.2 — Tags**
Record:
- `Reported-by: Chad Monroe <chad@monroe.io>` — real user hit this
- `Link:
  https://patch.msgid.link/20260724124813.3961474-23-nbd@nbd.name` —
  patch 23/29 of an mt76-next series
- `Signed-off-by: Felix Fietkau <nbd@nbd.name>` — mt76 maintainer
- No `Fixes:`, no `Cc: stable` (expected for this review)
- No `Reviewed-by` / `Tested-by` / `Acked-by` on the commit itself
- Ignore `Signed-off-by: Sasha Levin` / `[Upstream commit ...]` if
  present (pipeline)

**Step 1.3 — Body**
Record:
- Bug: `mt7615_tx()` falls back to the vif BSS wcid when mac80211 TX has
  no station (e.g. station teardown), and to `global_wcid` if there is
  no vif. Both `tx_prepare_skb` paths `container_of` that wcid into
  `mt7615_sta` and, if `IEEE80211_TX_CTL_RATE_CTRL_PROBE` is set, call
  `mt7615_mac_set_rates()`.
- Symptom: kernel NULL deref / oops:
  `Unable to handle kernel read from unreadable memory at virtual
  address 0000000000000002`, `pc: mt7615_mac_set_rates`, `lr:
  mt7615_tx_prepare_skb`
- Root cause: BSS-embedded sta has a NULL `vif` backpointer;
  `global_wcid` is not a `mt7615_sta` at all. Neither is rate-
  controlled.
- Fix: only resolve `msta` when `wcid->sta` is set.

**Step 1.4 — Hidden bug fix?**
Record: Not hidden. Explicit crash fix with a stack trace and a
reporter.

## Phase 2: Diff analysis

**Step 2.1 — Inventory**
Record:
- `drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c`:
  `mt7615_tx_prepare_skb` — ~3 lines
- `drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c`:
  `mt7663_usb_sdio_tx_prepare_skb` — ~3 lines
- Scope: single-driver surgical fix, two TX prepare paths (PCIe/MMIO and
  USB/SDIO)

**Step 2.2 — Code flow**
Record: Before, any non-NULL `wcid` was treated as `mt7615_sta`. After,
`msta` is set only if `wcid && wcid->sta`. The existing `if (...
RATE_CTRL_PROBE && msta)` already skips `mt7615_mac_set_rates()` when
`msta` is NULL.

**Step 2.3 — Bug mechanism**
Record: `[NULL pointer dereference]` — `mt7615_mac_set_rates()` does
`sta->vif->mt76.omac_idx`. For the per-vif embedded sta, `vif` is never
set. For `global_wcid`, `container_of` is invalid. The fix uses the
existing `wcid->sta` flag.

**Step 2.4 — Fix quality**
Record: Obviously correct. Same pattern already used in this tree
(`wcid_to_sta()`, `mt76_connac_pm_dequeue_skbs()`,
`mt7615_rx_get_wcid()`). Skipping rate-probe setup for non-station wcids
is intended: those entries are not rate-controlled. Regression risk is
very low. No API change.

## Phase 3: Git history

**Step 3.1 — Blame**
Record: The incomplete NULL check is `8d3cdc1bbb1d3` (“mt76: mt7615: fix
NULL pointer dereference in tx_prepare_skb()”, Lorenzo Bianconi, 2021).
That only handled `wcid == NULL` (then `global_wcid`). The BSS-wcid
fallback in `mt7615_tx()` is from 2019 (`04b8e65922f631` /
`2b8cdfb28d3402`). The bug has been in this lineage since mt7615 TX was
added.

**Step 3.2 — Fixes: tag**
Record: None. The incomplete 2021 fix is already in this tree (`git
merge-base --is-ancestor 8d3cdc1bbb1d3 HEAD` succeeded). This commit
closes the remaining hole.

**Step 3.3 — File history**
Record: Recent mt7615 changes in this tree are unrelated (runtime-pm
timeout, TSF, DMA reset). No prerequisite refactor for this two-line
guard. Standalone.

**Step 3.4 — Author**
Record: Felix Fietkau is the mt76 maintainer. Related earlier NULL-deref
fix was also signed off by him.

**Step 3.5 — Dependencies**
Record: Patch 23/29 of an mt76-next batch, but the other patches are
independent (mt7996/mt7915/scan/WED). This hunk only needs `wcid->sta`
and the existing `msta` NULL check, both present here. Standalone.

## Phase 4: Mailing list / external

**Step 4.1 — Original discussion**
Record: `b4 mbox` saved the thread. Subject: `[PATCH mt76-next 23/29]
wifi: mt76: mt7615: fix NULL deref in mt7615_mac_set_rates`. Sent 24 Jul
2026 by Felix to linux-wireless. 29-message thread is the series itself,
not a v2/v3 of this patch. No NAK. No reviewer `Cc: stable`. Lore HTTP
fetch returned 403; discussion was recovered via `b4`.

**Step 4.2 — Recipients**
Record: To: linux-wireless@vger.kernel.org. Maintainer is the author.

**Step 4.3 — Bug report**
Record: Reported-by Chad Monroe with a concrete oops (`pc:
mt7615_mac_set_rates`, `lr: mt7615_tx_prepare_skb`). Chad also authored
other patches in the same series, so this is a real device user, not a
theoretical report.

**Step 4.4 — Series**
Record: Independent mt76 bug-fix dump. mt7996 patches are irrelevant to
5.15. This patch does not need 1–22 or 24–29.

**Step 4.5 — Stable list**
Record: UNVERIFIED — lore.kernel.org/stable HTTP 403. No evidence it was
rejected for stable.

## Phase 5: Semantic / call-chain

**Step 5.1 — Functions**
Record: `mt7615_tx_prepare_skb`, `mt7663_usb_sdio_tx_prepare_skb`
(callers of `mt7615_mac_set_rates`).

**Step 5.2 — Callers**
Record:
- PCIe/MMIO: `mt7615_tx_prepare_skb` via `mt7615/mmio.c`
  `.tx_prepare_skb`, from `mt76_dma_tx_queue_skb` (`dma.c:409`)
- USB: `usb.c:917`; SDIO: `sdio.c:263`
- Upstream of that: `mt7615_tx()` → `mt76_tx()` /
  `mt76_connac_pm_queue_skb()`

**Step 5.3 — Callees**
Record: `mt7615_mac_set_rates()` immediately uses
`sta->vif->mt76.omac_idx` (mac.c:1063 in this tree).

**Step 5.4 — Reachability**
Record: Yes, from normal wireless TX. `mt7615_tx()`:

```737:743:drivers/net/wireless/mediatek/mt76/mt7615/main.c
        if (vif && !control->sta) {
                struct mt7615_vif *mvif;
                mvif = (struct mt7615_vif *)vif->drv_priv;
                msta = &mvif->sta;
                wcid = &msta->wcid;
        }
```

mac80211 can pass `control->sta == NULL` while
`IEEE80211_TX_CTL_RATE_CTRL_PROBE` is still set on a previously rate-
controlled skb (station teardown). That is a userspace-reachable
AP/client path.

**Step 5.5 — Similar patterns**
Record: Same `wcid && wcid->sta` guard already exists in
`mt76x02_mac.c`, `mt76_connac_mac.c`, `wcid_to_sta()`.
`mt7615_rx_get_wcid()` already refuses non-station wcids. `wcid.sta = 1`
is set only in `mt7615_mac_sta_add()`, not in `mt7615_add_interface()`.

## Phase 6: Local tree (5.15.221 / pending-5.15)

**Step 6.1 — Buggy code present?**
Record: Yes.
- `pci_mac.c:142`: `msta = wcid ? container_of(wcid, struct mt7615_sta,
  wcid) : NULL;`
- `usb_sdio.c:200`: same
- `mac.c:1063`: `u16 idx = sta->vif->mt76.omac_idx;`
- `add_interface` sets `mvif->sta.wcid` but never `mvif->sta.vif` or
  `wcid.sta`
- `wcid->sta` exists in `struct mt76_wcid` (`mt76.h:251`)

**Step 6.2 — Backport difficulty**
Record: Minor context mismatch, easy rework. Mainline USB path has extra
locals (`key`, `pktid`) and an in-function `global_wcid` fallback that
5.15 keeps in `mt7663_usb_sdio_write_txwi()`. PCIe path uses
`MT_TX_HW_QUEUE_EXT_PHY` / `mdev->phy2` here vs later `phys[MT_BAND1]`.
The semantic change is the same two-line `wcid->sta` check.
`mt76_vif_link` in the provided hunk context is *not* required.

**Step 6.3 — Related fixes already here?**
Record: `8d3cdc1bbb1d3` is present and is incomplete. No later
`mt7615_mac_set_rates` NULL-deref fix in this tree.

## Phase 7: Subsystem context

**Step 7.1**
Record: `[drivers/net/wireless/mediatek/mt76/mt7615]` `[IMPORTANT]` —
not core kernel, but a widely used 802.11ac chipset (MT7615E/MT7663E
PCIe, MT7663U USB, MT7663S SDIO, MT7622 SoC WMAC). Common on routers and
embedded boards, including 5.15 LTS/Android/OpenWrt-class systems.

**Step 7.2**
Record: Mature driver; this bug is old, not a new-subsystem issue.

## Phase 8: Impact and risk

**Step 8.1 — Who is affected**
Record: Users of MT7615/MT7663/MT7622 (`CONFIG_MT7615E` /
`CONFIG_MT7663U` / `CONFIG_MT7663S` / `CONFIG_MT7622_WMAC`). Driver-
specific, not universal.

**Step 8.2 — Trigger**
Record: TX without a station while `IEEE80211_TX_CTL_RATE_CTRL_PROBE` is
set — typically station teardown / disconnect with a probe rate sample
in flight. Not every packet, but a normal Wi-Fi event. Unprivileged
clients disconnecting from an AP can induce it.

**Step 8.3 — Failure mode**
Record: `[Kernel oops / NULL deref in hard TX path]` `[CRITICAL]`

**Step 8.4 — Risk vs benefit**
Record: Benefit high for that hardware (prevents oops). Risk very low
(~6 lines, existing flag, same pattern as sibling code). Skipping
`mac_set_rates` on BSS/global wcid is the correct behavior.

## Phase 9: Synthesis

**Step 9.1 — Evidence**

FOR:
- Real oops with reporter and stack trace
- Bug and incomplete 2021 fix both exist in this 5.15 tree
- Small, obviously correct guard
- Maintainer-authored
- Matches stable rules (crash, contained, no new API)
- Hardware is common on 5.15-era devices

AGAINST:
- Driver-specific, not core
- Won’t `git am` cleanly (context only)
- Part of a 29-patch series (other patches are unrelated)
- No `Fixes:` / `Cc: stable` (not a negative under these rules)
- No mailing-list review tags on this specific patch

UNRESOLVED:
- Could not fetch lore/stable over HTTP (403); recovered the thread with
  `b4`
- Exact crash address `...0002` matches a newer `vif` layout; in 5.15
  `omac_idx` is at offset 1. Same NULL `vif` deref either way.

**Step 9.2 — Stable rules**
1. Obviously correct and tested? **PASS** — maintainer fix; user-
   reported oops; logic matches existing `wcid->sta` usage
2. Real bug affecting users? **PASS** — Chad Monroe crash
3. Important (crash/security/corruption/deadlock)? **PASS** — kernel
   oops in TX
4. Small and contained? **PASS** — two functions, ~6 lines
5. No new features/APIs? **PASS**
6. Can apply to this tree? **PASS** — code is here; needs a trivial
   context tweak, not a rewrite

**Step 9.3 — Exceptions**
Record: None (not a device-ID/quirk/DT/build/docs exception). It
qualifies as a normal crash fix.

**Step 9.4 — Decision**
This is a real NULL deref in the mt7615 TX path that 5.15 still has. The
2021 patch only covered a NULL wcid; the BSS-wcid fallback still
crashes. Backport it.

## What the commit solves for this tree

On 5.15.221, `mt7615_tx()` still substitutes the per-vif embedded sta
when mac80211 has no station. `tx_prepare_skb` still `container_of`s
that wcid and can call `mt7615_mac_set_rates()`, which immediately loads
`sta->vif->mt76.omac_idx` while `vif` is NULL. That oopses. Restricting
`msta` to `wcid->sta` stops it. Same change belongs in both PCIe and
USB/SDIO prepare paths.

Risk is a skipped rate-probe update on wcids that were never valid for
rate control. Benefit is avoiding a driver oops during client teardown.

## Verification
- [Phase 1] Parsed tags: Reported-by Chad Monroe; Link to 23/29
  mt76-next; SOB Felix Fietkau; no Fixes/Cc stable
- [Phase 2] Diff: two `msta` assignments; require `wcid->sta` before
  `container_of`
- [Phase 3] Blame: 8d3cdc1bbb1d3 (2021) only NULL-wcid; BSS fallback
  since 2019
- [Phase 3] `git merge-base --is-ancestor 8d3cdc1bbb1d3 HEAD`: yes,
  incomplete fix is here
- [Phase 3] `git log --grep="fix NULL deref in mt7615_mac_set_rates" --
  mt7615/`: not in this tree
- [Phase 4] `b4 mbox 20260724124813.3961474-23-nbd@nbd.name`: 29-message
  independent mt76 series; this patch standalone; no NAK
- [Phase 4] lore HTTP 403; UNVERIFIED stable@ discussion
- [Phase 5] Call chain: mac80211 `drv_tx` → `mt7615_tx` → `mt76_tx` /
  DMA `tx_prepare_skb` → `mt7615_mac_set_rates`
- [Phase 5] `mt7615_add_interface` does not set `mvif->sta.vif` or
  `wcid.sta`; only `mt7615_mac_sta_add` sets `wcid.sta = 1`
- [Phase 6] `make kernelversion` / Makefile: **5.15.221**, branch
  `pending-5.15`
- [Phase 6] Buggy lines present in `pci_mac.c:142` and `usb_sdio.c:200`;
  deref at `mac.c:1063`
- [Phase 6] Surrounding context differs (phy2 vs phys[MT_BAND1], USB
  locals); semantic apply is still two lines
- [Phase 8] Failure: NULL deref oops in TX; severity CRITICAL for
  MT7615/MT7663/MT7622 users

**YES**

 drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c  | 5 +++--
 drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c | 5 +++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c
index b795d11d943d0..61efdf59133f5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c
@@ -68,10 +68,11 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
 	int pid, id;
 	u8 *txwi = (u8 *)txwi_ptr;
 	struct mt76_txwi_cache *t;
-	struct mt7615_sta *msta;
+	struct mt7615_sta *msta = NULL;
 	void *txp;
 
-	msta = wcid ? container_of(wcid, struct mt7615_sta, wcid) : NULL;
+	if (wcid && wcid->sta)
+		msta = container_of(wcid, struct mt7615_sta, wcid);
 	if (!wcid)
 		wcid = &dev->mt76.global_wcid;
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c b/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c
index 820b395900275..01e79f37649c1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c
@@ -187,10 +187,11 @@ int mt7663_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
 	struct sk_buff *skb = tx_info->skb;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_key_conf *key = info->control.hw_key;
-	struct mt7615_sta *msta;
+	struct mt7615_sta *msta = NULL;
 	int pad, err, pktid;
 
-	msta = wcid ? container_of(wcid, struct mt7615_sta, wcid) : NULL;
+	if (wcid && wcid->sta)
+		msta = container_of(wcid, struct mt7615_sta, wcid);
 	if (!wcid)
 		wcid = &dev->mt76.global_wcid;
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] wifi: ath11k: validate regulatory capability phy_id
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (19 preceding siblings ...)
  2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7615: fix NULL deref in mt7615_mac_set_rates Sasha Levin
@ 2026-10-19 13:50 ` Sasha Levin
  2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-5.10] wifi: cfg80211: include cf1 offset when sending chandef Sasha Levin
                   ` (19 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:50 UTC (permalink / raw)
  To: patches, stable
  Cc: Pengpeng Hou, Rameshkumar Sundaram, Baochen Qiang, Jeff Johnson,
	Sasha Levin, jjohnson, linux-wireless, ath11k, linux-kernel

From: Pengpeng Hou <pengpeng@iscas.ac.cn>

[ Upstream commit f8729a40ebcc94d164be8f154483a21669f3ab52 ]

ath11k_wmi_tlv_ext_hal_reg_caps() copies firmware regulatory
capability records into soc->hal_reg_cap[] using reg_cap.phy_id as
the destination index.  The loop count is bounded by num_phy, but the
phy_id embedded in each record is not checked against the fixed
MAX_RADIOS-sized destination array.

Reject firmware records whose phy_id does not fit soc->hal_reg_cap[]
before copying the parsed capability.

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20260704011040.26233-1-pengpeng@iscas.ac.cn
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

This tree is **7.3.0-rc4** (`v7.3-rc4-27-gf0100363d8c37`). The candidate
is a 6-line firmware `phy_id` bounds check in ath11k WMI parsing. The
buggy `memcpy` has been in this driver since v5.6; the check is
obviously correct and belongs here.

---

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: PARSE THE SUBJECT LINE**
Record: **[wifi: ath11k] [validate] [reject firmware `phy_id` that is
out of range for `soc->hal_reg_cap[]`]**

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- **Fixes:** none (expected for this review pipeline)
- **Reported-by:** none
- **Tested-by:** none
- **Reviewed-by:** Rameshkumar Sundaram
  `<rameshkumar.sundaram@oss.qualcomm.com>`; Baochen Qiang
  `<baochen.qiang@oss.qualcomm.com>` (Qualcomm ath11k reviewers)
- **Acked-by:** none
- **Link:**
  `https://patch.msgid.link/20260704011040.26233-1-pengpeng@iscas.ac.cn`
- **Cc: stable:** none (expected; not a negative signal)
- **Signed-off-by:** Pengpeng Hou (author); Jeff Johnson (ath11k
  maintainer)

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** `ath11k_wmi_tlv_ext_hal_reg_caps()` copies firmware HAL
  regulatory-capability records into `soc->hal_reg_cap[]` using
  **`reg_cap.phy_id` as the destination index**. The loop is bounded by
  `num_phy`, but **`phy_id` inside each record is not checked** against
  `MAX_RADIOS`.
- **Symptom/failure mode:** out-of-bounds write into `struct
  ath11k_base` (memory corruption).
- **Version information:** none in the message.
- **Root cause:** firmware-controlled `u32 phy_id` used as an array
  index without a bounds check.

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: **Not disguised.** This is an explicit firmware-index validation
/ OOB-write fix. Verb “validate” is a bounds check, not cleanup.

---

## PHASE 2: DIFF ANALYSIS

**Step 2.1: INVENTORY THE CHANGES**
Record:
- **File:** `drivers/net/wireless/ath/ath11k/wmi.c` — **+6 / -0**
- **Function:** `ath11k_wmi_tlv_ext_hal_reg_caps()`
- **Scope:** single-file surgical fix

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record (verified in this tree at `wmi.c:4862-4880`):
- **Before:** `ath11k_pull_reg_cap_svc_rdy_ext()` fills `reg_cap` from
  firmware TLV `ext_reg_cap[i].phy_id`, then
  `memcpy(&soc->hal_reg_cap[reg_cap.phy_id], &reg_cap, sizeof(reg_cap))`
  with no check that `phy_id < MAX_RADIOS`.
- **After:** if `reg_cap.phy_id >= ARRAY_SIZE(soc->hal_reg_cap)`, log a
  warning and return `-EINVAL`; otherwise copy as before.
- **Path:** firmware `WMI_SERVICE_READY_EXT` event during ath11k bring-
  up (probe/init), not a hot datapath.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record:
- **Category:** **(d) memory safety — buffer overflow / out-of-bounds
  write**
- **Mechanism:** `phy_id` is a firmware `u32`
  (`wmi_hal_reg_capabilities_ext.phy_id`). Destination is
  `hal_reg_cap[MAX_RADIOS]` with **`MAX_RADIOS == 3`** (`core.h:242`,
  `core.h:971`). Loop bound `num_phy` is also firmware-supplied and is
  **not** the same as `phy_id`. A record with `phy_id >= 3` writes
  `sizeof(struct ath11k_hal_reg_capabilities_ext)` (10 × `u32` = 40
  bytes) past the array into following `ath11k_base` fields
  (`free_vdev_map`, `tbl_mtx_lock`, peer rhashtables).
- The parse helper only checks TLV count vs `num_phy`
  (`n_ext_hal_reg_caps >= param.num_phy` → `-ENOBUFS`); it does **not**
  validate `phy_id`.

**Step 2.4: ASSESS THE FIX QUALITY**
Record:
- **Obviously correct:** `ARRAY_SIZE(soc->hal_reg_cap)` is the real
  destination size; reject-and-return is the right failure mode.
- **Minimal:** 6 lines, one check, no API/struct changes.
- **Regression risk:** **very low**. Well-formed firmware with `phy_id`
  0–2 is unchanged. Invalid `phy_id` now fails WMI parse instead of
  corrupting memory. That is the intended probe failure, not a behavior
  change for working hardware.

---

## PHASE 3: GIT HISTORY INVESTIGATION

**Step 3.1: BLAME THE CHANGED LINES**
Record:
- Loop + `memcpy`: **`d5c65159f28953`** — “ath11k: driver for Qualcomm
  IEEE 802.11ax devices” (Kalle Valo, 2019-11-25).
- Bounds check: **`f8729a40ebcc9`** (this commit).
- Introducer is in **v5.6**, not v5.5 (`git merge-base --is-ancestor`).
  Bug has been in every tree with ath11k since then.

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: **No Fixes: tag.** Not applicable. Introducer identified by
blame: `d5c65159f28953` (original driver).

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record:
- Recent `wmi.c` work is other firmware TLV hardening (overread, stride,
  leak) — related thematically, **not prerequisites**.
- Earlier `84eee3c845d37` (“refine the phy_id check in
  ath11k_reg_chan_list_event”) is a **different** event path.
- **Standalone**, not patch N/M. Maintainer applied it as `[1/1]`.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Pengpeng Hou has this one ath11k commit here. Weight comes from
**Qualcomm reviewers** and **maintainer Jeff Johnson** (MAINTAINERS:
ATH11K).

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: **None.** Uses existing `ARRAY_SIZE`, `ath11k_warn`, `-EINVAL`,
`soc->hal_reg_cap`. Can apply standalone on any tree with this 2019
function.

---

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- **Lore URL (b4 dig):**
  `https://patch.msgid.link/20260704011040.26233-1-pengpeng@iscas.ac.cn`
- **Revisions:** **v1 only** (`b4 dig -a`); committed v1.
- **Thread (saved via `b4 dig -m`):**
  - Baochen Qiang: `Reviewed-by`
  - Rameshkumar Sundaram: `Reviewed-by`
  - Jeff Johnson: “Applied, thanks!” `[1/1]`
- **No NAKs, no stable nomination, no requested revisions.**

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record (`b4 dig -w`): To/Cc were Jeff Johnson, `linux-wireless`,
`ath11k@lists.infradead.org`, `linux-kernel`. Right lists and
maintainer.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: **No user/syzbot/bugzilla report.** Found by code review of
firmware TLV parsing. Severity is from the mechanism (OOB write), not
from a crash log.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: Standalone `[PATCH]`, not a series. ath12k still has an
analogous unguarded `soc->hal_reg_cap[reg_cap.phy_id] = reg_cap` in
`ath12k/wmi.c` — sibling issue, **not a dependency**.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: **UNVERIFIED** for lore.kernel.org/stable (HTTP 403). Local
history has no stable-specific discussion of this subject.

---

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1: KEY FUNCTIONS**
Record: `ath11k_wmi_tlv_ext_hal_reg_caps()`; helpers
`ath11k_pull_reg_cap_svc_rdy_ext()`,
`ath11k_wmi_tlv_ext_hal_reg_caps_parse()`.

**Step 5.2: TRACE CALLERS**
Record (verified with grep/read):
- `ath11k_wmi_tlv_ext_hal_reg_caps()` ←
  `ath11k_wmi_tlv_svc_rdy_ext_parse()` (`WMI_TAG_ARRAY_STRUCT` after hw-
  mode and mac-phy TLVs)
- ← `ath11k_service_ready_ext_event()`
- ← WMI event switch `WMI_SERVICE_READY_EXT_EVENTID`

**Step 5.3: TRACE CALLEES**
Record: `ath11k_wmi_tlv_iter()`, `ath11k_pull_reg_cap_svc_rdy_ext()`
(copies firmware `phy_id`), `memcpy()`.

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: Reachable on **ath11k device init** when firmware sends service-
ready-ext. Not a syscall hot path. Trigger needs **CONFIG_ATH11K** +
Qualcomm 802.11ax hardware + firmware that puts `phy_id >= 3` (or
otherwise ≥ `ARRAY_SIZE`). Unprivileged users cannot poke this WMI path
directly; **buggy or malicious firmware** can. That is still a real
kernel OOB write.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: Same driver already bounds other firmware indices (e.g. `phy_idx
>= reg_caps->num_phy` in the pull helper). This copy site was the hole.
ath12k has the same hole unfixed.

---

## PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: **Yes.** `ath11k_wmi_tlv_ext_hal_reg_caps()` and
`hal_reg_cap[MAX_RADIOS]` are present. The unguarded `memcpy` was here
from v5.6 until `f8729a40ebcc9`. **Bug introduced in v5.6, long before
7.3.** `git merge-base --is-ancestor f8729a40ebcc9 HEAD` is true (fix is
in 7.3-rc1+); that is mainline merge, not “already selected for stable.”

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: **Clean apply.** Surrounding function body is still the 2019
structure plus this 6-line check. No refactor of this function in
between.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: No alternate fix for this memcpy. Other nearby TLV fixes address
different bugs.

---

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: SUBSYSTEM AND CRITICALITY**
Record: **ath11k (Qualcomm 802.11ax)** under
`drivers/net/wireless/ath/ath11k/`. **IMPORTANT** — not core mm/fs, but
a widely used Wi-Fi driver (laptops, AP SoCs, Chromebooks, phones).
CONFIG: `ATH11K` / `ATH11K_PCI` / `ATH11K_AHB`.

**Step 7.2: SUBSYSTEM ACTIVITY**
Record: Actively maintained (Jeff Johnson). Recent WMI work is firmware-
message validation, consistent with this patch.

---

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: WHO IS AFFECTED**
Record: **Driver-specific / config-specific:** `CONFIG_ATH11K` users.
Impact only if firmware sends a `phy_id` that does not fit
`hal_reg_cap[]`.

**Step 8.2: TRIGGER CONDITIONS**
Record: Device init / firmware service-ready-ext. **Not** every packet.
Needs bad `phy_id` in the WMI record (firmware bug or hostile firmware).
Unprivileged userspace cannot fire it without controlling firmware.

**Step 8.3: FAILURE MODE SEVERITY**
Record: **Out-of-bounds write** of 40 bytes into `struct ath11k_base`
after `hal_reg_cap[]` — can corrupt `free_vdev_map`, mutexes, peer
tables → crash, deadlock, or further memory corruption. **Severity:
HIGH** (OOB write / memory corruption). Not a panic on every boot with
good firmware.

**Step 8.4: RISK-BENEFIT RATIO**
Record:
- **Benefit:** High for ath11k — stops a real OOB write on a long-
  standing path (v5.6+).
- **Risk:** Very low — 6 lines, error-path reject, no lock/API change,
  good firmware unaffected.
- **Ratio:** strongly favors backport.

---

## PHASE 9: FINAL SYNTHESIS

**Step 9.1: COMPILE THE EVIDENCE**

**FOR:**
- Real OOB write: firmware `u32 phy_id` used as index into a 3-element
  array.
- Small, obviously correct check (`ARRAY_SIZE` + `-EINVAL`).
- Present in this tree’s ath11k code; bug dates to original driver
  (v5.6).
- Reviewed by Qualcomm ath11k developers; applied by the maintainer.
- Standalone; no new APIs; no series dependencies.
- Matches stable pattern: buffer overflow / firmware TLV validation.

**AGAINST:**
- No `Reported-by` / syzbot / production crash.
- Trigger is firmware-supplied data at probe, not a generic syscall.
- No explicit `Cc: stable` (not a negative per pipeline rules).

**UNRESOLVED:**
- Could not query lore.kernel.org/stable (403).
- No public report that shipping firmware actually sent `phy_id >= 3`.

**Step 9.2: STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — local review + two Qualcomm
   Reviewed-by + maintainer apply.
2. Fixes a real bug that affects users? **PASS** — OOB write on firmware
   parse; ath11k users are real users.
3. Important issue? **PASS** — OOB write / memory corruption (**HIGH**),
   not style.
4. Small and contained? **PASS** — +6 lines, one function.
5. No new features or APIs? **PASS**.
6. Can apply to the local tree? **PASS** — same function/context; no
   missing prerequisites.

**Step 9.3: EXCEPTION CATEGORIES**
Record: None (not a device ID / quirk / DT / build / doc exception).
Qualifies as a normal bugfix.

**Step 9.4: DECISION**

This is a surgical firmware-index bounds check that stops a memcpy past
`hal_reg_cap[MAX_RADIOS]`. The destination array and unguarded copy
exist in this 7.3 tree’s ath11k code; the bug is older than this branch.
Risk is negligible; the failure mode is memory corruption. That meets
stable criteria for **this** tree.

---

### What the commit solves for this tree
`ath11k_wmi_tlv_ext_hal_reg_caps()` trusted firmware `phy_id` as an
index into a 3-slot array. A bad `phy_id` overwrites the rest of `struct
ath11k_base`. The patch rejects those records before the copy.

### Stable rules
Small, obviously correct, no new APIs, applies cleanly, fixes a real OOB
write.

### Risk vs benefit
Benefit is preventing kernel memory corruption on ath11k bring-up with
bad firmware. Risk is an early `-EINVAL` only when `phy_id` is already
invalid.

### Concerns
No in-the-wild crash report; trigger is firmware, not unprivileged
syscalls. That does not make an OOB write unsuitable for stable. No
backport rework needed here.

---

Verification:
- **[Phase 1]** Parsed tags: two Qualcomm Reviewed-by, maintainer
  SOB/Link; no Fixes/Reported-by/Cc:stable
- **[Phase 2]** Diff: +6 in `ath11k_wmi_tlv_ext_hal_reg_caps()`;
  `ARRAY_SIZE` check before `memcpy(&soc->hal_reg_cap[reg_cap.phy_id],
  ...)`
- **[Phase 2]** `MAX_RADIOS` is 3; `hal_reg_cap[MAX_RADIOS]` in
  `core.h:971`; `phy_id` is firmware `u32`
- **[Phase 3]** `git blame`: memcpy from `d5c65159f28953` (2019); check
  from `f8729a40ebcc9`
- **[Phase 3]** Introducer in v5.6, not v5.5; fix in v7.3-rc1, not v7.2
- **[Phase 3]** `git merge-base --is-ancestor f8729a40ebcc9 HEAD` → yes
  (mainline already has the fix; ignored as “already selected”)
- **[Phase 3]** No series/prereqs; author has only this ath11k commit
  here
- **[Phase 4]** `b4 dig -c f8729a40ebcc9`: v1 at
  patch.msgid.link/20260704011040.26233-1-pengpeng@iscas.ac.cn
- **[Phase 4]** `b4 dig -a`: v1 only; `b4 dig -w`: maintainer + linux-
  wireless + ath11k list
- **[Phase 4]** mbox: Reviewed-by Baochen Qiang + Rameshkumar Sundaram;
  Jeff Johnson applied `[1/1]`; no NAK
- **[Phase 4]** lore HTTP fetch 403; used `b4 dig -m` instead
- **[Phase 5]** Call chain: WMI `SERVICE_READY_EXT` →
  `ath11k_service_ready_ext_event` → TLV parse → this function
- **[Phase 5]** ath12k has the same unguarded pattern (sibling, not a
  prereq)
- **[Phase 6]** `git describe HEAD` = `v7.3-rc4-27-gf0100363d8c37`;
  `make kernelversion` = 7.3.0-rc4; buggy function present
- **[Phase 6]** Surrounding code still matches 2019 introducer → clean
  apply
- **[Phase 7]** MAINTAINERS: Jeff Johnson, Supported
- **[Phase 8]** Failure mode: 40-byte OOB write into `ath11k_base` after
  `hal_reg_cap[]` → HIGH
- **UNVERIFIED:** stable@ lore search (HTTP 403); whether any shipping
  firmware actually sent `phy_id >= 3`

**YES**

 drivers/net/wireless/ath/ath11k/wmi.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
index 3305ec66ddbf2..c6b9e84b169c9 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -4816,6 +4816,12 @@ static int ath11k_wmi_tlv_ext_hal_reg_caps(struct ath11k_base *soc,
 			return ret;
 		}
 
+		if (reg_cap.phy_id >= ARRAY_SIZE(soc->hal_reg_cap)) {
+			ath11k_warn(soc, "invalid reg cap phy_id %u\n",
+				    reg_cap.phy_id);
+			return -EINVAL;
+		}
+
 		memcpy(&soc->hal_reg_cap[reg_cap.phy_id],
 		       &reg_cap, sizeof(reg_cap));
 	}
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] wifi: cfg80211: include cf1 offset when sending chandef
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (20 preceding siblings ...)
  2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-5.10] wifi: ath11k: validate regulatory capability phy_id Sasha Levin
@ 2026-10-19 13:50 ` Sasha Levin
  2026-10-19 13:50 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: mld: cancel wiphy work before freeing wiphy Sasha Levin
                   ` (18 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:50 UTC (permalink / raw)
  To: patches, stable
  Cc: Lachlan Hodges, Johannes Berg, Sasha Levin, johannes,
	linux-wireless, linux-kernel

From: Lachlan Hodges <lachlan.hodges@morsemicro.com>

[ Upstream commit 5a69b8dffd2a1b06e4cc4c9003c639eb78bac4cd ]

The cf1 offset is not included when sending the chandef leading
to incorrect channel resolution in usermode. Include it.

Signed-off-by: Lachlan Hodges <lachlan.hodges@morsemicro.com>
Link: https://patch.msgid.link/20260721053958.227853-1-lachlan.hodges@morsemicro.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## Phase 1: Commit message forensics

**Step 1.1 — Subject**
- Record: `[wifi: cfg80211] [include] include cf1 offset when sending
  chandef`
- Subsystem: cfg80211 / nl80211 (`net/wireless/nl80211.c`)
- Verb is “include”, not “fix”, but the body states a concrete userspace
  correctness bug.

**Step 1.2 — Tags**
- Record:
  - `Signed-off-by: Lachlan Hodges <lachlan.hodges@morsemicro.com>`
    (author)
  - `Link: https://patch.msgid.link/20260721053958.227853-1-
    lachlan.hodges@morsemicro.com`
  - `Signed-off-by: Johannes Berg <johannes.berg@intel.com>` (wireless
    maintainer apply)
  - No `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Acked-
    by:`, or `Cc: stable` (absence is expected and is not treated as a
    negative)
- Pattern: vendor S1G/HaLow developer (Morse Micro), applied same day by
  the subsystem maintainer. No syzbot/KASAN report.

**Step 1.3 — Body**
- Record:
  - Bug: `freq1_offset` is omitted when nl80211 sends a chandef.
  - Symptom: “incorrect channel resolution in usermode.”
  - Failure mode: userspace reconstructs the operating-channel center
    from `NL80211_ATTR_CENTER_FREQ1` (MHz) only, dropping the kHz
    remainder.
  - Version info: none in the message.
  - Root cause as stated: send path does not emit
    `NL80211_ATTR_CENTER_FREQ1_OFFSET`.

**Step 1.4 — Hidden bug fix?**
- Record: Yes. “Include it” is a dump-path omission fix, not a cleanup.
  It restores the send side of an attribute the kernel has parsed since
  2020.

## Phase 2: Diff analysis

**Step 2.1 — Inventory**
- Record:
  - File: `net/wireless/nl80211.c` (`+4 / -0`)
  - Function: `nl80211_send_chandef()`
  - Scope: single-file surgical fix

**Step 2.2 — Code flow**
- Record: After putting `NL80211_ATTR_CENTER_FREQ1`, the function now
  also puts `NL80211_ATTR_CENTER_FREQ1_OFFSET` when
  `chandef->freq1_offset` is non-zero. Same `-ENOBUFS` pattern as
  `center_freq2` / `punctured`. Normal dump/event path, not an error-
  only path.

**Step 2.3 — Bug mechanism**
- Record: **Logic / ABI completeness.** Parse path already does:
  `chandef->freq1_offset =
  nla_get_u32_default(attrs[NL80211_ATTR_CENTER_FREQ1_OFFSET], 0)`
  Send path already emits `NL80211_ATTR_WIPHY_FREQ_OFFSET` for the
  *control* channel, but never emitted the matching center-segment
  offset. Kernel identity comparison (`cfg80211_chandef_identical`)
  includes `freq1_offset`, so the kernel treats that field as part of
  the channel.

**Step 2.4 — Fix quality**
- Record: Obviously correct; 4 lines; mirrors existing nla_put style.
  Regression risk is very low: the attribute is already in uapi (since
  2020), is optional, and is only sent when the offset is non-zero. Old
  userspace ignores unknown/unused attributes. No API or struct change.

## Phase 3: Git history

**Step 3.1 — Blame**
- Record: `nl80211_send_chandef()` dates to 2012 (`683b6d3b31a519`).
  Control-channel kHz offset send was added in `942ba88ba9c87`
  (2020-05-27, “nl80211: add KHz frequency offset for most wifi
  commands”). That commit added parse of
  `NL80211_ATTR_CENTER_FREQ1_OFFSET` into `chandef->freq1_offset` and
  send of `WIPHY_FREQ_OFFSET`, but not send of `CENTER_FREQ1_OFFSET`.
  The struct field itself was added in `934f4c7dd3a54` (2020-04-24,
  “cfg80211: express channels with a KHz component”). The omission has
  been present since the KHz ABI was introduced.

**Step 3.2 — Fixes: tag**
- Record: None. Closest introducer is `942ba88ba9c87` (verified present
  in this tree). No later conflicting rewrite of this hunk besides the
  candidate itself (`5a69b8dffd2a1`).

**Step 3.3 — File history**
- Record: Related completeness patch by the same author: `3fc830cd8c9d0`
  (“include s1g_primary_2mhz when sending chandef”). Standalone; not
  patch X/Y. No prerequisite refactor required for these four lines.

**Step 3.4 — Author**
- Record: Lachlan Hodges is a regular S1G/cfg80211 contributor (Morse
  Micro). Nearby work is S1G chandef validation and the in-tree `mm81x`
  HaLow driver (`b1906cea00b02`, 2026-07-08). Johannes Berg applied the
  patch.

**Step 3.5 — Dependencies**
- Record: Needs `chandef->freq1_offset` and
  `NL80211_ATTR_CENTER_FREQ1_OFFSET`. Both exist in this tree (2020).
  Applies standalone.

## Phase 4: Mailing list / external

**Step 4.1 — Original discussion**
- Record: `b4 dig -c 5a69b8dffd2a1` → https://patch.msgid.link/202607210
  53958.227853-1-lachlan.hodges@morsemicro.com
- Series: v1 only (`b4 dig -a`). Subject: `[PATCH wireless-next]`.
- Saved mbox (`b4 dig -m`): only the original submission; no replies, no
  NAK, no reviewer `Cc: stable`.
- UNVERIFIED: lore.kernel.org HTML/WebFetch returned 403 (Anubis).
  Discussion content is taken from the b4 mbox, not the HTML thread
  view.

**Step 4.2 — Recipients (`b4 dig -w`)**
- Record: Johannes Berg, linux-wireless, Arien Judge (Morse Micro).
  Maintainer was To: and applied the patch the same day.

**Step 4.3 — Bug report**
- Record: No syzbot/bugzilla link. Evidence of user impact is the Morse
  Micro author plus in-tree S1G hardware that uses 500 kHz offsets.

**Step 4.4 — Series**
- Record: Standalone v1. Not part of a multi-patch series.

**Step 4.5 — Stable list**
- Record: UNVERIFIED for lore.kernel.org/stable HTML (403). No stable
  discussion in the b4-matched wireless thread.

## Phase 5: Semantic / call-chain

**Step 5.1 — Functions**
- Record: `nl80211_send_chandef()` only.

**Step 5.2 — Callers (verified)**
- Record:
  - `nl80211_send_iface()` — GET/NEW interface dump, including MLO links
    (`iw` / netlink dump)
  - channel-switch notify (`cfg80211_ch_switch_notify` / started)
  - `cfg80211_incumbent_signal_notify`
  - DFS/radar notify
  - `cfg80211_nan_channel_evac`
  - `mac80211_hwsim` (exported symbol)
- Calling context: netlink dump and MLME multicast events. Userspace-
  reachable.

**Step 5.3 — Callees**
- Record: `nla_put_u32()` only for this hunk.

**Step 5.4 — Reachability**
- Record: Yes. Unprivileged dumps depend on nl80211 permissions, but any
  process that can GET_INTERFACE / receive MLME events sees the
  truncated center. S1G AP/STA userspace that round-trips a dumped
  chandef into SET_CHANNEL would restore `freq1_offset = 0`.

**Step 5.5 — Similar patterns**
- Record: Same send-path omission pattern as `s1g_primary_2mhz`. S1G
  frequencies are `902000 + chan * 500` kHz
  (`ieee80211_channel_to_freq_khz`). Morse `mm81x` channels are all
  `freq_offset = 500` (902.5, 903.5, …). Non-zero `freq1_offset` is the
  common case for that hardware, not an edge case.

## Phase 6: This checkout

**Step 6.1 — Buggy code in this tree?**
- Record: Local tree is **7.3.0-rc4** (`v7.3-rc4-27-gf0100363d8c37`,
  Makefile `VERSION=7 PATCHLEVEL=3 SUBLEVEL=0 EXTRAVERSION=-rc4`).
- `nl80211_send_chandef`, `freq1_offset`, and
  `NL80211_ATTR_CENTER_FREQ1_OFFSET` all exist here.
- Bug introduced with the 2020 KHz ABI (`942ba88ba9c87` /
  `934f4c7dd3a54`), long before this branch.
- Candidate `5a69b8dffd2a1` is an ancestor of HEAD (landed in 7.3-rc1).
  That is not used as a “already selected for stable” reason; it only
  confirms the code under review is this tree’s current
  `nl80211_send_chandef`.

**Step 6.2 — Backport difficulty**
- Record: Clean on this tree (the four-line hunk matches current code).
  Surrounding later fields (`npca_*`) are already present here; no
  rework needed *on this tree*.

**Step 6.3 — Other fixes already here?**
- Record: No alternate fix. This is the only send of
  `CENTER_FREQ1_OFFSET` in the tree (`nla_put` grep).

## Phase 7: Subsystem context

**Step 7.1**
- Record: `net/wireless` cfg80211/nl80211. Criticality: **IMPORTANT**
  (Wi-Fi uAPI; not mm/core, but the dump path is the userspace contract
  for every wireless interface).

**Step 7.2**
- Record: Actively developed (S1G, NPCA, MLO). The omission itself is
  old; S1G use of kHz offsets is what made it user-visible.

## Phase 8: Impact and risk

**Step 8.1 — Who is affected**
- Record: Config/driver-specific: S1G/HaLow and any chandef with non-
  zero `freq1_offset`. In this tree that includes `mm81x` and hwsim S1G.
  2.4/5/6 GHz integer-MHz channels have `freq1_offset == 0`, so the new
  `nla_put` is skipped.

**Step 8.2 — Trigger**
- Record: Common for S1G: interface dump, channel switch, radar, NAN
  evac. Not a race. Userspace that reads nl80211 can trigger it; no
  exploit primitive verified.

**Step 8.3 — Failure mode**
- Record: Wrong operating-channel center in userspace (typically **500
  kHz** on S1G, which is half of a 1 MHz channel). Kernel does not oops.
  Severity: **MEDIUM** (connectivity / wrong-channel round-trip, not
  crash/corruption/UAF). Fits stable’s “oh, that’s not good” / real bug
  that bothers users of that hardware.

**Step 8.4 — Risk-benefit**
- Record: Benefit medium for S1G users (correct channel identity). Risk
  very low (4 lines, optional existing attribute, offset==0 is a no-op).
  Ratio favors taking it.

## Phase 9: Synthesis

**Step 9.1 — Evidence**

FOR:
- Real dump/event omission: parse has accepted `CENTER_FREQ1_OFFSET`
  since 2020; send never included it.
- S1G channel grid is 500 kHz; Morse `mm81x` channels all have
  `freq_offset = 500`.
- Kernel chandef identity includes `freq1_offset`; userspace cannot
  reconstruct it from `CENTER_FREQ1` alone.
- Dump-then-set round-trip zeros the offset.
- 4-line, obviously correct, no new API.
- Maintainer (Johannes Berg) applied it; callers are standard nl80211
  dump/event paths.

AGAINST:
- Not a crash, deadlock, UAF, or security issue.
- Submitted as `wireless-next`, not `wireless` fixes; no list review
  replies in the b4 mbox.
- Affects a narrower band (S1G/HaLow), not all Wi-Fi users.

UNRESOLVED:
- Full lore HTML (403). Stable-list search (403). Exact userspace
  (iw/hostapd) behavior not inspected in this repo.

**Step 9.2 — Stable rules**
1. Obviously correct and tested? **PASS** — 4 lines, same pattern as
   adjacent attributes; maintainer applied.
2. Real bug that affects users? **PASS** — S1G userspace gets the wrong
   operating center.
3. Important issue? **PASS** (medium) — wrong RF channel center on
   dump/events and on chandef round-trip; not a crash, but a user-
   visible correctness bug on in-tree HaLow hardware.
4. Small and contained? **PASS** — 4 lines, one function.
5. No new features/APIs? **PASS** — emits an existing uapi attribute.
6. Can apply to this tree? **PASS** — fields and function exist here.

**Step 9.3 — Exception category**
- Record: None of device-ID / quirk / DT / build / docs. Ordinary small
  correctness fix.

**Step 9.4 — Decision**
This tree is 7.3-rc4. The affected send path and `freq1_offset` exist
here. The patch is a small, obviously correct fix for a real userspace
channel-identity bug on S1G, with negligible regression risk. It meets
the stable rules for this checkout.

### What the commit solves
`nl80211_send_chandef()` already reported the control frequency plus
`WIPHY_FREQ_OFFSET`, but dropped `chandef->freq1_offset` for the
operating center. Userspace then resolves center as an integer MHz
value. On S1G that is systematically wrong by 500 kHz.

### Stable fit
Small, contained, no new API, real user-visible bug, low risk.

### Risk vs benefit
Benefit: correct channel dumps/events for S1G/HaLow. Risk: very low
optional netlink attribute.

### Concerns
No crash report; vendor-driven; lore HTML unverified. None of those
outweigh the verified omission and the 500 kHz S1G grid.

Verification:
- [Phase 1] Parsed tags: author Lachlan Hodges, Link msgid, SOB Johannes
  Berg; no Fixes/Reported-by/Cc-stable
- [Phase 2] Diff: +4 lines in `nl80211_send_chandef()` adding
  `NL80211_ATTR_CENTER_FREQ1_OFFSET`
- [Phase 3] `git blame`: send of `WIPHY_FREQ_OFFSET` from
  `942ba88ba9c87` (2020); this hunk from `5a69b8dffd2a1`
- [Phase 3] `git log -S 'u16 freq1_offset' -- include/net/cfg80211.h`:
  field added in `934f4c7dd3a54` (2020)
- [Phase 3] Parse path already reads `CENTER_FREQ1_OFFSET` at
  nl80211.c:4006–4007
- [Phase 3] `git merge-base --is-ancestor 5a69b8dffd2a1 HEAD` → yes
  (inspection only)
- [Phase 4] `b4 dig -c/-a/-w/-m`: v1 wireless-next, no replies in mbox;
  To: Johannes
- [Phase 4] WebFetch/curl lore: 403 Anubis — UNVERIFIED HTML thread
- [Phase 5] Callers: iface dump, CSA, radar, NAN, hwsim
- [Phase 5] S1G freq: `902000 + chan * 500`; mm81x channels all offset
  500
- [Phase 5] `cfg80211_chandef_identical` compares `freq1_offset`
- [Phase 6] `git describe HEAD` / `make kernelversion`: 7.3.0-rc4; buggy
  pattern exists; attr/field present
- [Phase 8] Failure mode: wrong userspace channel center (typically 500
  kHz), severity MEDIUM
- UNVERIFIED: stable@ lore discussion; iw/hostapd source handling of the
  attribute

**YES**

 net/wireless/nl80211.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index b851e398b1b36..6ebbb16accfe8 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -4260,6 +4260,10 @@ int nl80211_send_chandef(struct sk_buff *msg, const struct cfg80211_chan_def *ch
 		return -ENOBUFS;
 	if (nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ1, chandef->center_freq1))
 		return -ENOBUFS;
+	if (chandef->freq1_offset &&
+	    nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ1_OFFSET,
+			chandef->freq1_offset))
+		return -ENOBUFS;
 	if (chandef->center_freq2 &&
 	    nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2, chandef->center_freq2))
 		return -ENOBUFS;
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18] wifi: iwlwifi: mld: cancel wiphy work before freeing wiphy
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (21 preceding siblings ...)
  2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-5.10] wifi: cfg80211: include cf1 offset when sending chandef Sasha Levin
@ 2026-10-19 13:50 ` Sasha Levin
  2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-6.12] wifi: ath12k: avoid setting 320MHz support on non 6GHz band Sasha Levin
                   ` (17 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:50 UTC (permalink / raw)
  To: patches, stable
  Cc: Miri Korenblit, Johannes Berg, Sasha Levin, linux-wireless,
	linux-kernel

From: Miri Korenblit <miriam.rachel.korenblit@intel.com>

[ Upstream commit c99bc4d4e0ba6f4661b2b914c96a597d26e7cc05 ]

When we fail to load the fw during op-mode start, we purge the list
of the async handlers but we don't cancel the work.
Same when we stop the op-mode.

Before freeing wiphy, we need to cancel/flush any pending wiphy work,
otherwise the work will fire with a freed memory.
cfg80211 will do it anyway, but it will warn.

Cancel the work in those cases.

Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Link: https://patch.msgid.link/20260714165826.07aa49f755a2.I734a27b1b0eeb5b0e821aee3318fee8dc0a6bc03@changeid
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

I have enough to decide: this is a small UAF/WARN fix in iwlwifi MLD,
the buggy path exists in this 7.3-rc4 tree, and the change is self-
contained.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

**Step 1.1: PARSE THE SUBJECT LINE**
Record: `[iwlwifi/mld] [cancel] cancel wiphy work before freeing wiphy`
- Subsystem: `wifi: iwlwifi: mld`
- Action verb: **cancel** (prevent leftover work from running after
  teardown)
- Intent: stop pending `wiphy_work` before `ieee80211_free_hw()` so it
  cannot run against freed memory

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- `Reviewed-by: Johannes Berg <johannes.berg@intel.com>` —
  mac80211/cfg80211 and iwlwifi maintainer
- `Link: https://patch.msgid.link/20260714165826.07aa49f755a2.I734a27b1b
  0eeb5b0e821aee3318fee8dc0a6bc03@changeid`
- `Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>`
  (author; ignore any Sasha Levin SOB)
- **No** `Fixes:`, **no** `Cc: stable`, **no** `Reported-by`, **no**
  `Tested-by` — expected for this review pipeline
- Notable: maintainer Reviewed-by; no syzbot/KASAN report in the message

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** On op-mode start firmware-load failure, async handler *list*
  is purged (`iwl_mld_stop_fw()` →
  `iwl_mld_cancel_async_notifications()`), but `async_handlers_wk` is
  not cancelled. Same gap on op-mode stop.
- **Symptom:** Pending wiphy work can run after `ieee80211_free_hw()`;
  cfg80211 still drains/cancels and **WARNs**.
- **Failure mode:** use-after-free of wiphy/`iwl_mld` if the work runs;
  otherwise `WARN_ON(!list_empty(&rdev->wiphy_work_list))` in
  `cfg80211_dev_free()`.
- **Root cause:** cancel of `async_handlers_wk` was removed from the
  generic purge helper; start-fail/stop still free the wiphy with work
  queued.
- **Version info in message:** none

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not disguised. Explicit teardown correctness / UAF-prevention.
Not style cleanup.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `drivers/net/wireless/intel/iwlwifi/mld/mld.c` — **+3 lines**, 0
  removed (`git show --stat`: 3 insertions)
- Functions: `iwl_op_mode_mld_start()`, `iwl_op_mode_mld_stop()`
- Scope: **single-file surgical fix**

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:
Hunk 1 (`iwl_op_mode_mld_start`, firmware/NVM failure):
- **Before:** `wiphy_unlock` → `rtnl_unlock` → `goto err` →
  `ieee80211_free_hw()` with `async_handlers_wk` possibly still on
  `wiphy_work_list`.
- **After:** `wiphy_work_cancel(mld->wiphy, &mld->async_handlers_wk)`
  while `wiphy_lock` is still held, then unlock/free.
- Path: **error path** (fw load or NVM read failure during probe/op-mode
  start).

Hunk 2 (`iwl_op_mode_mld_stop`):
- **Before:** lock, `iwl_mld_low_latency_stop` /
  `iwl_mld_deinit_time_sync`, unlock, `ieee80211_unregister_hw` /
  `ieee80211_free_hw`.
- **After:** same, but cancel `async_handlers_wk` under the wiphy lock
  first.
- Path: **teardown** (module unload / transport op-mode leave).

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record:
- **Category:** memory safety (use-after-free of work item / wiphy) +
  leftover-work WARN
- **Mechanism:** `wiphy_work_queue()` during RX after ALIVE;
  `iwl_mld_stop_fw()` purges `async_handlers_list` but (after
  59a5876e474ac) no longer cancels the work. `ieee80211_free_hw()` →
  `wiphy_free()` → `cfg80211_dev_free()` WARNs if the list is non-empty.
  Worker `cfg80211_wiphy_work()` can also run
  `iwl_mld_async_handlers_wk()` after unlock and race teardown.
- **Fix:** `wiphy_work_cancel()` under the wiphy mutex (required by
  `lockdep_assert_held(&wiphy->mtx)` in `wiphy_work_cancel()`).

**Step 2.4: ASSESS THE FIX QUALITY**
Record:
- Obviously correct: both sites already hold `wiphy_lock`; cancel of a
  not-queued work is a no-op (`list_empty` check in
  `wiphy_work_cancel()`).
- Minimal; no API/data-structure change.
- Regression risk: **very low**. Cancel vs flush is appropriate here (do
  not run handlers from a dead/going-away FW). Does not restore the lock
  requirement on `iwl_mld_cancel_async_notifications()`.
- Residual (pre-existing, not introduced here): NVM-fail path still does
  not call `iwl_mld_stop_fw()`; cancel avoids running those handlers
  during free. That is strictly safer than leaving work queued.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

**Step 3.1: BLAME THE CHANGED LINES**
Record:
- Surrounding start-fail/stop skeleton: `d1e879ec600f9` (“wifi: iwlwifi:
  add iwlmld sub-driver”, 2025-02/03) — first appeared in **v6.15**.
- The two new cancel lines: `c99bc4d4e0ba6` (this commit, 2026-07-14).
- Stop-path `wiphy_lock` wrapper: `83128399f3b492` (Benjamin Berg,
  2025-05).

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No `Fixes:` tag. Historical chain (verified with `git show` /
`git log -S`):
1. `4f7a07791944e` (2025-04, Fixes: d1e879ec600f9) — cancel async notifs
   on start failure specifically because work can run after
   `ieee80211_free_hw` (**UAF**).
2. `833026098b2d9` — fold cancel+purge into
   `iwl_mld_cancel_async_notifications()`.
3. **`59a5876e474ac` (2026-05-26, in v7.2, not in v7.1)** — **removed**
   `wiphy_work_cancel()` from that helper so it can run without the
   wiphy lock. That **reopened** the free-without-cancel hole.
4. This commit puts cancel back on the two paths that actually free the
   wiphy.

`59a5876e474ac` **is** an ancestor of this tree (`git merge-base --is-
ancestor` → yes via v7.2).

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record:
- Nearby: `a40ad60a47f7c` purge-on-NIC-error; `59a5876e474ac` remove
  cancel from helper.
- This is **not** patch-dependent on other hunks in the 15-patch
  iwlwifi-next dump; parent is unrelated `21b3263b90e80` (“mvm: validate
  monitor notif link_id”).
- Standalone: **yes**.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Miri Korenblit is a primary iwlwifi MLD author (driver
introduction and most async-handler work). Johannes Berg reviewed. High
confidence in the diagnosis.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record:
- Needs `wiphy_work_*` and `struct wiphy_work async_handlers_wk` —
  present since MLD intro in this tree.
- Needs the start-fail `if (ret)` / stop `wiphy_lock` shape — present.
- Needs `59a5876e474ac` as the regression that made cancel missing; that
  commit is in this tree.
- **Can apply standalone: yes** (already an ancestor of HEAD).

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- `b4 dig -c c99bc4d4e0ba6`: **[PATCH iwlwifi-next 08/15]**
  https://patch.msgid.link/20260714143119.07aa49f755a2.I734a27b1b0eeb5b0
  e821aee3318fee8dc0a6bc03@changeid
- `b4 dig -a`: v1 then **v2** “wifi: iwlwifi: updates - 07-14-2026”
  https://patch.msgid.link/20260714165826.07aa49f755a2.I734a27b1b0eeb5b0
  e821aee3318fee8dc0a6bc03@changeid
  Committed `Link:` is **v2** (latest).
- Lore WebFetch returned **403**; patchwork bot-blocked. Review body
  beyond tags is **UNVERIFIED**. No NAK found in b4 metadata.

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record (`b4 dig -w`): Miri Korenblit; Johannes Berg
(`johannes@sipsolutions.net` / intel.com); `linux-
wireless@vger.kernel.org`. Maintainer was To/Cc and `Reviewed-by`.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: No `Reported-by` / bugzilla / syzbot. Author-found from code
(consistent with 4f7a077’s earlier UAF write-up). User count:
**UNVERIFIED**, but the start-fail path is firmware-load failure — a
real probe path.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: 08/15 of a mixed iwlwifi-next batch, not a dependent 1/N fix
series. Parent commit unrelated. No other series patch required for this
hunk.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: WebSearch of lore.kernel.org/stable for this subject did **not**
find a stable-specific thread. **UNVERIFIED** that anyone nominated or
rejected it on stable@ (absence of Cc:stable is expected).

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

**Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF**
Record: `iwl_op_mode_mld_start`, `iwl_op_mode_mld_stop`. Related
callees: `wiphy_work_cancel`, `iwl_mld_load_fw`, `iwl_mld_stop_fw`,
`ieee80211_free_hw`.

**Step 5.2: TRACE CALLERS**
Record:
- `iwl_mld_ops.start = iwl_op_mode_mld_start` — op-mode start from
  iwlwifi transport when `iwlmld` is selected
  (`iwl_opmode_register("iwlmld", ...)`).
- Stop is the matching `.stop` callback on unbind/unload.
- Context: process, probe/remove — not IRQ. Reachable whenever
  CONFIG_IWLMLD hardware probes or the module is removed.

**Step 5.3: TRACE CALLEES**
Record:
- Start-fail: `iwl_mld_load_fw()` on error after ALIVE calls
  `iwl_mld_stop_fw()` → purges list, does **not** cancel work.
- Then `ieee80211_free_hw()` → `wiphy_free()` → `put_device()` →
  `wiphy_dev_release()` → `cfg80211_dev_free()` which
  `WARN_ON(!list_empty(&rdev->wiphy_work_list))` then
  `cancel_work_sync(&rdev->wiphy_work)`.
- Worker: `cfg80211_wiphy_work()` → `wk->func` →
  `iwl_mld_async_handlers_wk()`.

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: Userspace/admin trigger: load iwlwifi on MLD firmware (Wi-Fi 7
Intel), failed firmware/NVM, or unload. Not a syscall exploit path;
**driver probe/remove**. Common enough for production laptops.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: MVM already cancels/flushes analog work in `iwl_mvm_mac_stop()`
(`wiphy_work_cancel` on `async_handlers_wiphy_wk`). MLD
`iwl_mld_mac80211_stop()` already cancels `add_txqs_wk` but **not**
`async_handlers_wk`. This commit aligns MLD teardown with that rule.

===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record:
- Local tree: **v7.3-rc4** (`git describe HEAD` →
  `v7.3-rc4-27-gf0100363d8c37`; `VERSION=7 PATCHLEVEL=3 SUBLEVEL=0
  EXTRAVERSION=-rc4`).
- MLD driver **present**
  (`drivers/net/wireless/intel/iwlwifi/mld/mld.c`).
- Regression `59a5876e474ac` **is** in this history (v7.2+).
- Current file already contains both `wiphy_work_cancel` calls (this
  commit is ancestor of HEAD). Pre-fix parent of `c99bc4d4e0ba6` matches
  the supplied diff exactly.
- Bug was introduced **before** this 7.3 branch (in v7.2), not after.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: **Clean apply** on this tree (already applied). Surrounding
`iwl_op_mode_mld_start`/`stop` matches the patch. `wiphy_work_cancel`
exists in `net/wireless/core.c`.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: `4f7a07791944e` / `833026098b2d9` / `59a5876e474ac` are all
here. No alternate fix of this hole besides `c99bc4d4e0ba6`. `git log
--grep='cancel wiphy work'` only this commit.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: `drivers/net/wireless/intel/iwlwifi/mld` — Intel Wi-Fi MLD
(CONFIG_IWLMLD). **IMPORTANT** (shipping Wi-Fi 7 NICs), not core mm/VFS,
not staging.

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: Very active (NAN, RSC, scan, firmware API churn in recent `git
log` on `mld.c`). Mature enough that this is a teardown correctness fix,
not new-feature scaffolding.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: **driver-specific / config-specific** — CONFIG_IWLMLD users
(Intel MLD firmware devices). Not universal.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record:
- Start-fail: firmware load/init failure after ALIVE (missing/bad fw,
  PNVM/init timeout) — **realistic probe path**.
- Stop: op-mode teardown/unload.
- Timing: leftover `wiphy_work` after list purge.
- Unprivileged trigger: only if an unprivileged user can unload the
  driver or force fw failure — typically **admin/probe**. Not a syzbot-
  style syscall UAF, but probe-fail is still user-visible.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record:
- Confirmed: `WARN_ON` in `cfg80211_dev_free()` if work remains queued
  (taint; panic if `panic_on_warn`).
- Author/prior commit (`4f7a077`): work running after
  `ieee80211_free_hw` is **UAF**. cfg80211’s `cancel_work_sync` in
  `cfg80211_dev_free` reduces but does not make the WARN or the post-
  unlock race imaginary (`cfg80211_wiphy_work` can run after
  `wiphy_unlock` and before free).
- Severity: **HIGH** (WARN + realistic UAF race on probe fail / unload).

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record:
- Benefit: **high** for IWLMLD users — stops WARN/UAF on fw init failure
  and stop.
- Risk: **very low** — 3 lines, existing API, lock already held.
- Ratio: strongly in favor of including the fix.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

**Step 9.1: COMPILE THE EVIDENCE**

FOR:
- Real teardown bug: pending `async_handlers_wk` after wiphy free
- Regression from `59a5876e474ac` (in this tree); restores cancel only
  where memory is freed
- Same UAF class as `4f7a07791944e` (explicit “access freed memory”)
- 3-line, obviously correct, maintainer Reviewed-by
- Applies to this tree’s MLD code; prerequisites present
- cfg80211 documents leftover work with WARN_ON

AGAINST:
- No Fixes:/Cc:stable/Reported-by (not a negative per pipeline rules)
- Error/teardown path, not hot datapath
- cfg80211 already `cancel_work_sync`s, so many hits are WARN rather
  than a guaranteed oops
- 08/15 series member (but standalone)

UNRESOLVED:
- Full lore review text (HTTP 403)
- Whether stable@ already discussed this subject
- How often start-fail hits with work still queued (depends on
  notifications after ALIVE)

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — lock already held; Johannes
   reviewed; cancel is the documented API.
2. Fixes a real bug that affects users? **PASS** — leftover wiphy work
   on fw-start failure and op-mode stop.
3. Important issue? **PASS** — UAF risk + `WARN_ON` in cfg80211 (HIGH).
4. Small and contained? **PASS** — +3 lines, one file, two call sites.
5. No new features or APIs? **PASS**.
6. Can apply to the local tree? **PASS** — MLD + `wiphy_work_cancel` +
   matching functions exist (commit already in 7.3-rc4).

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: Not a device-ID/quirk/DT/build/docs exception. Ordinary small
bugfix.

**Step 9.4: MAKE YOUR DECISION**

This tree is **7.3-rc4** and contains the iwlwifi MLD op-mode. The hole
is real here: after `59a5876e474ac`, start-fail and stop free the wiphy
without cancelling `async_handlers_wk`. That is a use-after-free/WARN
class bug on firmware load failure — a path users hit. The fix is three
lines, matches cfg80211’s contract, and does not need the rest of the
15-patch series.

---

### What the commit solves
On MLD op-mode start, firmware can ALIVE and queue `async_handlers_wk`.
Failure then purges the handler list in `iwl_mld_stop_fw()` but leaves
the wiphy work queued. `ieee80211_free_hw()` then frees that memory.
cfg80211 still `cancel_work_sync`s and **WARNs**; there is also a window
after `wiphy_unlock` where the worker can run. The same missing cancel
exists in `iwl_op_mode_mld_stop`. Cancelling under the wiphy lock closes
that.

### Stable rules
Meets all six criteria for **this** tree: small, correct, no new API,
real WARN/UAF, code present.

### Risk vs benefit
Benefit high for Intel MLD hardware; risk very low (idempotent cancel,
lock already held).

### Concerns
None that block inclusion. Not a dependent series member. NVM-fail still
does not `iwl_mld_stop_fw()` (pre-existing); this patch still improves
that path by not leaving work queued.

Verification:
- [Phase 1] Parsed subject/tags: Reviewed-by Johannes Berg; Link to v2
  msgid; no Fixes/Cc:stable/Reported-by
- [Phase 1] Body: purge-without-cancel on start-fail and stop; work vs
  freed wiphy; cfg80211 WARN
- [Phase 2] Diff: +3 lines in `mld.c`; `iwl_op_mode_mld_start` error
  path and `iwl_op_mode_mld_stop`; `wiphy_work_cancel`
- [Phase 2] `wiphy_work_cancel()` in `net/wireless/core.c` requires
  wiphy mutex; both sites already `wiphy_lock`
- [Phase 2] `cfg80211_dev_free()`:
  `WARN_ON(!list_empty(&rdev->wiphy_work_list))` then `cancel_work_sync`
- [Phase 3] `git describe HEAD`: v7.3-rc4-27-gf0100363d8c37; `make
  kernelversion` 7.3.0-rc4
- [Phase 3] `git merge-base --is-ancestor c99bc4d4e0ba6 HEAD` → yes
- [Phase 3] `git blame` start-fail/stop: skeleton `d1e879ec600f9` (MLD
  intro); cancel lines this commit
- [Phase 3] MLD first in v6.15 (`git merge-base --is-ancestor
  d1e879ec600f9 v6.15`); not in v6.14
- [Phase 3] `git show 59a5876e474ac`: removed `wiphy_work_cancel` from
  `iwl_mld_cancel_async_notifications`; in v7.2, not v7.1
- [Phase 3] `git show 4f7a07791944e`: original UAF fix on start-fail;
  Fixes: d1e879ec600f9
- [Phase 3] `git log -S wiphy_work_cancel -- mld/`: d1e879ec, 4f7a077,
  833026, 59a5876, c99bc4d4
- [Phase 3] Parent of candidate is unrelated mvm change; series 08/15 is
  a mixed iwlwifi-next batch
- [Phase 4] `b4 dig -c`: lore/patchwork msgid for 08/15; `-a`: v1 then
  v2 (applied); `-w`: Johannes + linux-wireless
- [Phase 4] WebFetch lore 403; patchwork bot wall; spinics 500 — review
  comments UNVERIFIED
- [Phase 4] No stable@ hit for this subject (search not useful)
- [Phase 5] `iwl_mld_ops.start` = `iwl_op_mode_mld_start`; RX path
  `wiphy_work_queue(&mld->async_handlers_wk)` in `notif.c`
- [Phase 5] `iwl_mld_load_fw` error after init sequence calls
  `iwl_mld_stop_fw` (purge, no cancel)
- [Phase 5] MVM `iwl_mvm_mac_stop` already cancels analogous wiphy work
- [Phase 6] Local `mld.c` already has both cancel sites; pre-image of
  parent matches the candidate diff
- [Phase 7] CONFIG_IWLMLD in
  `drivers/net/wireless/intel/iwlwifi/Kconfig`
- [Phase 8] Trigger: fw load fail after ALIVE / op-mode stop; severity
  HIGH (WARN + UAF race)
- UNVERIFIED: exact lore review discussion text; field frequency of this
  WARN

**YES**

 drivers/net/wireless/intel/iwlwifi/mld/mld.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mld.c b/drivers/net/wireless/intel/iwlwifi/mld/mld.c
index cf003a4a37408..49fcbe6814677 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/mld.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/mld.c
@@ -440,6 +440,8 @@ iwl_op_mode_mld_start(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg,
 	}
 
 	if (ret) {
+		/* wiphy memory is about to be freed, we should cancel any pending work */
+		wiphy_work_cancel(mld->wiphy, &mld->async_handlers_wk);
 		wiphy_unlock(mld->wiphy);
 		rtnl_unlock();
 		goto err;
@@ -505,6 +507,7 @@ iwl_op_mode_mld_stop(struct iwl_op_mode *op_mode)
 	iwl_mld_thermal_exit(mld);
 
 	wiphy_lock(mld->wiphy);
+	wiphy_work_cancel(mld->wiphy, &mld->async_handlers_wk);
 	iwl_mld_low_latency_stop(mld);
 	iwl_mld_deinit_time_sync(mld);
 	wiphy_unlock(mld->wiphy);
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18-6.12] wifi: ath12k: avoid setting 320MHz support on non 6GHz band
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (22 preceding siblings ...)
  2026-10-19 13:50 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: mld: cancel wiphy work before freeing wiphy Sasha Levin
@ 2026-10-19 13:50 ` Sasha Levin
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: mld: reset the driver state upon firmware recovery Sasha Levin
                   ` (16 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:50 UTC (permalink / raw)
  To: patches, stable
  Cc: Nicolas Escande, Baochen Qiang, Rameshkumar Sundaram,
	Jeff Johnson, Sasha Levin, jjohnson, linux-wireless, ath12k,
	linux-kernel

From: Nicolas Escande <nico.escande@gmail.com>

[ Upstream commit eaf478b3ea68e1b5df659acd24c4df5850e12325 ]

On a split phy qcn9274 (2.4GHz + 5GHz low), "iw phy" reports 320MHz
related features on the 5GHz band while it should not:

    Wiphy phy1
    [...]
        Band 2:
    [...]
            EHT Iftypes: managed
    [...]
                EHT PHY Capabilities: (0xe2ffdbe018778000):
                    320MHz in 6GHz Supported
    [...]
                    Beamformee SS (320MHz): 7
    [...]
                    Number Of Sounding Dimensions (320MHz): 3
    [...]
                EHT MCS/NSS: (0x22222222222222222200000000):

This is also reflected in the beacons sent by a mesh interface started on
that band. They erroneously advertise 320MHz support too.

This should not happen as IEEE Std 802.11-2024, subclause 9.4.2.323.3 says
we should not set the 320MHz related fields when not operating on a 6GHz
band. For example it says about Bit 0 "Support For 320 MHz In 6 GHz"

  "Reserved if the EHT Capabilities element is indicating capabilities for
   the 2.4 GHz or 5 GHz bands."

Fix this by clearing the related bits when converting from WMI eht phy
capabilities to mac80211 phy capabilities, for bands other than 6GHz.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00218-QCAHKSWPL_SILICONZ-1

Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Link: https://patch.msgid.link/20260623151613.72113-1-nico.escande@gmail.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

This is a 6.18.y tree (`v6.18.53`). The patch is a small ath12k
firmware-workaround that stops 5 GHz/2.4 GHz from advertising 6 GHz-only
320 MHz EHT bits, including in mesh beacons.

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: PARSE THE SUBJECT LINE**
- Record: `[ath12k / wifi] [avoid] [do not advertise 320 MHz EHT
  capabilities on non-6 GHz bands]`

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
- Record:
  - No `Fixes:` tag (expected for this review; Qualcomm review of v2
    asked for one because the bug is user-visible, and v3 still omitted
    it)
  - No `Reported-by:`, `Tested-by:`, `Cc: stable`
  - `Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>`
  - `Reviewed-by: Rameshkumar Sundaram
    <rameshkumar.sundaram@oss.qualcomm.com>`
  - `Link: https://patch.msgid.link/20260623151613.72113-1-
    nico.escande@gmail.com`
  - `Signed-off-by: Nicolas Escande` (author)
  - `Signed-off-by: Jeff Johnson` (ath maintainer; applied to ath-next)
  - `Tested-on: QCN9274 hw2.0 PCI ...` (hardware test, not a tag)
  - Ignore `[Upstream commit eaf478b3ea68...]` and `Signed-off-by: Sasha
    Levin` (pipeline)

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
- Record: On split-phy QCN9274 (2.4 GHz + 5 GHz low), firmware-reported
  EHT PHY caps are copied onto the 5 GHz band, so `iw phy` shows “320MHz
  in 6GHz Supported”, beamformee SS 320 MHz, and 320 MHz sounding
  dimensions. Mesh beacons on that band advertise the same. IEEE
  802.11-2024 9.4.2.323.3 marks those fields reserved off 6 GHz.
- Symptom: wrong userspace capability dump and wrong over-the-air EHT
  Capabilities IE.
- Root cause: WMI EHT PHY caps are copied as-is; 320 MHz/6 GHz bits are
  not cleared for 2.4/5 GHz.
- Version info: none beyond QCN9274 test hardware.

**Step 1.4: DETECT HIDDEN BUG FIXES**
- Record: Not a disguised cleanup. It is an explicit correctness/spec
  fix (firmware workaround). “Avoid setting” here means “stop
  advertising reserved bits.”

## PHASE 2: DIFF ANALYSIS

**Step 2.1: INVENTORY THE CHANGES**
- Record: Single file `drivers/net/wireless/ath/ath12k/wmi.c`, +16/−1.
  Function: `ath12k_wmi_eht_caps_parse()`. Surgical, one-driver.

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
- Before: after `le32_to_cpu()` of firmware PHY caps, only the 6 GHz
  path ORs back a saved 320 MHz bit. 2.4/5 GHz keep whatever firmware
  sent, including 320 MHz/6 GHz bits.
- After: 6 GHz path unchanged; non-6 GHz path clears eight reserved 320
  MHz/6 GHz fields in the byte view of `eht_cap_phy_info[]`.
- Path: capability parse at firmware ready / MAC-PHY caps-ext, not a hot
  datapath.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
- Record: Category (h) firmware workaround + (g) protocol correctness.
- Mechanism: firmware reports 6 GHz/320 MHz caps on the 5 GHz WMI blob.
  Those bits are memcpy’d into mac80211 `ieee80211_sta_eht_cap`
  (`ath12k_mac_copy_eht_cap()`). `ieee80211_eht_mcs_nss_size()` adds 3
  MCS/NSS bytes when `IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ` is set, so
  5 GHz beacons can carry a longer EHT Capabilities IE than a spec-
  compliant peer expects. cfg80211 still refuses 320 MHz off 6 GHz
  (`net/wireless/chan.c`), so the kernel will not actually operate at
  320 MHz on 5 GHz.

**Step 2.4: ASSESS THE FIX QUALITY**
- Record: Obviously correct. Masks match
  `include/linux/ieee80211-eht.h`. `WMI_MAX_EHTCAP_PHY_SIZE` is 3 u32s
  (12 bytes); `phy_cap[7]` is in range. u8 overlay of a host-endian u32
  array matches existing ath12k memcpy of the same array into
  `phy_cap_info[]` (little-endian hosts, which is where QCN9274 runs).
  No API/lock/alloc change. Regression risk is low: only reserved bits
  on non-6 GHz are cleared. Review expanded v1’s incomplete mask set; v3
  clears the full set Qualcomm asked for.

## PHASE 3: GIT HISTORY INVESTIGATION

**Step 3.1: BLAME THE CHANGED LINES**
- Record: Function added in `1476014fadb662` (“wifi: ath12k: WMI support
  to process EHT capabilities”), contained in `v6.6-rc1`. 320 MHz
  preserve/OR logic added in `d4e244c85e45df` (“enable 320 MHz bandwidth
  for 6 GHz… WCN7850”), in v6.7. Buggy “copy firmware bits onto 5 GHz
  unchanged” behavior is as old as EHT parse in this driver (~v6.6).
  Present throughout 6.18.

**Step 3.2: FOLLOW THE FIXES: TAG**
- Record: No `Fixes:` tag. Closest introducing commits are
  `1476014fadb662` and `d4e244c85e45df`; both are ancestors of `v6.18`.
  No later follow-up on this file after the upstream commit.

**Step 3.3: CHECK FILE HISTORY**
- Record: Nearby `wmi.c` work is unrelated (endianness, TLV length,
  scan). Standalone; not patch X/Y.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
- Record: Nicolas Escande is a regular ath11k/ath12k contributor
  (Freebox/Iliad), not the subsystem maintainer. Jeff Johnson applied
  it. Qualcomm (Baochen Qiang, Rameshkumar Sundaram) reviewed.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
- Record: None. Uses existing `NL80211_BAND_*` and
  `IEEE80211_EHT_PHY_CAP*` symbols already in this tree. Applies
  standalone.

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
- Record: `b4 dig -c eaf478b3ea68` →
  https://patch.msgid.link/20260623151613.72113-1-nico.escande@gmail.com
- Series: v1 (2026-01-23) → v2 (2026-06-11) → v3 (2026-06-23, applied).
  v1 incomplete masks; v2/v3 clear remaining 320 MHz/6 GHz fields after
  Qualcomm/Pablo feedback. v3 vs v2 is comment/typo/spec-citation
  cleanup.
- No NAKs. Jeff Johnson: “Applied, thanks!”
- No reviewer `Cc: stable` on v3.

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
- Record (`b4 dig -w`): To/Cc `ath12k@lists.infradead.org`, `linux-
  wireless@vger.kernel.org`. Reviewers: Rameshkumar Sundaram, Baochen
  Qiang (Qualcomm). Johannes Berg (mac80211) on v1: this is a firmware
  workaround and belongs in the driver, not mac80211. Pablo MARTIN-GOMEZ
  (Freebox) pointed out missing CAP7 bits.

**Step 4.3: SEARCH FOR THE BUG REPORT**
- Record: No syzbot/bugzilla. Author reproduced on QCN9274 split-phy;
  `iw phy` dump and mesh beacons in the message. Real hardware, not
  theoretical.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
- Record: Single-patch series. v1→v3 only refined which reserved bits to
  clear. No hidden dependency.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
- Record: No useful stable-list discussion of this subject. WebSearch of
  lore stable did not turn up this patch. UNVERIFIED beyond that (lore
  HTTP 403 on direct fetch; thread recovered via `b4`).

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1: KEY FUNCTIONS**
- Record: `ath12k_wmi_eht_caps_parse()` only.

**Step 5.2: TRACE CALLERS**
- Record: Only from `ath12k_wmi_tlv_mac_phy_caps_ext_parse()` for 2.4 /
  5 / 6 GHz. That is called from `ath12k_wmi_tlv_mac_phy_caps_ext()`,
  registered as the WMI TLV parser for
  `WMI_TAG_MAC_PHY_CAPABILITIES_EXT` during service-ready. Device bring-
  up, not IRQ/hot path.

**Step 5.3: TRACE CALLEES**
- Record: `le32_to_cpu()` and bit clears only. No alloc/lock/IO.

**Step 5.4: FOLLOW THE CALL CHAIN**
- Record: firmware ready → WMI caps-ext → `ath12k_mac_copy_eht_cap()` →
  mac80211 sband iftype data → `iw phy`, association, and beacon IEs.
  Reachable for any ath12k user with 11be firmware (QCN9274, WCN7850,
  etc.). Unprivileged users cannot trigger a crash; they do
  see/advertise wrong caps. Mesh/AP beacons go over the air.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
- Record: rtw89 and mt76 only *set* 320 MHz bits when `band ==
  NL80211_BAND_6GHZ`. mac80211 strips 320 MHz bits when `bw_limit <
  320`. ath12k was the outlier that trusted firmware on 5 GHz.

## PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
- Record: Yes. Tree is `v6.18.53` (`VERSION=6 PATCHLEVEL=18
  SUBLEVEL=53`). `git merge-base --is-ancestor eaf478b3ea68 v6.18.53` is
  false — the fix is not in 6.18.53. Parent of the candidate still has
  the old if-only-6 GHz OR. `1476014fadb662` and `d4e244c85e45df` *are*
  in v6.18. Bug exists here.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
- Record: Clean apply. Context in this tree matches (function at ~4937).
  All masks exist in `include/linux/ieee80211-eht.h`. Expected
  difficulty: clean apply.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
- Record: No other commit in this tree clears these bits in
  `ath12k_wmi_eht_caps_parse()`. `ath12k_mac_filter_eht_cap_mesh()` only
  strips some CAP7 bits for mesh iftypes, not CAP0 320 MHz-in-6 GHz, so
  it does not replace this fix.

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: SUBSYSTEM AND CRITICALITY**
- Record: `drivers/net/wireless/ath/ath12k` — Qualcomm Wi-Fi 7.
  Criticality: IMPORTANT (production Wi-Fi 7, not core mm/net).
  `CONFIG_ATH12K`.

**Step 7.2: SUBSYSTEM ACTIVITY**
- Record: Active (many 2026 ath12k WMI commits). This bug is old (v6.6),
  not a regression from brand-new code.

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: WHO IS AFFECTED**
- Record: ath12k users, especially split-phy QCN9274 5 GHz (author’s
  case) and any firmware that sets 320 MHz bits in the 2.4/5 GHz WMI
  blob. Not universal.

**Step 8.2: TRIGGER CONDITIONS**
- Record: Device probe / cap parse whenever firmware reports those bits.
  Common on affected SKUs. Unprivileged users do not get a kernel
  exploit; they get wrong `iw` output and wrong beacon IEs. Not a race.

**Step 8.3: FAILURE MODE SEVERITY**
- Record: Not a panic/UAF/deadlock. Kernel will not run 320 MHz on 5 GHz
  (`chan.c` requires 6 GHz; MLME 320 MHz limit is `is_6ghz && cap bit`).
  User impact is (1) wrong `iw phy`, (2) reserved bits in beacons, (3)
  extra 3-byte 320 MHz MCS/NSS field in the EHT Capabilities IE, which
  can confuse spec-compliant peers. Severity: MEDIUM (protocol/interop),
  not CRITICAL.

**Step 8.4: RISK-BENEFIT RATIO**
- Benefit: medium for QCN9274/mesh/AP users; stops malformed EHT IEs.
  Risk: very low (~15 lines, reserved-bit clears, reviewed, tested).
  Ratio: favorable.

## PHASE 9: FINAL SYNTHESIS

**Step 9.1: EVIDENCE**

FOR:
- Real hardware bug (QCN9274), user-visible `iw phy` and mesh beacons
- Malformed EHT Capabilities IE (reserved bit + extra MCS/NSS bytes) —
  interoperability, not just cosmetics
- Small, obviously correct, constants and function exist in 6.18
- Reviewed by Qualcomm; applied by Jeff Johnson; Johannes agrees it is a
  driver firmware workaround
- No new API; no prerequisites missing in this tree
- Analogous to a hardware/firmware quirk

AGAINST:
- Not a crash, leak, UAF, deadlock, or CVE
- Johannes noted most extra 320 MHz bits are unused at runtime; cfg80211
  already blocks 320 MHz off 6 GHz
- Author never added `Fixes:` even after Rameshkumar asked
- Affects one driver / specific firmware behavior

UNRESOLVED:
- Direct lore.kernel.org HTTP fetch returned 403; discussion recovered
  via `b4` mbox
- No stable-list thread found

**Step 9.2: STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — masks match the spec;
   Tested-on QCN9274; two Qualcomm Reviewed-by
2. Fixes a real bug that affects users? **PASS** — observed wrong caps
   and wrong beacons
3. Important issue? **PASS** (medium) — OTA IE malformation/interop on
   Wi-Fi 7 APs/mesh, not a crash. Within “etc.” for driver protocol bugs
   / firmware quirks
4. Small and contained? **PASS** — 16 insertions, one function
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — code and symbols present;
   clean apply

**Step 9.3: EXCEPTION CATEGORIES**
- Record: Firmware/hardware workaround (quirk-like). Not a new device
  ID, DT, or build fix.

**Step 9.4: DECISION**
Backport to this 6.18.y tree. The bug is in 6.18, the fix is surgical,
and wrong EHT IEs on 5 GHz are a real user-visible protocol defect on
shipping QCN9274 hardware.

---

Verification:
- [Phase 1] Parsed tags: Reviewed-by Baochen Qiang, Rameshkumar
  Sundaram; Link msgid; Tested-on QCN9274; no Fixes/Reported-
  by/Cc:stable
- [Phase 1] Body: split-phy QCN9274 `iw phy` + mesh beacons advertise
  320 MHz on 5 GHz; IEEE 802.11-2024 9.4.2.323.3 reserved-bit citation
- [Phase 2] Diff: `ath12k_wmi_eht_caps_parse()` +16/−1; else-branch
  clears 8 reserved PHY bits
- [Phase 2] `WMI_MAX_EHTCAP_PHY_SIZE == 3` (12 bytes); `phy_cap[7]` in
  bounds (`wmi.h:2767`)
- [Phase 2] Masks verified in `include/linux/ieee80211-eht.h` (CAP0
  0x02, CAP1 0xe0, CAP2 0xc0, CAP3 0x01, CAP6 MCS15 0x40 / DUP 0x80,
  CAP7 0x08 / 0x40)
- [Phase 3] `git blame`: function `1476014fadb662` (v6.6-rc1); 320 MHz
  OR `d4e244c85e45df` (v6.7)
- [Phase 3] `git merge-base --is-ancestor 1476014fadb662 v6.18` and
  `d4e244c85e45df v6.18`: both true
- [Phase 3] No `Fixes:` tag; no follow-up on `wmi.c` after upstream
  `eaf478b3ea68`
- [Phase 4] `b4 dig -c eaf478b3ea68`: lore URL; v1/v2/v3; v3 applied as
  `eaf478b3ea68`
- [Phase 4] `b4 dig -w`: ath12k + linux-wireless lists
- [Phase 4] v1 mbox: Johannes — firmware workaround, belongs in driver;
  Pablo — missing CAP7; Rameshkumar — also clear CAP3/CAP6 DUP/CAP7
- [Phase 4] v2 mbox: Rameshkumar asked for `Fixes:` because it is user-
  visible; author did not add it in v3
- [Phase 4] v3 mbox: both Qualcomm Reviewed-by; Jeff Johnson applied; no
  NAK; no Cc:stable
- [Phase 4] lore WebFetch 403; thread read from `b4 dig -m` / `b4 mbox`
- [Phase 5] Callers: only `ath12k_wmi_tlv_mac_phy_caps_ext_parse` → WMI
  service-ready. Impact via `ath12k_mac_copy_eht_cap` /
  `ath12k_mac_copy_eht_mcs_nss` (320 MHz MCS copy gated on CAP0 bit)
- [Phase 5] `ieee80211_eht_mcs_nss_size()` adds 3 bytes when CAP0 320
  MHz bit is set — IE length bug on 5 GHz
- [Phase 5] `net/wireless/chan.c`: 320 MHz rejected unless band is 6 GHz
  — no local 320 MHz operation on 5 GHz
- [Phase 6] `git describe HEAD`: `v6.18.53-5049-g0f0bdc2b0dffb`; `make
  kernelversion`: 6.18.53
- [Phase 6] `git merge-base --is-ancestor eaf478b3ea68 v6.18.53`: false
  — fix not in 6.18.53
- [Phase 6] Parent of candidate still has old if-only-6 GHz code;
  constants present
- [Phase 7] Subsystem ath12k, CONFIG_ATH12K, important Wi-Fi 7 driver
- [Phase 8] Failure mode: wrong IEs / interop, not oops; severity
  MEDIUM; backport risk very low
- UNVERIFIED: no independent user bugzilla beyond the author’s QCN9274
  report; stable@ lore search did not find this patch

The fix is small, already reviewed, and addresses a real over-the-air
capability bug that exists in this 6.18 tree.

**YES**

 drivers/net/wireless/ath/ath12k/wmi.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index ade14ba6703f3..39d5110eca901 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -4939,6 +4939,7 @@ static void ath12k_wmi_eht_caps_parse(struct ath12k_pdev *pdev, u32 band,
 				       __le32 cap_info_internal)
 {
 	struct ath12k_band_cap *cap_band = &pdev->cap.band[band];
+	u8 *phy_cap = (u8 *)&cap_band->eht_cap_phy_info[0];
 	u32 support_320mhz;
 	u8 i;
 
@@ -4952,8 +4953,22 @@ static void ath12k_wmi_eht_caps_parse(struct ath12k_pdev *pdev, u32 band,
 	for (i = 0; i < WMI_MAX_EHTCAP_PHY_SIZE; i++)
 		cap_band->eht_cap_phy_info[i] = le32_to_cpu(cap_phy_info[i]);
 
-	if (band == NL80211_BAND_6GHZ)
+	if (band == NL80211_BAND_6GHZ) {
 		cap_band->eht_cap_phy_info[0] |= support_320mhz;
+	} else {
+		/*
+		 * Firmware may report 6 GHz/320 MHz specific capabilities for
+		 * non-6 GHz bands, so explicitly clear them.
+		 */
+		phy_cap[0] &= ~IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ;
+		phy_cap[1] &= ~IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_320MHZ_MASK;
+		phy_cap[2] &= ~IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_320MHZ_MASK;
+		phy_cap[3] &= ~IEEE80211_EHT_PHY_CAP3_SOUNDING_DIM_320MHZ_MASK;
+		phy_cap[6] &= ~IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_320MHZ;
+		phy_cap[6] &= ~IEEE80211_EHT_PHY_CAP6_EHT_DUP_6GHZ_SUPP;
+		phy_cap[7] &= ~IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_320MHZ;
+		phy_cap[7] &= ~IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_320MHZ;
+	}
 
 	cap_band->eht_mcs_20_only = le32_to_cpu(supp_mcs[0]);
 	cap_band->eht_mcs_80 = le32_to_cpu(supp_mcs[1]);
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18] wifi: iwlwifi: mld: reset the driver state upon firmware recovery
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (23 preceding siblings ...)
  2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-6.12] wifi: ath12k: avoid setting 320MHz support on non 6GHz band Sasha Levin
@ 2026-10-19 13:51 ` Sasha Levin
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: mld: support aborting an ongoing ftm request Sasha Levin
                   ` (15 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:51 UTC (permalink / raw)
  To: patches, stable
  Cc: Emmanuel Grumbach, Miri Korenblit, Sasha Levin, linux-wireless,
	linux-kernel

From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>

[ Upstream commit 71ac392d8b5c23c45c66f30eff1c319580ada4da ]

Just like we did in iwlmvm, we also need to clear the mld state when the
firmware was killed because of the device being powered off during
suspend.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Link: https://patch.msgid.link/20260714165826.ff1c9e05e0a9.I8df8d4a0384065fd2a32cf258339be77084c55bd@changeid
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

I have enough of the tree, the sibling mvm fix, and the lore series to
judge this on merit. Writing the full phase-by-phase analysis next.

---

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: PARSE THE SUBJECT LINE**

Record: **[iwlwifi/mld] [reset] [clear MLD driver state when firmware is
killed because the device was powered off during suspend]**

- Subsystem: `wifi: iwlwifi: mld`
- Action verb: **reset** (correctness / recovery, not a feature)
- Intent: after firmware recovery from a power-off-during-suspend, wipe
  MLD software state the same way `iwlmvm` already does

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**

Record (from `git show 71ac392d8b5c2`):
- **Fixes:** none (expected for this review pipeline)
- **Reported-by:** none
- **Tested-by:** none
- **Reviewed-by:** none on the commit itself
- **Acked-by:** none
- **Link:** `https://patch.msgid.link/20260714165826.ff1c9e05e0a9.I8df8d
  4a0384065fd2a32cf258339be77084c55bd@changeid`
- **Cc: stable:** none (not a negative signal)
- **Signed-off-by:** Emmanuel Grumbach (author); Miri Korenblit (iwlwifi
  maintainer)
- Ignore pipeline markers: none present on the original commit

Notable: Intel iwlwifi developers; maintainer SOB; no syzbot/user
reports.

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**

Record:
- **Bug:** When firmware is killed because the NIC was powered off in
  suspend, MLD driver state is left as if the firmware were still
  configured.
- **Symptom:** After that resume path, software
  IDs/keys/scan/FTM/internal STAs no longer match a freshly started
  firmware image. Connection/recovery after suspend can fail; later FW
  commands can error or WARN.
- **Version info:** none in the message. Analog is explicit: “Just like
  we did in iwlmvm”.
- **Root cause (author):** `device_powered_off` stopped firmware
  (`iwl_mld_stop_fw`) and cleared `in_d3`, but never ran the existing
  restart cleanup that zeros restart-sensitive state and walks
  vifs/stations.

**Step 1.4: DETECT HIDDEN BUG FIXES**

Record: **Not disguised.** It is a real recovery-path correctness fix.
“Reset the driver state” is the missing counterpart of
`iwl_mld_restart_cleanup()` already used from `iwl_mld_mac80211_start()`
when `in_hw_restart` is set. The mvm sibling (`0a00c3ec2db76`) states
the same problem more clearly: after power-off, firmware must be
reloaded **and reconfigured**.

---

## PHASE 2: DIFF ANALYSIS - LINE BY LINE

**Step 2.1: INVENTORY THE CHANGES**

Record:
- `drivers/net/wireless/intel/iwlwifi/mld/mac80211.c`:
  `iwl_mld_restart_cleanup` un-static’d (`static void` → `void`) — **3
  +/− lines net**
- `drivers/net/wireless/intel/iwlwifi/mld/mac80211.h`: export prototype;
  copyright year — **+2**
- `drivers/net/wireless/intel/iwlwifi/mld/mld.c`: one call
  `iwl_mld_restart_cleanup(mld);` in `iwl_mld_device_powered_off` —
  **+1**
- Totals: **+4 / −2**, three files, one function body unchanged
- Scope: **single-subsystem, surgical**

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**

Hunk 1 (`mac80211.c`): `iwl_mld_restart_cleanup` still does
`iwl_cleanup_mld` → iterate vifs (`iwl_mld_cleanup_vif`) → iterate
stations (`iwl_mld_cleanup_sta`) → `iwl_mld_ftm_restart_cleanup`. Only
linkage changes (now callable from `mld.c`).

Hunk 2 (`mac80211.h`): prototype so `mld.c` can call it. `mld.c` already
includes `mac80211.h`.

Hunk 3 (`mld.c` `iwl_mld_device_powered_off`, `CONFIG_PM_SLEEP`):

**Before:**
```
wiphy_lock
iwl_mld_stop_fw(mld)   // abort waits, stop device, fw_status.running =
false
in_d3 = false
wiphy_unlock
```

**After:** same, plus `iwl_mld_restart_cleanup(mld)` between stop_fw and
clearing `in_d3`.

Path: PCI resume when scratch/MAC grab shows the device was powered off
(`iwl_op_mode_device_powered_off` from `pcie/drv.c`). Not the happy
wowlan-keep-alive path.

**Step 2.3: IDENTIFY THE BUG MECHANISM**

Record: **[Logic / correctness — stale driver state after firmware
death]**

Without cleanup, `iwl_mld_mac80211_start` sees `in_d3 == false`, skips
D3 resume, and calls `iwl_mld_start_fw()` **without**
`iwl_mld_restart_cleanup()`. Firmware is empty; driver still holds:
- `zeroed_on_hw_restart` groups (phy, scan, iface, link, sta, txq)
- firmware station IDs / internal STAs
- keys
- FTM initiator request

`iwl_mld_cleanup_vif` frees internal STAs and keys; skipping it on this
path is a leak plus ID mismatch. Category is **incomplete error/recovery
handling**, not a new feature.

**Step 2.4: ASSESS THE FIX QUALITY**

Record:
- **Obviously correct:** reuses the function already used on HW restart;
  mvm does the same from `iwl_op_mode_mvm_device_powered_off`
  (`iwl_mvm_restart_cleanup`).
- **Minimal:** one call + un-static.
- **Regression risk low:** already runs under `wiphy_lock` from
  `iwl_mld_mac80211_start`; `device_powered_off` already takes
  `wiphy_lock`. Cleanup is largely idempotent (`CLEANUP_STRUCT` memset,
  `sta_id != IWL_INVALID_STA` guards). FTM abort on a dead NIC during
  resume is appropriate.
- **Redundant** `in_d3 = false` after `iwl_cleanup_mld` also clears it —
  harmless.
- No public API / data-structure change except making an existing helper
  non-static.

---

## PHASE 3: GIT HISTORY INVESTIGATION

**Step 3.1: BLAME THE CHANGED LINES**

Record:
- Buggy `iwl_mld_device_powered_off` introduced in **`d1e879ec600f9`**
  (`wifi: iwlwifi: add iwlmld sub-driver`, 2025-03-05; that commit’s
  Makefile is **6.14.0-rc4**).
- Merged to this lineage via `c73ebc0dbb6ed` (`iwlwifi-
  next-2025-06-25`).
- Intermediate: `7aeec8c8d63bf` removed `system_pm_mode` assignment;
  still no cleanup.
- `iwl_mld_restart_cleanup` existed as **static** since MLD
  introduction; this commit only exports it.

**Step 3.2: FOLLOW THE FIXES: TAG**

Record: **No Fixes: tag.** Bug is original MLD `device_powered_off`
(omit cleanup). Target `d1e879ec600f9` **is** an ancestor of this tree
(`git merge-base --is-ancestor`).

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**

Record:
- **`71ac392d8b5c2`** — this fix (in tree)
- **`0a00c3ec2db76`** — mvm analog, same day/author/series (14/15 vs
  15/15)
- **`1c031ac5a39eb`** — later “do not cleanup FW state when device is
  dead”; **different path** (chanctx unassign / NULL link), not a revert
  of this call
- **`c99bc4d4e0ba6`** — cancel wiphy work before free (same series,
  08/15); not a prerequisite for this hunk

Standalone: no other series patch is required for this one-line call.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**

Record: Emmanuel Grumbach is a long-time Intel iwlwifi developer. Same-
day pair: mvm cleanup + this MLD mirror. Maintainer Miri Korenblit SOB’d
both. Weight: **high**.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**

Record: Needs `iwl_mld_restart_cleanup`, `iwl_mld_device_powered_off`,
MLD op_mode — all present since MLD add. `mld.c` already `#include
"mac80211.h"`. **Applies standalone** on this tree.

---

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**

Record:
- `b4 dig -c 71ac392d8b5c2` → **https://patch.msgid.link/20260714165826.
  ff1c9e05e0a9.I8df8d4a0384065fd2a32cf258339be77084c55bd@changeid**
- **v2**, `[PATCH v2 iwlwifi-next 15/15]`; v2 cover: resend so next
  contains an unrelated compile fix (`too long hcmds`), **not** a
  redesign of this patch
- Cover: “Usual fixed, cleanups and features from our internal tree.”
  This commit listed under Emmanuel’s fixes.
- Saved mbox: **16 messages, all series posts, zero review replies /
  NAKs / Cc: stable**
- lore.kernel.org / patch.msgid.link HTTP fetch: **403** — discussion
  taken from `b4 dig -m` mbox instead

**Step 4.2: CHECK WHO REVIEWED THE PATCH**

Record (`b4 dig -w`): To/Cc **Johannes Berg**, **linux-
wireless@vger.kernel.org**, Miri Korenblit, Emmanuel Grumbach. No
Reviewed-by on 15/15 (several other series patches have Johannes R-b).
Applied via iwlwifi-next (`905b418df8af2`, 2026-07-23). Maintainer-tree
merge is the review signal.

**Step 4.3: SEARCH FOR THE BUG REPORT**

Record: **No user/syzbot/bugzilla report.** Bug is reasoned from the mvm
gap. Severity from code: stale FW IDs after D3cold/hibernate-style
power-off — WiFi may not come back cleanly.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**

Record: 15-patch iwlwifi-next dump. **14/15 is the mvm twin**
(independent). This patch does **not** depend on 01–13. Mix of features
and fixes; this hunk is a self-contained fix.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**

Record: Web search found **other** iwlwifi MLD restart patches in stable
(e.g. “stop TX during firmware restart” for 6.18/7.0). **No hit** for
this subject on stable@. UNVERIFIED: whether anyone already nominated
this exact commit for older -stable.

---

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1: IDENTIFY KEY FUNCTIONS**

Record: `iwl_mld_restart_cleanup` (export), `iwl_mld_device_powered_off`
(call site). Unchanged callees: `iwl_cleanup_mld`,
`iwl_mld_cleanup_vif`, `iwl_mld_cleanup_sta`,
`iwl_mld_ftm_restart_cleanup`.

**Step 5.2: TRACE CALLERS**

Record:
- `iwl_mld_restart_cleanup`: `iwl_mld_mac80211_start` (if
  `in_hw_restart`); **now** `iwl_mld_device_powered_off`
- `iwl_mld_device_powered_off`: op_mode `.device_powered_off` →
  `iwl_op_mode_device_powered_off` → **`_iwl_pci_resume`** in
  `pcie/drv.c` when restore or scratch says powered off
- Context: **PM resume**, process context, already holds `wiphy_lock`
- Reachable on Intel WiFi 7 / MLD laptops that D3cold the NIC or
  hibernate

**Step 5.3: TRACE CALLEES**

Record: stop_fw (trans stop, abort waits); cleanup zeros restart groups;
frees internal STAs/keys; may call
`ieee80211_remain_on_channel_expired`; FTM reports failure to cfg80211.
Side effects are the intended reset.

**Step 5.4: FOLLOW THE CALL CHAIN**

Record: **Userspace-reachable** via suspend/resume (and hibernate), not
a syscall bug. Trigger is common on laptops that cut WiFi power.
Unprivileged users typically cannot force PCI D3cold, but they **do**
suspend.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**

Record: **Exact mvm analog** `0a00c3ec2db76` — same author, same series.
Pattern is systematic (mvm had the cleanup; mld was missed at
introduction).

---

## PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**

Record:
- Local tree: **`git describe HEAD` = `v7.3-rc4-27-gf0100363d8c37`**,
  `make kernelversion` = **7.3.0-rc4**
- MLD files present under `drivers/net/wireless/intel/iwlwifi/mld/`
- **`git merge-base --is-ancestor 71ac392d8b5c2 HEAD` succeeds** — this
  fix is **already in this checkout**
- Pre-fix body (parent of 71ac392d8b5c2) had `device_powered_off`
  without cleanup; current `mld.c:750` has the call
- Bug introduced with MLD (`d1e879ec600f9`, ~6.14 development / 2025);
  **not** after 7.3 branched

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**

Record: **Clean apply** on this tree (already applied). Context around
`iwl_mld_device_powered_off` matches the candidate diff. No conflicting
refactor.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**

Record: This fix **is** here. mvm analog **is** here. No earlier
different MLD-powered-off cleanup. Follow-up `1c031ac5a39eb` is
unrelated chanctx/dead-device WARN, not a replacement.

---

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**

Record: **iwlwifi MLD** (`CONFIG_IWLMLD`) — Intel Wi-Fi 7 / MLO devices.
**IMPORTANT** (very common laptop NIC), not core mm/VFS. Affects all
IWLMLD users on PM sleep.

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**

Record: **Active** (regular iwlwifi-next pulls). Bug is an original
omission in a still-young op_mode (~1.5 years), not bitrot in abandoned
code.

---

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: DETERMINE WHO IS AFFECTED**

Record: **Driver-specific + config-specific:** `CONFIG_IWLWIFI` +
`CONFIG_IWLMLD` + `CONFIG_PM_SLEEP`. Intel BE200/BE201-class Wi-Fi 7.
Population is large for a driver fix.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**

Record:
- Trigger: resume after the transport decides the device was powered off
  (scratch bits, 0xFFFFFFFF, or failed NIC grab) — **hibernate, D3cold,
  some s2idle**
- Not every suspend (wowlan-alive path skips this)
- Not a userspace exploit path
- Timing: deterministic once the platform cuts power

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**

Record:
- **Failure:** driver/firmware state desync after resume; commands with
  stale IDs; possible internal-STA/key leak; FTM requests left hanging;
  Wi-Fi may not recover without reload
- Not shown as oops/UAF/CVE in the message (UNVERIFIED as crash)
- **Severity: HIGH** for affected hardware (broken Wi-Fi after suspend),
  **not CRITICAL** (no verified panic/corruption)

Stable-rules fit: **“oh, that’s not good”** / hardware resume quirk, not
theoretical.

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**

Record:
- **Benefit: high** for IWLMLD + PM — resume actually reconfigures like
  mvm
- **Risk: very low** — +1 call to existing helper, same lock as start
  path
- **Ratio: strongly favorable**

---

## PHASE 9: FINAL SYNTHESIS

**Step 9.1: COMPILE THE EVIDENCE**

**FOR backporting to this 7.3 tree:**
- Real resume bug: firmware stopped, MLD software state not reset
- Same fix already proven in mvm (`0a00c3ec2db76`)
- Tiny, obviously correct; helper already used on HW restart
- Intel Wi-Fi 7 is common; suspend/resume is a user-facing path
- MLD and the buggy function exist in this tree; no extra prereqs
- Maintainer-tree merge; Johannes on Cc
- Matches stable rule of a real bug that bothers people (Wi-Fi
  dead/wrong after power-off suspend)

**AGAINST:**
- No Reported-by / syzbot / stack trace
- Brief commit message
- 15/15 of a mixed “updates” series, not a dedicated stable submission
- No explicit crash/security
- Power-off-during-suspend is not every resume (wowlan-alive OK)

**UNRESOLVED:**
- Exact user-visible rate (no public bugzilla)
- lore HTTP 403; no on-list NAK found in mbox
- No stable@ discussion of this exact subject

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**

1. Obviously correct and tested? **PASS** — mirrors mvm; merged to
   iwlwifi-next/mainline; logic is a single missing call.
2. Fixes a real bug that affects users? **PASS** — stale MLD state vs
   empty firmware after D3cold/hibernate resume.
3. Important issue? **PASS** — user-visible Wi-Fi recovery failure
   (HIGH, not panic). Fits “oh, that’s not good” / resume hardware path.
4. Small and contained? **PASS** — ~4 insertions, one subsystem.
5. No new features or APIs? **PASS** — export existing helper + call it.
6. Can apply to the local tree? **PASS** — code present; patch already
   applies (already in v7.3-rc4).

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**

Record: **None** (not a device ID / quirk table / DT / build / docs).
Qualifies as a normal small bugfix.

**Step 9.4: MAKE YOUR DECISION**

This tree is **7.3.0-rc4**. The MLD `device_powered_off` path exists
here and omitted restart cleanup until `71ac392d8b5c2`. The commit is a
4-line, low-risk fix for a real suspend/resume correctness bug on Intel
MLD hardware. It should be in this tree’s stable stream.

### What the commit solves (for 7.3 users)

On PCI resume, if the NIC was powered off, MLD only stopped firmware and
cleared `in_d3`. `iwl_mld_mac80211_start` then did a cold
`iwl_mld_start_fw()` **without** `iwl_mld_restart_cleanup()`, so
firmware IDs, keys, scan, and internal STAs stayed live in software. Wi-
Fi 7 devices can fail to recover after that suspend. The fix is the same
cleanup mvm already does.

Risk is a single call under the lock already used for restart cleanup.
Benefit is working wireless after D3cold/hibernate on common Intel
hardware.

---

Verification:
- [Phase 1] `git show 71ac392d8b5c2`: subject/tags/body as above; SOB
  Grumbach + Korenblit; Link msgid; no Fixes/Reported-by/Cc stable
- [Phase 2] Diff: un-static `iwl_mld_restart_cleanup`, header prototype,
  +1 call in `iwl_mld_device_powered_off`; +4/−2
- [Phase 2] Parent of commit: `device_powered_off` was stop_fw +
  `in_d3=false` only
- [Phase 2] Current `mld.c:743-753`: call present under `wiphy_lock`
- [Phase 2] `iwl_cleanup_mld` / `iwl_mld_cleanup_vif` /
  `iwl_mld_cleanup_sta` / `iwl_mld_ftm_restart_cleanup` read in tree
- [Phase 3] `git log -L` on `iwl_mld_device_powered_off`: d1e879ec600f9
  → 7aeec8c8d63bf → 71ac392d8b5c2
- [Phase 3] `d1e879ec600f9` Makefile 6.14.0-rc4; ancestor of HEAD
- [Phase 3] `git show 0a00c3ec2db76`: mvm analog same day
- [Phase 3] `git log -S iwl_mld_restart_cleanup -- mld/`: only MLD add +
  this commit
- [Phase 3] `1c031ac5a39eb` is a different chanctx/dead-device WARN, not
  a revert
- [Phase 4] `b4 dig -c/-a/-w/-m`: v2 15/15 iwlwifi-next; recipients
  Johannes + linux-wireless; mbox 16 series mails, no NAK
- [Phase 4] WebFetch lore/msgid: 403; used mbox instead
- [Phase 4] WebSearch stable@: other MLD restart fixes, not this subject
- [Phase 5] `git grep iwl_op_mode_device_powered_off`: `pcie/drv.c:1281`
  from `_iwl_pci_resume` when powered off
- [Phase 5] `mld.c` includes `mac80211.h`
- [Phase 6] `git describe HEAD` = v7.3-rc4-27-gf0100363d8c37; `make
  kernelversion` 7.3.0-rc4
- [Phase 6] `git merge-base --is-ancestor 71ac392d8b5c2 HEAD`: yes
- [Phase 8] Failure mode inferred from code + mvm message (reload
  **and** reconfigure); no crash dump in commit (stated)
- UNVERIFIED: public user reports; whether older LTS without this commit
  would be in scope (out of band — this verdict is 7.3-rc4 only)

**YES**

 drivers/net/wireless/intel/iwlwifi/mld/mac80211.c | 3 +--
 drivers/net/wireless/intel/iwlwifi/mld/mac80211.h | 2 ++
 drivers/net/wireless/intel/iwlwifi/mld/mld.c      | 1 +
 3 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
index 27ae06e208402..69a066904a808 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
@@ -483,8 +483,7 @@ iwl_mld_mac80211_tx(struct ieee80211_hw *hw,
 	iwl_mld_tx_skb(mld, skb, NULL);
 }
 
-static void
-iwl_mld_restart_cleanup(struct iwl_mld *mld)
+void iwl_mld_restart_cleanup(struct iwl_mld *mld)
 {
 	iwl_cleanup_mld(mld);
 
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.h b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.h
index aad04d7b2617d..f3302997b28f2 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.h
+++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.h
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
 /*
  * Copyright (C) 2024 Intel Corporation
+ * Copyright (C) 2026 Intel Corporation
  */
 #ifndef __iwl_mld_mac80211_h__
 #define __iwl_mld_mac80211_h__
@@ -9,5 +10,6 @@
 
 int iwl_mld_register_hw(struct iwl_mld *mld);
 void iwl_mld_recalc_multicast_filter(struct iwl_mld *mld);
+void iwl_mld_restart_cleanup(struct iwl_mld *mld);
 
 #endif /* __iwl_mld_mac80211_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mld.c b/drivers/net/wireless/intel/iwlwifi/mld/mld.c
index 49e46babf8221..cf003a4a37408 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/mld.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/mld.c
@@ -739,6 +739,7 @@ static void iwl_mld_device_powered_off(struct iwl_op_mode *op_mode)
 
 	wiphy_lock(mld->wiphy);
 	iwl_mld_stop_fw(mld);
+	iwl_mld_restart_cleanup(mld);
 	mld->fw_status.in_d3 = false;
 	wiphy_unlock(mld->wiphy);
 }
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18] wifi: iwlwifi: mld: support aborting an ongoing ftm request
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (24 preceding siblings ...)
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: mld: reset the driver state upon firmware recovery Sasha Levin
@ 2026-10-19 13:51 ` Sasha Levin
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-5.10] wifi: mt76: mt76x02: report rx FCS errors to mac80211 Sasha Levin
                   ` (14 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:51 UTC (permalink / raw)
  To: patches, stable
  Cc: Avraham Stern, Miri Korenblit, Sasha Levin, linux-wireless,
	linux-kernel

From: Avraham Stern <avraham.stern@intel.com>

[ Upstream commit ef704fc32ae1a519801ac4a06aa290fece5f403c ]

Add support for aborting an ongoing FTM request.

Signed-off-by: Avraham Stern <avraham.stern@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260715220243.340040bdc6a3.Ifbbf70021e42bf1d59db6ec45a73f1806a1c2289@changeid
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## Phase 1: Commit message forensics

**Step 1.1: Subject line**
Record: **[iwlwifi/mld]** **[support]** add abort for an in-flight FTM
(Fine Timing Measurement / peer measurement) request.

**Step 1.2: Tags**
Record:
- Signed-off-by: Avraham Stern <avraham.stern@intel.com> (author)
- Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
  (iwlwifi maintainer)
- Link: https://patch.msgid.link/20260715220243.340040bdc6a3.Ifbbf70021e
  42bf1d59db6ec45a73f1806a1c2289@changeid
- No Fixes:, Reported-by:, Tested-by:, Reviewed-by:, Acked-by:, or Cc:
  stable (absence of the last two is expected for this review)

**Step 1.3: Body**
Record:
- Bug description from message: none. One sentence: “Add support for
  aborting an ongoing FTM request.”
- Symptom/failure mode: not stated
- Version information: none
- Root-cause explanation: none

**Step 1.4: Hidden bug fix?**
Record: **Yes.** The wording is feature-like, but the MLD path already
stores `mld->ftm_initiator.req` and later dereferences it. cfg80211
frees that object on abort whether or not the driver implements
`abort_pmsr`. Missing abort is a use-after-free / stuck-FTM hole, not a
new userspace API.

## Phase 2: Diff analysis

**Step 2.1: Inventory**
Record:
- `drivers/net/wireless/intel/iwlwifi/mld/ftm-initiator.c`: +21 (new
  `iwl_mld_ftm_abort`)
- `drivers/net/wireless/intel/iwlwifi/mld/ftm-initiator.h`: +1
  (prototype)
- `drivers/net/wireless/intel/iwlwifi/mld/mac80211.c`: +10
  (`iwl_mld_abort_pmsr` + `.abort_pmsr` ops)
- Total: **+32 / −0**, single-driver surgical change

**Step 2.2: Code flow**
Record:
- Before: `.start_pmsr` was wired; `.abort_pmsr` was NULL. On netlink
  close or wdev teardown, cfg80211 still `kfree()`s the request while
  the driver keeps the pointer and firmware keeps ranging.
- After: abort sends `TOF_RANGE_ABORT_CMD`, cancels queued FTM RX
  notifications, then `iwl_mld_ftm_reset()` NULLs `req`/`req_wdev`.
- Path: abort/teardown only, not the normal completion path.

**Step 2.3: Bug mechanism**
Record: **Use-after-free + leftover firmware ranging**, fixed by
implementing the existing mac80211 `abort_pmsr` op (same pattern as
MVM). Also prevents the next `iwl_mld_ftm_start()` from returning
`-EBUSY` forever because `ftm_initiator.req` stayed non-NULL after the
object was freed.

**Step 2.4: Fix quality**
Record: Obviously correct relative to `iwl_mvm_ftm_abort()`. Minimal.
Regression risk is low: new code runs only on abort; on firmware abort
failure it still resets local state (the UAF-critical part). Helpers it
calls already exist in this tree.

## Phase 3: Git history

**Step 3.1: Blame / introduction**
Record: Buggy pattern came in with **`d1e879ec600f9`** (“wifi: iwlwifi:
add iwlmld sub-driver”, 2025-02-16). FTM start stored `req` and
registered `RX_HANDLER_OF_FTM_REQ` / `IWL_MLD_OBJECT_TYPE_FTM_REQ` from
day one, but never called cancel/abort. MVM has had abort since
**`fc36ffda32670`** (2019, “support FTM initiator”).

**Step 3.2: Fixes: tag**
Record: None. Not applicable.

**Step 3.3: File history**
Record: Recent FTM-initiator commits are unrelated (location BW
encoding, switch indentation). Neighbor **`71ac392d8b5c2`** (FW recovery
reset) is a different path. No prerequisite refactor for this hunk.

**Step 3.4: Author**
Record: Avraham Stern is a regular iwlwifi FTM contributor. Maintainer
Miri Korenblit signed off. Related later Stern commits in this tree are
MEI length checks, not FTM abort follow-ups. **No follow-up fix** to
`iwl_mld_ftm_abort` after this commit.

**Step 3.5: Dependencies**
Record: Standalone. Uses existing `iwl_mld_send_cmd_pdu`,
`iwl_mld_cancel_notifications_of_object`, `IWL_MLD_OBJECT_TYPE_FTM_REQ`,
`iwl_mld_ftm_reset`, `TOF_RANGE_ABORT_CMD`. Series membership is **01/15
of an iwlwifi-next “updates” dump**; other patches (MEI, WoWLAN, LARI,
etc.) are unrelated. Can apply alone.

## Phase 4: Mailing list / external

**Step 4.1: Original discussion**
Record:
- `b4 dig -c ef704fc32ae1a`: https://patch.msgid.link/20260715220243.340
  040bdc6a3.Ifbbf70021e42bf1d59db6ec45a73f1806a1c2289@changeid
- Cover: `[PATCH iwlwifi-next 00/15] wifi: iwlwifi: updates -
  07-15-2026` — “Cleanups, features, and fixes from our internal tree.”
- `b4 dig -a`: **v1 only**, this is the applied version
- No reviewer comments, NAKs, or Cc: stable on this patch in the saved
  thread
- lore.kernel.org WebFetch returned 403; thread recovered via `b4 dig
  -m`

**Step 4.2: Recipients**
Record: To Johannes Berg; Cc linux-wireless, Avraham Stern. Subsystem
maintainer (Miri) submitted the series.

**Step 4.3: Bug report**
Record: None. No syzbot/bugzilla.

**Step 4.4: Series**
Record: Mixed iwlwifi-next batch. This patch does not depend on 02–15.

**Step 4.5: Stable list**
Record: No stable-list discussion found (search did not surface this
subject).

## Phase 5: Semantic / call-chain

**Step 5.1: Functions**
Record: `iwl_mld_ftm_abort` (new), `iwl_mld_abort_pmsr` (new),
`iwl_mld_hw_ops.abort_pmsr` assignment.

**Step 5.2: Callers**
Record:
- `cfg80211_release_pmsr()` from `nl80211.c` on netlink port release
- `cfg80211_pmsr_wdev_down()` from `net/wireless/core.c` on wdev
  teardown
- both → `cfg80211_pmsr_process_abort()` → `rdev_abort_pmsr()` →
  `ieee80211_abort_pmsr()` → `drv_abort_pmsr()` → `iwl_mld_abort_pmsr()`
- `drv_abort_pmsr` only calls the driver if `local->ops->abort_pmsr` is
  set; cfg80211 **always kfree()s** afterward (`pmsr.c` around the abort
  loop)

**Step 5.3: Callees**
Record: firmware abort PDU; `iwl_mld_cancel_notifications_of_object()`;
`iwl_mld_ftm_reset()`.

**Step 5.4: Reachability**
Record: Yes, from userspace: start peer measurement
(`NL80211_CMD_PEER_MEASUREMENT_START`), then close the netlink socket or
take the interface down while ranging is in progress. Typically
privileged (`nl80211`), but a crashing location/RTT helper is a
realistic trigger (Android Wi-Fi RTT uses this API).

**Step 5.5: Similar patterns**
Record: Only iwlwifi MVM/MLD and mac80211_hwsim implement `.abort_pmsr`.
MVM has had it since FTM was added; MLD start without abort was the
incomplete copy.

Verified UAF path in this tree:

```246:247:drivers/net/wireless/intel/iwlwifi/mld/ftm-initiator.c
        if (mld->ftm_initiator.req)
                return -EBUSY;
```

```267:270:drivers/net/wireless/intel/iwlwifi/mld/ftm-initiator.c
        if (!ret) {
                mld->ftm_initiator.req = req;
                mld->ftm_initiator.req_wdev =
ieee80211_vif_to_wdev(vif);
        }
```

```340:342:drivers/net/wireless/intel/iwlwifi/mld/ftm-initiator.c
        if (IWL_FW_CHECK(mld, !mld->ftm_initiator.req,
                         "FTM response without a pending request\n"))
                return;
```

That NULL check does not save a dangling pointer.
`cfg80211_pmsr_process_abort()` kfree’s the request after the (optional)
abort op.

## Phase 6: This checkout

**Step 6.1: Local tree and buggy code**
Record:
- `git describe HEAD`: **v7.3-rc4-27-gf0100363d8c37**
- `make kernelversion`: **7.3.0-rc4**
- MLD FTM initiator **is present**. Bug introduced with MLD
  (`d1e879ec600f9`), long before 7.3 branched.
- Candidate SHA **`ef704fc32ae1a`**; `git merge-base --is-ancestor
  ef704fc32ae1a HEAD` → already in this mainline snapshot (landed in
  **7.3-rc1**, not in 7.2). Evaluation is still on technical merit, not
  “already selected.”

**Step 6.2: Backport difficulty**
Record: Clean apply on this tree. Structures and helpers match the hunk.

**Step 6.3: Related fixes already here**
Record: `iwl_mld_ftm_restart_cleanup()` covers FW restart only, not
userspace abort. No earlier abort implementation.

## Phase 7: Subsystem context

**Step 7.1**
Record: **iwlwifi MLD** (Intel Wi-Fi 7 opmode). Criticality:
**IMPORTANT** (common client Wi-Fi driver), not core mm/VFS. FTM itself
is a subset of users (RTT / indoor location).

**Step 7.2**
Record: Actively developed; MLD is the current Intel path. This is a
missing piece from the original MLD port, not a brand-new subsystem.

## Phase 8: Impact and risk

**Step 8.1: Who is affected**
Record: Intel MLD devices using nl80211 peer measurement (FTM
initiator). Not universal.

**Step 8.2: Trigger**
Record: Start FTM, then abort via socket close or iface down before
firmware completes. Not every boot; realistic for location stacks and
interface teardown. Unprivileged trigger: unverified (nl80211 PMSR is
typically admin-capable).

**Step 8.3: Failure mode**
Record:
- Firmware response after abort: **UAF** of `cfg80211_pmsr_request`
  (crash / KASAN / potential memory corruption)
- Without a later notification: FTM stays “busy” (`-EBUSY`) until driver
  reset
- Firmware keeps ranging until timeout
Severity: **HIGH** (UAF), not a panic on every probe.

**Step 8.4: Risk/benefit**
Record: Benefit medium-high for MLD FTM users (UAF + stuck session).
Risk **low** (32 lines, abort path only, same design as MVM). Ratio
favors taking it.

## Phase 9: Synthesis

**Step 9.1: Evidence**

FOR:
- Verified UAF: driver borrows cfg80211’s request; abort path frees it
  without clearing the driver pointer
- Also stuck `-EBUSY` on later FTM starts
- Small, self-contained, copies a long-standing MVM abort
- Cancel infrastructure (`IWL_MLD_OBJECT_TYPE_FTM_REQ`) was already
  registered; abort was the missing caller
- Maintainer-signed; applies cleanly here
- Same class of “missing stop/abort op” that stable routinely takes

AGAINST:
- Message sells it as “add support,” no crash report, no Fixes/syzbot
- Sent to **iwlwifi-next** in a mixed updates series
- FTM is not a hot path for most desktops
- Adds a new ops pointer (looks like a feature if you only read the
  subject)

UNRESOLVED:
- Could not fetch lore HTML (403); used `b4` mbox instead
- No evidence of a real-world crash report
- Unverified whether unprivileged users can start PMSR on typical
  distros

**Step 9.2: Stable rules**
1. Obviously correct and tested? **PASS** (MVM analogue; Intel-authored)
2. Real user-visible bug? **PASS** (UAF / stuck FTM after abort)
3. Important (crash/security/corruption)? **PASS** (UAF is crash/memory-
   safety; FTM-specific but real)
4. Small and contained? **PASS** (32 lines, one driver)
5. No new features/APIs? **PASS** — implements an existing mac80211 op;
   not a new syscall/uAPI
6. Can apply to this tree? **PASS** (MLD FTM code is here; helpers
   exist)

**Step 9.3: Exception category**
Record: Not ID/quirk/DT/build/docs. Ordinary driver correctness fix.

**Step 9.4: Decision**
This is a missing abort handler on a driver that caches a cfg80211-owned
object. That is a UAF fix, even though the subject says “support.” It is
small, applies here, and does not need the rest of the 15-patch series.

### What it solves for this tree
On 7.3-rc4, iwlwifi MLD FTM start stores `req` and handles firmware
range responses. Without abort, closing the measurement netlink socket
or taking the wdev down frees `req` while the driver and firmware still
use it. That is a use-after-free and can pin FTM at `-EBUSY`. The patch
aborts firmware, drops queued FTM notifs, and clears driver state.

### Risk vs benefit
Low risk, high severity if the abort path is hit. Benefit is limited to
Intel MLD + FTM users, which is enough given UAF.

Verification:
- [Phase 1] Parsed tags: SOB Stern + Korenblit; Link msgid; no
  Fixes/Reported-by/Cc stable
- [Phase 2] Diff: +32 lines, `iwl_mld_ftm_abort` + `.abort_pmsr`
- [Phase 3] `git show ef704fc32ae1a`; ancestor of HEAD; introduced with
  `d1e879ec600f9`; MVM abort `fc36ffda32670`
- [Phase 3] `git merge-base --is-ancestor ef704fc32ae1a 8d3ae59288f1e` →
  not in 7.2; in 7.3-rc1
- [Phase 3] No follow-ups on `ftm-initiator.c` after this commit
- [Phase 4] `b4 dig -c/-a/-w/-m`: v1 iwlwifi-next 01/15, To Johannes, no
  review replies in mbox
- [Phase 4] WebFetch lore/msgid.link → 403; used local mbox
- [Phase 5] Call chain: `cfg80211_release_pmsr` /
  `cfg80211_pmsr_wdev_down` → kfree after optional abort;
  `iwl_mld_handle_ftm_resp_notif` derefs `ftm_initiator.req`
- [Phase 6] `git describe HEAD` = v7.3-rc4-27-gf0100363d8c37;
  kernelversion 7.3.0-rc4; MLD FTM present
- [Phase 8] Failure mode: UAF on FTM abort + `-EBUSY` stuck state,
  severity HIGH
- UNVERIFIED: unprivileged PMSR start; no user crash report

**YES**

 .../intel/iwlwifi/mld/ftm-initiator.c         | 21 +++++++++++++++++++
 .../intel/iwlwifi/mld/ftm-initiator.h         |  1 +
 .../net/wireless/intel/iwlwifi/mld/mac80211.c | 10 +++++++++
 3 files changed, 32 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/ftm-initiator.c b/drivers/net/wireless/intel/iwlwifi/mld/ftm-initiator.c
index 3464b32687124..6e174c4d8b75e 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/ftm-initiator.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/ftm-initiator.c
@@ -449,3 +449,24 @@ void iwl_mld_ftm_restart_cleanup(struct iwl_mld *mld)
 			       mld->ftm_initiator.req, GFP_KERNEL);
 	iwl_mld_ftm_reset(mld);
 }
+
+void iwl_mld_ftm_abort(struct iwl_mld *mld, struct cfg80211_pmsr_request *req)
+{
+	struct iwl_tof_range_abort_cmd cmd = {
+		.request_id = req->cookie,
+	};
+
+	lockdep_assert_wiphy(mld->wiphy);
+
+	if (req != mld->ftm_initiator.req)
+		return;
+
+	if (iwl_mld_send_cmd_pdu(mld, WIDE_ID(LOCATION_GROUP,
+					      TOF_RANGE_ABORT_CMD),
+				 &cmd))
+		IWL_ERR(mld, "failed to abort FTM process\n");
+
+	iwl_mld_cancel_notifications_of_object(mld, IWL_MLD_OBJECT_TYPE_FTM_REQ,
+					       mld->ftm_initiator.req->cookie);
+	iwl_mld_ftm_reset(mld);
+}
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/ftm-initiator.h b/drivers/net/wireless/intel/iwlwifi/mld/ftm-initiator.h
index 3fab25a52508a..e82237b314673 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/ftm-initiator.h
+++ b/drivers/net/wireless/intel/iwlwifi/mld/ftm-initiator.h
@@ -25,5 +25,6 @@ int iwl_mld_ftm_start(struct iwl_mld *mld, struct ieee80211_vif *vif,
 void iwl_mld_handle_ftm_resp_notif(struct iwl_mld *mld,
 				   struct iwl_rx_packet *pkt);
 void iwl_mld_ftm_restart_cleanup(struct iwl_mld *mld);
+void iwl_mld_ftm_abort(struct iwl_mld *mld, struct cfg80211_pmsr_request *req);
 
 #endif /* __iwl_mld_ftm_initiator_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
index 69a066904a808..5234229a070a7 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
@@ -2609,6 +2609,15 @@ static int iwl_mld_start_pmsr(struct ieee80211_hw *hw,
 	return iwl_mld_ftm_start(mld, vif, request);
 }
 
+static void iwl_mld_abort_pmsr(struct ieee80211_hw *hw,
+			       struct ieee80211_vif *vif,
+			       struct cfg80211_pmsr_request *request)
+{
+	struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw);
+
+	iwl_mld_ftm_abort(mld, request);
+}
+
 static enum ieee80211_neg_ttlm_res
 iwl_mld_can_neg_ttlm(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		     struct ieee80211_neg_ttlm *neg_ttlm)
@@ -2696,5 +2705,6 @@ const struct ieee80211_ops iwl_mld_hw_ops = {
 	.prep_add_interface = iwl_mld_prep_add_interface,
 	.set_hw_timestamp = iwl_mld_set_hw_timestamp,
 	.start_pmsr = iwl_mld_start_pmsr,
+	.abort_pmsr = iwl_mld_abort_pmsr,
 	.can_neg_ttlm = iwl_mld_can_neg_ttlm,
 };
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] wifi: mt76: mt76x02: report rx FCS errors to mac80211
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (25 preceding siblings ...)
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: mld: support aborting an ongoing ftm request Sasha Levin
@ 2026-10-19 13:51 ` Sasha Levin
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-6.12] wifi: ath11k: fix resource leak on error in ext IRQ setup Sasha Levin
                   ` (13 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:51 UTC (permalink / raw)
  To: patches, stable
  Cc: Devin Wittmayer, 0072a70, Felix Fietkau, Sasha Levin, lorenzo,
	ryder.lee, matthias.bgg, angelogioacchino.delregno,
	linux-wireless, linux-kernel, linux-arm-kernel, linux-mediatek

From: Devin Wittmayer <lucid_duck@justthetip.ca>

[ Upstream commit ddae0bcb01e71c1184bb3f526f9622e31dc38f3b ]

When the fcsfail filter is enabled the hardware passes frames with a bad
FCS up to the driver, but mt76x02_mac_process_rx() never checks
MT_RXINFO_CRCERR and hands them to mac80211 without
RX_FLAG_FAILED_FCS_CRC. In monitor mode the radiotap flags byte then
never gets IEEE80211_RADIOTAP_F_BADFCS set and corrupted frames cannot be
told apart from clean ones.

Set RX_FLAG_FAILED_FCS_CRC from the descriptor CRC error bit, matching
mt7603, mt7615, mt7915, mt7921, mt7925 and mt7996.

Reported-by: 0072a70 <90307219+0072a70@users.noreply.github.com>
Closes: https://github.com/morrownr/mt76/issues/38
Tested-by: 0072a70 <90307219+0072a70@users.noreply.github.com>
Signed-off-by: Devin Wittmayer <lucid_duck@justthetip.ca>
Link: https://patch.msgid.link/20260613002544.27750-3-lucid_duck@justthetip.ca
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## Phase 1: Commit message forensics

**Step 1.1 — Subject**
- Record: `[wifi: mt76: mt76x02]` `[report]` `[report rx FCS errors to
  mac80211]`
- Subsystem is MediaTek mt76, mt76x02 family (mt76x0 / mt76x2 PCI and
  USB). “Report” here is a correctness fix: the driver already receives
  CRC-failed frames and must mark them.

**Step 1.2 — Tags**
- Record:
  - `Reported-by: 0072a70 <90307219+0072a70@users.noreply.github.com>` —
    real user hit
  - `Closes: https://github.com/morrownr/mt76/issues/38`
  - `Tested-by:` same reporter, on real hardware
  - `Signed-off-by: Devin Wittmayer` (author)
  - `Link: https://patch.msgid.link/20260613002544.27750-3-
    lucid_duck@justthetip.ca`
  - `Signed-off-by: Felix Fietkau` (mt76 maintainer)
  - No `Fixes:` tag (expected for this review)
  - No `Cc: stable` (expected; not a negative)
  - Ignore any pipeline `Signed-off-by: Sasha Levin` / `[Upstream commit
    ...]`

**Step 1.3 — Body**
- Record:
  - **Bug:** With the `fcsfail` filter enabled, hardware delivers frames
    with `MT_RXINFO_CRCERR` set. `mt76x02_mac_process_rx()` never reads
    that bit, so mac80211 never gets `RX_FLAG_FAILED_FCS_CRC`.
  - **Symptom:** In monitor mode, radiotap never sets
    `IEEE80211_RADIOTAP_F_BADFCS`; corrupted frames look identical to
    clean ones.
  - **Root cause:** Missing descriptor-bit → `rx_status` translation.
    Other mt76 chips already do this.
  - **Version info in the message:** none. Reporter used kernel 7.0.x;
    the code path is much older (see Phase 3).

**Step 1.4 — Hidden bug fix?**
- Record: Not disguised. It is an explicit missing-flag fix that
  implements the documented mac80211 contract for `FIF_FCSFAIL`.

## Phase 2: Diff analysis

**Step 2.1 — Inventory**
- Record: one file, `drivers/net/wireless/mediatek/mt76/mt76x02_mac.c`.
  Three lines added, none removed. Function: `mt76x02_mac_process_rx()`.
  Surgical single-file change.

**Step 2.2 — Flow**
- Record: After the existing `MT_RXINFO_L2PAD` check, if `rxinfo &
  MT_RXINFO_CRCERR`, set `status->flag |= RX_FLAG_FAILED_FCS_CRC`.
  Normal RX is unchanged for clean frames. Error/monitor path for CRC-
  failed frames is now marked.

**Step 2.3 — Bug mechanism**
- Record: **Logic / correctness** (driver contract). Hardware already
  passes CRC-failed frames when `FIF_FCSFAIL` is on
  (`MT76_FILTER(FCSFAIL, MT_RX_FILTR_CFG_CRC_ERR)` in
  `mt76x02_configure_filter()`). The driver failed to set the flag
  mac80211 requires (`include/net/mac80211.h`: *“pass frames with failed
  FCS (but you need to set RX_FLAG_FAILED_FCS_CRC for them)”*).

Verified mac80211 consequences in this tree:
- `ieee80211_add_rx_radiotap_header()` sets
  `IEEE80211_RADIOTAP_F_BADFCS` only if that flag is present
  (`net/mac80211/rx.c`).
- `should_drop_frame()` treats `RX_FLAG_FAILED_FCS_CRC` as drop-from-
  cooked-path. Without it, `ieee80211_rx_monitor()` copies the frame to
  monitor and **returns the original skb** to
  `__ieee80211_rx_handle_packet()`. FCS-failed frames can therefore
  enter the cooked RX path whenever `fcsfail` is enabled (including
  concurrent monitor + STA/AP).

**Step 2.4 — Fix quality**
- Record: Obviously correct; same pattern as
  `mt7603`/`mt7615`/`mt7915`/`mt7921`/`mt7996` in this tree. Minimal.
  Regression risk is low: only CRCERR frames get a flag they should
  already have. Clean frames are untouched. Does not add APIs or change
  locking.

## Phase 3: Git history

**Step 3.1 — Blame**
- Record: Insertion point is the 2018 `mt76x02_mac_process_rx()` body
  from `d9f8934ed147b3` (“mt76: move mt76x02_mac_process_rx in
  mt76x02-lib module”), 2018-10-04, first contained in **v4.20-rc1**.
  `MT_RXINFO_CRCERR` is defined in `mt76x02_mac.h:54` since
  `5327b5ea13910d` (2018-09-04). The bit has been defined for years and
  never consumed in RX processing.

**Step 3.2 — Fixes: tag**
- Record: None. The omission dates to the original mt76x02 RX path, not
  a later regression.

**Step 3.3 — File history**
- Record: Same-function sibling from the same series is already in this
  tree: `b6e7958602bd1` (“do not WARN on invalid rx descriptor length”).
  That is patch 1/2 of `[PATCH 0/2] wifi: mt76: mt76x02: rx fixes for
  fcsfail monitor mode`. This candidate is patch 2/2. They touch
  different lines; this one does not depend on patch 1. `git apply
  --check` of this hunk on HEAD is **clean**. No other FCS reporting
  commit exists on this file.

**Step 3.4 — Author**
- Record: Devin Wittmayer; not the subsystem maintainer. Maintainer
  Felix Fietkau signed off. Author also submitted the sibling WARN fix.
  Related author commits in this tree: `b6e7958602bd1`, plus unrelated
  mt7615/mt7921 TXRX_NOTIFY drops.

**Step 3.5 — Prerequisites**
- Record: None beyond symbols already in 6.6: `MT_RXINFO_CRCERR`,
  `RX_FLAG_FAILED_FCS_CRC`, `status->flag`. Commit text mentions mt7925;
  that chip need not exist here — it is comparison only. Standalone
  apply: yes.

## Phase 4: Mailing list / external research

**Step 4.1 — Original discussion**
- Record: `b4 dig -c <sha>` cannot match because this commit is not in
  the local history. Fallback: `b4 mbox
  20260613002544.27750-3-lucid_duck@justthetip.ca`.
  - Cover: https://patch.msgid.link/20260613002544.27750-1-
    lucid_duck@justthetip.ca
  - Series: v1 only (`b4 am --check-newer-revisions`: no later
    revision).
  - Two patches; this is 2/2.
  - Cover: tested on MT7612U and MT7610U; fcsfail monitor captures get
    BADFCS on corrupted frames, clean frames unchanged.
  - No NAKs in the retrieved thread (cover + 2 patches, no review
    replies). Applied by Felix Fietkau.
  - Lore HTTP fetch returned 403; b4 was used instead.

**Step 4.2 — Recipients**
- Record: To Felix Fietkau, Lorenzo Bianconi; Cc Ryder Lee, Shayne Chen,
  Sean Wang, linux-wireless, linux-kernel. Right maintainers/lists.

**Step 4.3 — Bug report**
- Record: GitHub issue #38 (closed). Hardware: Alfa AWUS036ACM, mt7612u,
  driver mt76x2u. With `iw set monitor fcsfail`, radiotap flags were
  always `0x00`; `radiotap.flags.badfcs == 1` matched 0 of 2978 frames.
  After this exact three-line change: 956/7353 frames had BADFCS `0x40`,
  clean frames stayed `0x00`. Confirmed on-list/issue by the reporter
  (`Tested-by`).

**Step 4.4 — Series context**
- Record: Patch 1 (WARN on bogus MPDU length under fcsfail) is already
  in this 6.6 tree. Patch 2 is the functional reporting fix.
  Independent; both target the same user-visible fcsfail path.

**Step 4.5 — stable@ discussion**
- Record: lore.kernel.org/stable HTTP 403. No separate stable-thread
  evidence retrieved. Absence is not a negative for this review.

## Phase 5: Semantic / call-chain analysis

**Step 5.1 — Functions**
- Record: `mt76x02_mac_process_rx()`.

**Step 5.2 — Callers**
- Record: Only `mt76x02_queue_rx_skb()` in `mt76x02_txrx.c` (data RX,
  not MCU queue). That is the USB/PCI RX completion path for mt76x0 and
  mt76x2.

**Step 5.3 — Callees (relevant)**
- Record: Sets `struct mt76_rx_status` in `skb->cb`, then `mt76_rx()` →
  mac80211. `mt76_rx()` already counts `RX_FLAG_FAILED_FCS_CRC` for
  testmode FCS stats (`mac80211.c`).

**Step 5.4 — Reachability**
- Record: Userspace-reachable: `iw set type monitor` + `iw set monitor
  fcsfail` (nl80211 `NL80211_MNTR_FLAG_FCSFAIL` →
  `ieee80211_adjust_monitor_flags()` → `fif_fcsfail` → `FIF_FCSFAIL` →
  hardware CRC filter cleared). Common on USB adapters used for capture
  (Alfa AWUS036ACM and similar).

**Step 5.5 — Similar patterns**
- Record: Same `status->flag |= RX_FLAG_FAILED_FCS_CRC` already present
  in this tree for mt7603, mt7615, mt7915, mt7921, mt7996. mt76x02 is
  the gap. `MT_RXINFO_ICVERR` / `MT_RXINFO_MICERR` are also unused here;
  out of scope for this patch.

## Phase 6: This tree (6.6.157 / pending-6.6)

**Step 6.1 — Does the buggy code exist?**
- Record: Yes. `mt76x02_mac_process_rx()` at `mt76x02_mac.c:794–797` has
  L2PAD then DECRYPT; no CRCERR check. `MT_RXINFO_CRCERR` is defined.
  `git merge-base --is-ancestor d9f8934ed147b3 HEAD` succeeded. Bug
  present since ~v4.20, so it is in 6.6.y.

Local tree identity:
- `git describe HEAD` → `p-6.6-3-g04810563abb71`
- `make kernelversion` → **6.6.157**
- Branch: `pending-6.6`

**Step 6.2 — Backport difficulty**
- Record: **Clean apply.** Context matches; `git apply --check`
  succeeded. Surrounding code is the same as the patch’s index.

**Step 6.3 — Related fixes already here**
- Record: No existing CRCERR → `RX_FLAG_FAILED_FCS_CRC` translation.
  Sibling WARN fix `b6e7958602bd1` is present (different hunk).
  `63fe66f102837` (mt7996 FCS bit in wrong RXD word) is a different
  chip.

## Phase 7: Subsystem context

**Step 7.1**
- Record: `drivers/net/wireless/mediatek/mt76` — **IMPORTANT** (widely
  used WiFi, not core mm/vfs). Covers MT76x0U/E and MT76x2U/E (`Kconfig`
  MT7610/MT7612 USB and PCIe). Peripheral relative to core kernel, but
  these USB NICs are common in the field.

**Step 7.2**
- Record: mt76 is active; mt76x02 RX processing itself has been stable
  for years. This is a long-standing omission, not churn from a new
  subsystem.

## Phase 8: Impact and risk

**Step 8.1 — Who is affected**
- Record: Users of mt76x0/mt76x2 (USB and PCIe) who enable monitor
  `fcsfail`. Normal STA/AP-only operation keeps the hardware CRC filter
  on, so those users are not on this path. Mixed monitor+managed on the
  same phy is affected for cooked RX.

**Step 8.2 — Trigger**
- Record: Explicit monitor `fcsfail` (and typically a busy channel). Not
  every boot. Unprivileged users cannot enable monitor without
  privileges, so this is not a generic local-priv-esc path; it is a
  privileged capture/correctness bug.

**Step 8.3 — Failure mode**
- Record:
  - Monitor: corrupted frames indistinguishable from good ones (broken
    advertised filter). **MEDIUM** for dedicated capture.
  - Cooked path: FCS-failed frames can be processed as valid 802.11 when
    `fcsfail` is on. That is frame-integrity / stack-correctness, not a
    panic. **MEDIUM–HIGH** in mixed-iface setups; not a guaranteed oops.
  - Overall severity: **MEDIUM**, with a real user-visible functional
    break and a documented driver-API violation.

**Step 8.4 — Risk vs benefit**
- Record: **Benefit: medium** (correct FCS reporting; stop garbage
  frames leaking into cooked RX). **Risk: very low** (3 lines, same
  pattern as sibling chips, no lock/API change). Ratio favors backport.

## Phase 9: Synthesis

**Step 9.1 — Evidence**

For:
- Real, reproduced bug (GitHub #38; Tested-by on MT7612U; author also
  tested MT7610U).
- Violates mac80211 `FIF_FCSFAIL` contract; radiotap BADFCS never set.
- FCS-failed frames can continue into `__ieee80211_rx_handle_packet()`
  without the flag.
- Three-line, obviously correct, matches every other mt76 MAC in this
  tree.
- Applies cleanly to 6.6.157; symbols and call path exist.
- Maintainer SOB (Felix Fietkau).
- Popular USB hardware (e.g. Alfa AWUS036ACM).

Against:
- Not a crash/UAF/deadlock; mainly monitor-mode correctness plus cooked-
  path leakage only when `fcsfail` is enabled.
- No `Fixes:` (omission from original driver, not a later regression).
- Affects a subset of mt76x02 users, not all machines.

Unresolved:
- Direct lore.kernel.org HTTP was 403; discussion recovered via b4.
- No independent stable@ thread found.

**Step 9.2 — Stable rules**
1. Obviously correct and tested? **PASS** — 3 lines, hardware-tested,
   maintainer-acked.
2. Real bug affecting users? **PASS** — reporter could not tell bad-FCS
   frames apart; contract violation is in-tree.
3. Important issue? **PASS** (medium) — broken advertised monitor filter
   plus cooked-path delivery of CRC-failed frames. Not a panic, but it
   is a real correctness/integrity bug, not a feature.
4. Small and contained? **PASS** — +3 lines, one function.
5. No new features/APIs? **PASS** — sets an existing `rx_status` flag
   other mt76 chips already set.
6. Can apply to this tree? **PASS** — clean apply on 6.6.157.

**Step 9.3 — Exception category**
- Record: Not a device-ID/quirk/DT/build/docs exception. Ordinary small
  driver correctness fix.

**Step 9.4 — Decision**
This tree is **6.6.157**. The buggy RX path, `MT_RXINFO_CRCERR`, and
mac80211 flag handling are all present. The patch is a tiny, tested,
maintainer-accepted fix for a user-visible bug on hardware this driver
supports. Benefit clearly outweighs risk.

---

### What the commit solves for 6.6 users

mt76x02 already programs the hardware to deliver CRC-failed frames when
monitor `fcsfail` is set, but never tells mac80211. Users of
MT7610/MT7612 USB and PCIe adapters then see every frame as clean in
radiotap, and those frames can also continue into the normal RX
handlers. The fix sets `RX_FLAG_FAILED_FCS_CRC` from `MT_RXINFO_CRCERR`,
which is what this tree already does for later mt76 chips.

### Stable-rule fit

Small, obviously correct, no new API, applies cleanly, real user-visible
bug. Importance is monitor/FCS integrity rather than a panic; that is
still within what stable takes for driver contract bugs of this size.

### Risk vs benefit

Very low risk (three lines, clean frames unchanged). Medium benefit for
mt76x02 monitor users and mixed-iface setups.

### Concerns

No functional dependencies. Series mate (WARN drop) is already in this
tree but is not required for this hunk. mt7925 in the commit message is
comparison only.

---

Verification:
- [Phase 1] Parsed tags: Reported-by/Tested-by 0072a70, Closes
  github.com/morrownr/mt76/issues/38, Link msgid `...27750-3...`, SOB
  Felix Fietkau; no Fixes/Cc:stable
- [Phase 2] Diff: +3 lines in `mt76x02_mac_process_rx()` after L2PAD;
  sets `RX_FLAG_FAILED_FCS_CRC` from `MT_RXINFO_CRCERR`
- [Phase 2] Confirmed `mt76x02_configure_filter()` maps `FIF_FCSFAIL` →
  clear `MT_RX_FILTR_CFG_CRC_ERR`
- [Phase 2] Confirmed mac80211 `should_drop_frame()` / radiotap BADFCS /
  `ieee80211_rx_monitor()` cooked-path return behavior in this tree
- [Phase 3] `git blame`: insertion region from `d9f8934ed147b3` (2018);
  `git merge-base --is-ancestor` true; `git describe --contains` →
  v4.20-rc1
- [Phase 3] `MT_RXINFO_CRCERR` defined at `mt76x02_mac.h:54`; `git grep`
  shows it is unused in `.c` files in this tree
- [Phase 3] Sibling `b6e7958602bd1` already in HEAD; this hunk
  independent; `git apply --check` CLEAN
- [Phase 4] `b4 mbox` saved 3-message series; cover tested
  MT7612U/MT7610U; `b4 am --check-newer-revisions` = v1 only, no NAKs
- [Phase 4] WebFetch of GitHub issue #38: reproduced 0 BADFCS; after
  patch 956/7353 frames flagged
- [Phase 4] lore.kernel.org WebFetch: 403 — UNVERIFIED via HTTP;
  recovered via b4
- [Phase 5] Only caller: `mt76x02_queue_rx_skb()`; chips: MT76x0U/E,
  MT76x2U/E
- [Phase 5] Same flag already set in mt7603/mt7615/mt7915/mt7921/mt7996
  in this checkout
- [Phase 6] `git describe HEAD` p-6.6-3-g04810563abb71; `make
  kernelversion` 6.6.157; buggy code present; fix not applied
- [Phase 8] Failure mode: wrong radiotap + possible cooked-path delivery
  of CRC-failed frames; not a panic
- UNVERIFIED: stable@ mailing-list thread content (HTTP 403)

**YES**

 drivers/net/wireless/mediatek/mt76/mt76x02_mac.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index 06f17da2c0106..17c9782915315 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -792,6 +792,9 @@ int mt76x02_mac_process_rx(struct mt76x02_dev *dev, struct sk_buff *skb,
 	if (rxinfo & MT_RXINFO_L2PAD)
 		pad_len += 2;
 
+	if (rxinfo & MT_RXINFO_CRCERR)
+		status->flag |= RX_FLAG_FAILED_FCS_CRC;
+
 	if (rxinfo & MT_RXINFO_DECRYPT) {
 		status->flag |= RX_FLAG_DECRYPTED;
 		status->flag |= RX_FLAG_MMIC_STRIPPED;
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18-6.12] wifi: ath11k: fix resource leak on error in ext IRQ setup
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (26 preceding siblings ...)
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-5.10] wifi: mt76: mt76x02: report rx FCS errors to mac80211 Sasha Levin
@ 2026-10-19 13:51 ` Sasha Levin
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: validate UEFI reduced-power SKU TLV length Sasha Levin
                   ` (12 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:51 UTC (permalink / raw)
  To: patches, stable
  Cc: ZhaoJinming, Rameshkumar Sundaram, Baochen Qiang, Jeff Johnson,
	Sasha Levin, jjohnson, linux-wireless, ath11k, linux-kernel

From: ZhaoJinming <zhaojinming@uniontech.com>

[ Upstream commit 8ab38bbac02298e3fb03008ed4a0227485c0fd62 ]

In ath11k_ahb_config_irq(), when a CE request_irq() fails, the function
returns the error immediately without freeing the CE IRQs that were
successfully registered in previous loop iterations. The probe error
path does not call ath11k_ahb_free_irq() either, so the previously
registered CE IRQ handlers remain attached to the interrupt lines and
are never released.

In ath11k_ahb_config_ext_irq(), when an external request_irq() fails,
the error is only logged and the loop continues. The function then
returns 0 indicating success, leaving the device in a partially
configured state where some external IRQs are not registered. This
causes enable_irq()/disable_irq()/free_irq() to be called on
unregistered IRQs during runtime and remove/shutdown, triggering
WARN_ON(!desc->action), and missing interrupt handlers lead to data
loss.

Additionally, if alloc_netdev_dummy() fails for a later IRQ group, the
function returns -ENOMEM without freeing the ext IRQs and napi_ndev
that were successfully set up for earlier groups.

Fix all three issues: propagate the error up to the caller and unwind
all successfully registered IRQs and allocated resources on failure.
Also move ab->irq_num[irq_idx] assignment after request_irq() succeeds
in the ext IRQ path to match the CE IRQ path and avoid storing a stale
IRQ number on failure.

Signed-off-by: ZhaoJinming <zhaojinming@uniontech.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20260729020005.219253-1-zhaojinming@uniontech.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

# Stable backport analysis: `8ab38bbac022` (“wifi: ath11k: fix resource
leak on error in ext IRQ setup”)

Local tree: **Linux 6.1.188** (`p-6.1-11-gffee1c0de6cf2`). The candidate
is **not** an ancestor of HEAD. Verdict is for this 6.1.y tree only.

---

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1 — Subject**
- Record: **[wifi: ath11k]** **[fix]** resource leak on error in AHB ext
  IRQ setup.

**Step 1.2 — Tags**
- Record:
  - `Reviewed-by: Rameshkumar Sundaram
    <rameshkumar.sundaram@oss.qualcomm.com>` (Qualcomm ath11k reviewer)
  - `Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>`
    (Qualcomm ath11k reviewer)
  - `Link: https://patch.msgid.link/20260729020005.219253-1-
    zhaojinming@uniontech.com`
  - `Signed-off-by: ZhaoJinming <zhaojinming@uniontech.com>` (author)
  - `Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>`
    (ath11k maintainer, applied)
  - No `Fixes:`, `Reported-by:`, `Tested-by:`, `Cc: stable` (absence is
    expected for this pipeline)
  - No syzbot / sanitizer tags

**Step 1.3 — Body**
The commit describes three bugs in `ath11k_ahb_config_irq()` /
`ath11k_ahb_config_ext_irq()`:

1. **CE `request_irq()` fail:** returns immediately; previously
   registered CE IRQs are not freed. Probe `err_ce_free` does **not**
   call `ath11k_ahb_free_irq()`, so those handlers stay attached.
2. **Ext `request_irq()` fail:** error is logged only; function still
   returns 0. Device probes in a partial-IRQ state. Later `enable_irq()`
   / `disable_irq()` / `free_irq()` on unregistered lines trigger
   `WARN_ON(!desc->action)`; missing handlers cause data loss.
3. **`alloc_netdev_dummy()` fail** on a later group: `-ENOMEM` without
   freeing earlier groups’ ext IRQs / dummy netdevs.

Fix: propagate errors, unwind registered IRQs/resources, assign
`ab->irq_num[irq_idx]` only after a successful `request_irq()`.

- Record: **[Bugs: IRQ leak, swallowed setup error, dummy-netdev leak]**
  **[Symptoms: leaked IRQ handlers; WARN_ON; missing datapath IRQs /
  data loss]** **[No version bounds in the message]** **[Root cause:
  missing unwind + ignored `request_irq()` failure]**

**Step 1.4 — Hidden bug fix?**
- Record: **No.** This is an explicit error-path / resource-leak fix,
  not cleanup disguised as a fix.

---

## PHASE 2: DIFF ANALYSIS

**Step 2.1 — Inventory**
- Record: **1 file**, `drivers/net/wireless/ath/ath11k/ahb.c`, **+55 /
  −24**.
- Functions: `ath11k_ahb_free_ext_irq` split into
  `ath11k_ahb_free_ext_irq_grp` + wrapper; new
  `ath11k_ahb_free_ce_irqs`; `ath11k_ahb_free_irq` uses the new helpers;
  `ath11k_ahb_config_ext_irq` and `ath11k_ahb_config_irq` grow unwind
  paths.
- Scope: **single-file surgical fix** (small helper extract, no API
  change).

**Step 2.2 — Flow change**
- **`free_ext_irq`:** all-groups cleanup → per-group helper so a failed
  group can be unwound without touching later groups.
- **`config_ext_irq` `request_irq` fail:** log and continue / return 0 →
  set `num_irq = j`, free current group, unwind prior groups, return
  error.
- **`alloc_netdev_dummy` fail:** immediate `-ENOMEM` → same unwind of
  prior groups.
- **`irq_num` store:** before `request_irq` → after success (avoids a
  stale IRQ number used by later enable/disable/free).
- **`config_irq` CE fail:** bare `return ret` →
  `ath11k_ahb_free_ce_irqs(ab, i)` then return.
- **`config_irq` ext fail:** return `ret` with CE IRQs still held → free
  all CE IRQs then return.

**Step 2.3 — Bug mechanism**
- Record: **[Error-path resource leak + logic/correctness (swallowed
  error)]**
- CE leak = missing `free_irq` on probe failure.
- Ext path = ignored `request_irq` error so probe “succeeds” with
  unregistered IRQs; `ath11k_ahb_ext_grp_enable()` then calls
  `enable_irq()` over `irq_grp->num_irq`.
- Dummy-netdev leak is mainline-only (see Phase 6).

**Step 2.4 — Fix quality**
- Record: **Obviously correct for the two `request_irq` bugs.** Helpers
  match existing free loops. `num_irq = j` before freeing the failed
  group is right (only successful IRQs). `err_request_irq` does `i--` so
  the current group is not double-freed. **Regression risk is low** if
  adapted; **high if the mainline diff is applied blindly** because it
  calls `free_netdev(irq_grp->napi_ndev)` and `napi_ndev` is an embedded
  `struct net_device` here, not a pointer.

---

## PHASE 3: GIT HISTORY

**Step 3.1 — Blame / introduction**
- Record: Buggy CE early-return and swallowed ext `request_irq` error
  are in the original driver **`d5c65159f2895` (2019-11-23, “ath11k:
  driver for Qualcomm IEEE 802.11ax devices”)**. Present since before
  v5.6; certainly in 6.1.

**Step 3.2 — Fixes: tag**
- Record: **No `Fixes:` tag.** Original buggy commit is `d5c65159f2895`,
  which **is** in this tree.

**Step 3.3 — File history on this tree**
- Record: Recent 6.1.y ahb.c commits are unrelated (IPQ5018 CE remap,
  rproc defer, fw deinit, `platform_get_irq` for MSI). Related older
  commit **`22b59cb965f79`** added `netif_napi_del()` on free to fix a
  reload oops — same area, does **not** fix these leaks. **Standalone
  candidate**, not patch X/Y.

**Step 3.4 — Author**
- Record: ZhaoJinming has **no other ath11k commits in this 6.1 tree**.
  Review/apply came from Qualcomm (Baochen Qiang, Rameshkumar Sundaram,
  Jeff Johnson).

**Step 3.5 — Prerequisites**
- Record: Mainline diff **depends on `bca592ead8252` (2024-04-22,
  dynamic dummy netdev)** for `alloc_netdev_dummy` / `free_netdev`. That
  commit is **not** in 6.1 (`git merge-base --is-ancestor` failed).
  CE/ext `request_irq` unwind does **not** need that commit. **Cannot
  apply the mainline diff standalone; a 6.1-shaped backport can.**

---

## PHASE 4: MAILING LIST / EXTERNAL

**Step 4.1 — Original discussion**
- Record: `b4 dig -c 8ab38bbac0229` → lore thread
  https://patch.msgid.link/20260728031335.3818736-1-
  zhaojinming@uniontech.com
- Revisions: **v1 (2026-06-22) through v7 (2026-07-28)**; committed
  message id is a follow-up of v7. Review drove: move `irq_grp` to
  function scope, init `ret` on ENOMEM, unwind CE IRQs on ext failure,
  extract per-group/CE free helpers, drop an unreachable `napi_ndev`
  NULL guard, store `irq_num` only after success.
- **No NAK.** Baochen’s v7 comment was process-only (don’t put old-
  version `Link:` in the commit body). **No reviewer `Cc: stable`.**

**Step 4.2 — Recipients (`b4 dig -w`)**
- Record: Jeff Johnson, Baochen Qiang, `ath11k@lists.infradead.org`,
  `linux-wireless@vger.kernel.org`, `linux-kernel@vger.kernel.org`.
  Right maintainers were on the thread.

**Step 4.3 — Bug report**
- Record: **No user/syzbot/bugzilla report.** Analysis-driven. Severity
  claimed by the author is verified in this tree’s code (Phase 6).

**Step 4.4 — Series**
- Record: **Single-patch series** (v1–v7 are revisions of the same
  change). No sibling patches required.

**Step 4.5 — Stable list**
- Record: **UNVERIFIED.** `lore.kernel.org/stable` fetch returned HTTP
  403. No stable-list discussion found via `b4`.

---

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1 — Functions**
- Record: `ath11k_ahb_free_ext_irq_grp` (new),
  `ath11k_ahb_free_ext_irq`, `ath11k_ahb_free_ce_irqs` (new),
  `ath11k_ahb_free_irq`, `ath11k_ahb_config_ext_irq`,
  `ath11k_ahb_config_irq`.

**Step 5.2 — Callers (this tree)**
- `ath11k_ahb_config_irq()` — only from `ath11k_ahb_probe()`
  (`ahb.c:1219`).
- `ath11k_ahb_free_irq()` — from `ath11k_ahb_free_resources()` on
  remove/shutdown (`ahb.c:1268`), **not** from probe `err_ce_free`.
- `ath11k_ahb_ext_grp_enable()` — from `ath11k_ahb_ext_irq_enable()` /
  NAPI complete; walks `irq_grp->num_irq` and `enable_irq()`.
- Hybrid WCN6750 uses `ath11k_pcic_config_irq()` instead (PCI probe
  **does** have `err_free_irq`).

**Step 5.3 — Callees**
- Record: `request_irq`, `free_irq`, `platform_get_irq_byname`,
  `irq_set_status_flags`, `netif_napi_add` / `netif_napi_del`,
  `init_dummy_netdev` (6.1) vs `alloc_netdev_dummy` / `free_netdev`
  (mainline).

**Step 5.4 — Reachability**
- Record: Probe / start / remove of `CONFIG_ATH11K_AHB` devices
  (IPQ8074/6018/5018 and similar). Userspace cannot hit it via a normal
  syscall; it runs on device bind, `ath11k_ahb_start()`, and unbind.
  **Reachable on every AHB ath11k probe.** The *failure* path needs
  `request_irq()` to fail (missing DT IRQ, IRQ alloc failure).

**Step 5.5 — Similar patterns**
- Record: `ath11k_pcic_ext_irq_config()` **does** return `request_irq`
  errors; PCI probe frees IRQs on error. AHB is the inconsistent path.
  Same swallowed-`request_irq` pattern has been in AHB since 2019.

---

## PHASE 6: THIS TREE (6.1.188)

**Step 6.1 — Does the buggy code exist?**
Yes, two of three bugs:

```617:624:drivers/net/wireless/ath/ath11k/ahb.c
                        if (ret) {
                                ath11k_err(ab, "failed request_irq for
%d\n",
                                           irq);
                        }
                }
        }

        return 0;
```

`num_irq` is set to the **full** count **before** that loop
(`ahb.c:605`), and `ab->irq_num[irq_idx] = irq` is stored **before**
`request_irq()` (`ahb.c:612`). `ath11k_ahb_ext_grp_enable()` then
`enable_irq()`s every entry (`ahb.c:247-248`).

```649:650:drivers/net/wireless/ath/ath11k/ahb.c
                if (ret)
                        return ret;
```

Probe error path:

```1219:1230:drivers/net/wireless/ath/ath11k/ahb.c
        ret = ath11k_ahb_config_irq(ab);
        if (ret) {
                ath11k_err(ab, "failed to configure irq: %d\n", ret);
                goto err_ce_free;
        }
        ...
err_ce_free:
        ath11k_ce_free_pipes(ab);
```

No `ath11k_ahb_free_irq()` on that path.

**Third bug does not exist here.** Dummy NAPI netdev is embedded:

```172:172:drivers/net/wireless/ath/ath11k/core.h
        struct net_device napi_ndev;
```

Setup uses `init_dummy_netdev(&irq_grp->napi_ndev)` (`ahb.c:558`). No
`alloc_netdev_dummy`, no `free_netdev`.

- Record: **Bugs 1 and 2 present since 2019. Bug 3 introduced in 2024;
  not in 6.1.**

**Step 6.2 — Backport difficulty**
- `git show 8ab38bb | git apply --check` **fails**: context expects
  `free_netdev(irq_grp->napi_ndev)`.
- Needed 6.1 backport: same error propagation and CE/ext unwind;
  **omit** `free_netdev` and the `alloc_netdev_dummy` ENOMEM path; keep
  `netif_napi_del` only.
- Record: **Needs rework (not a clean cherry-pick).** Blind apply would
  not compile.

**Step 6.3 — Related fixes already here?**
- Record: **No equivalent fix.** `22b59cb965f79` only added
  `netif_napi_del` on the success/remove free path.

---

## PHASE 7: SUBSYSTEM CONTEXT

**Step 7.1**
- Record: **`drivers/net/wireless/ath/ath11k` (AHB HIF).** Criticality:
  **IMPORTANT** — Qualcomm Wi-Fi 6 on IPQ SoCs used in routers/APs; not
  core mm/net, but common on 6.1 LTS embedded/enterprise images.
  `CONFIG_ATH11K_AHB`.

**Step 7.2**
- Record: Mature driver (2019). 6.1.y still receives targeted ath11k
  backports (rproc defer, fw deinit, IPQ5018 CE remap). Not a staging or
  newly added subsystem.

---

## PHASE 8: IMPACT AND RISK

**Step 8.1 — Who is affected**
- Record: **Driver-specific / config-specific:** `CONFIG_ATH11K_AHB`
  (IPQ8074/6018/5018 class). Hybrid WCN6750 uses the PCI-common path and
  is not fixed (or broken) by this change.

**Step 8.2 — Trigger**
- Record: `request_irq()` failure during probe (bad/missing DT
  interrupt, IRQ exhaustion). **Uncommon on a correct board DT**, but
  then **every** subsequent enable/disable/free and datapath completion
  is wrong. Not an unprivileged syscall primitive; bind is typically
  module load / boot. **Unprivileged users do not directly trigger it.**

**Step 8.3 — Failure mode**
- Swallowed ext IRQ error: **`WARN_ON(!desc->action)`** plus missing
  TX/RX completion IRQs → **data loss / broken Wi-Fi while probe reports
  success**. Severity: **HIGH**.
- CE IRQ leak on failed probe: leaked IRQ actions, messy rebind.
  Severity: **MEDIUM–HIGH** (reload already oopsed in this area before
  `22b59cb`).
- Dummy-netdev leak: **N/A on this tree**.

**Step 8.4 — Risk vs benefit**
- Benefit: **High** for AHB boards if `request_irq` fails (WARN_ON +
  silent datapath loss is worse than a clean probe failure).
- Risk of a **correct 6.1 backport**: **Low** (error paths + helper
  split; success path behavior unchanged).
- Risk of the **raw mainline patch**: **High** (`free_netdev` on an
  embedded `net_device`).
- Ratio: **favorable if adapted; do not cherry-pick as-is.**

---

## PHASE 9: SYNTHESIS

**Step 9.1 — Evidence**

**For:**
- Real bugs in **this** 6.1 tree (CE leak; swallowed ext `request_irq`).
- User-visible: kernel `WARN_ON`, missing datapath IRQs, data loss,
  leaked IRQ handlers.
- Small, one-file, no new API/feature.
- Logic checked against probe/remove and `enable_irq` paths in this
  checkout.
- Present since 2019; reviewed by Qualcomm ath11k reviewers; applied by
  Jeff Johnson.
- PCI sibling already returns `request_irq` errors; AHB is the hole.

**Against:**
- Mainline diff **does not apply**; it assumes `alloc_netdev_dummy` /
  pointer `napi_ndev` (`bca592ead8252` not in 6.1).
- Third issue is **not** in 6.1.
- Trigger is uncommon (needs `request_irq` failure).
- No `Reported-by` / syzbot / stable-list nomination (stable search
  UNVERIFIED).
- Author is not an ath11k regular on this tree.

**Unresolved:** stable@ discussion (HTTP 403).

**Step 9.2 — Stable rules**
1. Obviously correct and tested? **PASS** for the two applicable bugs
   (review + maintainer apply). The shipped diff is **not** drop-in
   correct on 6.1.
2. Real bug affecting users? **PASS** (WARN_ON, data loss, IRQ leak on
   AHB probe/remove).
3. Important (crash / warn / data loss / leak)? **PASS** — HIGH for
   swallowed ext IRQ failure.
4. Small and contained? **PASS** (one file, ~50 lines of logic).
5. No new features/APIs? **PASS**.
6. Can apply to this tree? **FAIL** as a raw cherry-pick; **PASS** as a
   small mechanical backport (drop `free_netdev` / `alloc_netdev_dummy`
   ENOMEM path).

**Step 9.3 — Exception category**
- Record: **None** (not a device ID, quirk, DT, build, or doc fix).
  Qualifies as a normal error-path / correctness bug fix.

**Step 9.4 — Decision**
The two bugs that matter on 6.1 are in this tree, are real, and are
serious when they fire. The mainline commit also cleans up a later
dummy-netdev leak that 6.1 does not have; that does not erase the AHB
`request_irq` holes. A 6.1 backport must **not** call `free_netdev` on
the embedded `napi_ndev`. With that adjustment, this belongs on 6.1.y.

---

## What the commit solves for 6.1 users

On IPQ AHB ath11k, a failed `request_irq()` for an ext IRQ is ignored
and probe still succeeds. Start/remove then `enable_irq`/`free_irq`
unregistered lines (`WARN_ON`) and drop datapath interrupts. A failed CE
`request_irq()` also leaks earlier CE handlers because probe’s
`err_ce_free` never calls `ath11k_ahb_free_irq()`. Both are old,
contained, and worth fixing on this LTS tree. The dummy-netdev part of
the mainline patch is irrelevant here and must be omitted.

---

## Verification
- [Phase 1] Parsed tags: Reviewed-by Rameshkumar Sundaram, Baochen
  Qiang; SOB ZhaoJinming + Jeff Johnson; Link msgid 20260729020005; no
  Fixes/Reported-by/Cc:stable
- [Phase 2] Diff: +55/−24 in `ahb.c`; helper split + error unwind;
  `irq_num` assigned after success
- [Phase 3] `git log` on `ahb.c`: swallowed ext error and CE early-
  return since `d5c65159f2895` (2019-11-23)
- [Phase 3] No Fixes: tag; `bca592ead8252` is **not** an ancestor of
  HEAD
- [Phase 3] `git log --author=ZhaoJinming` on ath11k in this tree: no
  other commits
- [Phase 4] `b4 dig -c 8ab38bbac0229`: thread https://patch.msgid.link/2
  0260728031335.3818736-1-zhaojinming@uniontech.com
- [Phase 4] `b4 dig -a`: v1–v7; committed version is latest content
  (v6+irq_num ordering, v7 resend)
- [Phase 4] `b4 dig -w`: Jeff Johnson, Baochen Qiang, ath11k and linux-
  wireless lists
- [Phase 4] mbox: Baochen process comment only; no NAK; no Cc:stable
- [Phase 4] lore.kernel.org WebFetch: HTTP 403; stable-list search
  UNVERIFIED
- [Phase 5] Callers: `ath11k_ahb_probe` → `config_irq`; enable path
  `ath11k_ahb_ext_grp_enable` uses `num_irq`
- [Phase 6] `git describe HEAD` / Makefile: **6.1.188**
  (`p-6.1-11-gffee1c0de6cf2`); `v6.1.188` is ancestor
- [Phase 6] `git merge-base --is-ancestor 8ab38bbac0229 HEAD`: **not
  present**
- [Phase 6] Read `ahb.c` 545–659 and 1219–1230: bugs 1 and 2 present;
  `init_dummy_netdev` / embedded `napi_ndev`
- [Phase 6] `git apply --check` of 8ab38bb: **does not apply** (expects
  `free_netdev`)
- [Phase 8] Failure mode verified: `enable_irq` on stored irq_num after
  ignored `request_irq` → WARN_ON / data loss
- UNVERIFIED: whether stable@ already discussed this commit (lore 403)

The two AHB `request_irq` bugs exist in 6.1.188, are user-visible when
they trigger, and a small adapted backport (no `free_netdev`) is the
right way to take this commit.

**YES**

 drivers/net/wireless/ath/ath11k/ahb.c | 79 +++++++++++++++++++--------
 1 file changed, 55 insertions(+), 24 deletions(-)

diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c
index b8437e23e5192..5d8c0457721cd 100644
--- a/drivers/net/wireless/ath/ath11k/ahb.c
+++ b/drivers/net/wireless/ath/ath11k/ahb.c
@@ -431,36 +431,44 @@ static void ath11k_ahb_init_qmi_ce_config(struct ath11k_base *ab)
 	ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id;
 }
 
-static void ath11k_ahb_free_ext_irq(struct ath11k_base *ab)
+static void ath11k_ahb_free_ext_irq_grp(struct ath11k_base *ab,
+					struct ath11k_ext_irq_grp *irq_grp)
 {
-	int i, j;
-
-	for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
-		struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
+	int j;
 
-		for (j = 0; j < irq_grp->num_irq; j++)
-			free_irq(ab->irq_num[irq_grp->irqs[j]], irq_grp);
+	for (j = 0; j < irq_grp->num_irq; j++)
+		free_irq(ab->irq_num[irq_grp->irqs[j]], irq_grp);
 
-		netif_napi_del(&irq_grp->napi);
-		free_netdev(irq_grp->napi_ndev);
-	}
+	netif_napi_del(&irq_grp->napi);
+	free_netdev(irq_grp->napi_ndev);
 }
 
-static void ath11k_ahb_free_irq(struct ath11k_base *ab)
+static void ath11k_ahb_free_ext_irq(struct ath11k_base *ab)
 {
-	int irq_idx;
 	int i;
 
-	if (ab->hw_params.hybrid_bus_type)
-		return ath11k_pcic_free_irq(ab);
+	for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++)
+		ath11k_ahb_free_ext_irq_grp(ab, &ab->ext_irq_grp[i]);
+}
 
-	for (i = 0; i < ab->hw_params.ce_count; i++) {
+static void ath11k_ahb_free_ce_irqs(struct ath11k_base *ab, int max_idx)
+{
+	int irq_idx, i;
+
+	for (i = 0; i < max_idx; i++) {
 		if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
 			continue;
 		irq_idx = ATH11K_IRQ_CE0_OFFSET + i;
 		free_irq(ab->irq_num[irq_idx], &ab->ce.ce_pipe[i]);
 	}
+}
+
+static void ath11k_ahb_free_irq(struct ath11k_base *ab)
+{
+	if (ab->hw_params.hybrid_bus_type)
+		return ath11k_pcic_free_irq(ab);
 
+	ath11k_ahb_free_ce_irqs(ab, ab->hw_params.ce_count);
 	ath11k_ahb_free_ext_irq(ab);
 }
 
@@ -524,20 +532,25 @@ static irqreturn_t ath11k_ahb_ext_interrupt_handler(int irq, void *arg)
 static int ath11k_ahb_config_ext_irq(struct ath11k_base *ab)
 {
 	struct ath11k_hw_params *hw = &ab->hw_params;
+	struct ath11k_ext_irq_grp *irq_grp;
 	int i, j;
 	int irq;
 	int ret;
 
 	for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
-		struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
 		u32 num_irq = 0;
 
+		irq_grp = &ab->ext_irq_grp[i];
+
 		irq_grp->ab = ab;
 		irq_grp->grp_id = i;
 
 		irq_grp->napi_ndev = alloc_netdev_dummy(0);
-		if (!irq_grp->napi_ndev)
-			return -ENOMEM;
+		if (!irq_grp->napi_ndev) {
+			ret = -ENOMEM;
+			irq_grp->num_irq = 0;
+			goto err_request_irq;
+		}
 
 		netif_napi_add(irq_grp->napi_ndev, &irq_grp->napi,
 			       ath11k_ahb_ext_grp_napi_poll);
@@ -585,14 +598,11 @@ static int ath11k_ahb_config_ext_irq(struct ath11k_base *ab)
 				}
 			}
 		}
-		irq_grp->num_irq = num_irq;
-
-		for (j = 0; j < irq_grp->num_irq; j++) {
+		for (j = 0; j < num_irq; j++) {
 			int irq_idx = irq_grp->irqs[j];
 
 			irq = platform_get_irq_byname(ab->pdev,
 						      irq_name[irq_idx]);
-			ab->irq_num[irq_idx] = irq;
 			irq_set_status_flags(irq, IRQ_NOAUTOEN | IRQ_DISABLE_UNLAZY);
 			ret = request_irq(irq, ath11k_ahb_ext_interrupt_handler,
 					  IRQF_TRIGGER_RISING,
@@ -600,11 +610,24 @@ static int ath11k_ahb_config_ext_irq(struct ath11k_base *ab)
 			if (ret) {
 				ath11k_err(ab, "failed request_irq for %d\n",
 					   irq);
+				irq_grp->num_irq = j;
+				ath11k_ahb_free_ext_irq_grp(ab, irq_grp);
+				goto err_request_irq;
 			}
+			ab->irq_num[irq_idx] = irq;
 		}
+
+		irq_grp->num_irq = num_irq;
 	}
 
 	return 0;
+
+err_request_irq:
+	for (i--; i >= 0; i--) {
+		irq_grp = &ab->ext_irq_grp[i];
+		ath11k_ahb_free_ext_irq_grp(ab, irq_grp);
+	}
+	return ret;
 }
 
 static int ath11k_ahb_config_irq(struct ath11k_base *ab)
@@ -629,16 +652,24 @@ static int ath11k_ahb_config_irq(struct ath11k_base *ab)
 		ret = request_irq(irq, ath11k_ahb_ce_interrupt_handler,
 				  IRQF_TRIGGER_RISING, irq_name[irq_idx],
 				  ce_pipe);
-		if (ret)
+		if (ret) {
+			ath11k_err(ab, "failed request_irq for %d\n", irq);
+			ath11k_ahb_free_ce_irqs(ab, i);
 			return ret;
+		}
 
 		ab->irq_num[irq_idx] = irq;
 	}
 
 	/* Configure external interrupts */
 	ret = ath11k_ahb_config_ext_irq(ab);
+	if (ret) {
+		ath11k_err(ab, "failed to configure ext irq: %d\n", ret);
+		ath11k_ahb_free_ce_irqs(ab, ab->hw_params.ce_count);
+		return ret;
+	}
 
-	return ret;
+	return 0;
 }
 
 static int ath11k_ahb_map_service_to_pipe(struct ath11k_base *ab, u16 service_id,
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18] wifi: iwlwifi: validate UEFI reduced-power SKU TLV length
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (27 preceding siblings ...)
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-6.12] wifi: ath11k: fix resource leak on error in ext IRQ setup Sasha Levin
@ 2026-10-19 13:51 ` Sasha Levin
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: mld: validate wake packet crypto overhead Sasha Levin
                   ` (11 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:51 UTC (permalink / raw)
  To: patches, stable
  Cc: Pengpeng Hou, Miri Korenblit, Sasha Levin, linux-wireless,
	linux-kernel

From: Pengpeng Hou <pengpeng@iscas.ac.cn>

[ Upstream commit f051995c539582b05276abda4c5874fd4cafd2a5 ]

iwl_uefi_reduce_power_parse() reads an iwl_sku_id from an
IWL_UCODE_TLV_PNVM_SKU payload after only checking that the generic TLV
payload is present.

A short type-specific payload can therefore make the three data[] reads
extend beyond the TLV. Reject SKU TLVs shorter than the structure before
accessing it.

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Link: https://patch.msgid.link/20260715135916.24417-2-pengpeng@iscas.ac.cn
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

This checkout is **v7.3-rc4** (mainline `7.3.0-rc4`). The analysis below
is only for this tree.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

Step 1.1: PARSE THE SUBJECT LINE
Record: **[iwlwifi / wifi]** **[validate]** — reject a UEFI reduced-
power `IWL_UCODE_TLV_PNVM_SKU` payload shorter than `struct iwl_sku_id`
before reading it. “Validate” here is a bounds check, not a feature add.

Step 1.2: PARSE ALL COMMIT MESSAGE TAGS
Record:
- **Fixes:** none (expected for this review path)
- **Reported-by:** none
- **Tested-by:** none
- **Reviewed-by:** none on the commit; v1 was reviewed on-list by the
  iwlwifi maintainer
- **Acked-by:** none
- **Link:**
  `https://patch.msgid.link/20260715135916.24417-2-pengpeng@iscas.ac.cn`
- **Cc: stable:** none (expected)
- **Signed-off-by:** Pengpeng Hou (author); Miri Korenblit (iwlwifi
  maintainer, applied it)
- Ignore pipeline SOBs. Pattern: two-patch series (`24417-1` PNVM
  parser, `24417-2` this UEFI parser); no syzbot.

Step 1.3: ANALYZE THE COMMIT BODY TEXT
Record:
- **Bug:** `iwl_uefi_reduce_power_parse()` treats a PNVM SKU TLV as
  `struct iwl_sku_id` after only checking that the generic TLV payload
  fits in the remaining buffer.
- **Symptom:** three `data[]` reads can extend past the TLV; if
  remaining bytes after the header are also `< 12`, that is a real out-
  of-bounds read of the UEFI blob.
- **Version info:** none in the message.
- **Root cause:** missing type-specific minimum length vs `sizeof(struct
  iwl_sku_id)` (`__le32 data[3]`, 12 bytes).

Step 1.4: DETECT HIDDEN BUG FIXES
Record: Not disguised. It is an explicit length check before the three
SKU word reads.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

Step 2.1: INVENTORY THE CHANGES
Record:
- **File:** `drivers/net/wireless/intel/iwlwifi/fw/uefi.c` — **+6 / −0**
- **Function:** `iwl_uefi_reduce_power_parse()`
- **Scope:** single-file surgical fix

Step 2.2: UNDERSTAND THE CODE FLOW CHANGE
Record:
- **Before:** loop requires `len >= sizeof(*tlv)` (8-byte header). After
  subtracting the header it checks `len < tlv_len` (payload vs remaining
  buffer), then on `IWL_UCODE_TLV_PNVM_SKU` casts the payload to `struct
  iwl_sku_id` and reads `data[0..2]` even if `tlv_len` is 0–11.
- **After:** if `tlv_len < sizeof(*tlv_sku_id)` log and return `-EINVAL`
  before those reads.
- **Path:** firmware/UEFI parse during Intel WiFi PNVM/reduce-power
  load, not a hot datapath.

Step 2.3: IDENTIFY THE BUG MECHANISM
Record: **Memory safety / out-of-bounds read.** Outer check only proves
the claimed TLV payload is inside the remaining buffer, not that it is
12 bytes. If `tlv_len=4` and remaining `len=8`, `8 < 4` is false, then
12 bytes are read from an 8-byte remainder → **allocation OOB**. If
remaining `len >= 12` but `tlv_len < 12`, the reads stay in the
allocation but past this TLV.

Step 2.4: ASSESS THE FIX QUALITY
Record: Obviously correct and minimal (same pattern as the sibling PNVM
check). Regression risk is low: a too-short SKU TLV cannot be used
anyway; `-EINVAL` makes `iwl_pnvm_load_reduce_power_to_trans()` set
`failed_to_load_reduce_power_image` and skip the table. No API or lock
changes.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

Step 3.1: BLAME THE CHANGED LINES
Record: The parser dates to **9dad325f9d575** (“iwlwifi: support loading
the reduced power table from UEFI”, 2021-06-21), first in **v5.14-rc1**.
SKU access was later adjusted by **3a68ae0fa2ec13** (“wifi: iwlwifi:
remove sku_id from trans”, 2025-05-04). The six new lines are this
commit (**f051995c53958**, 2026-07-15). The missing min-length check has
been there since the parser was added.

Step 3.2: FOLLOW THE FIXES: TAG
Record: No `Fixes:` tag. Introduction commit **9dad325f9d575** is an
ancestor of this HEAD. No intermediate SKU-length check on this function
before this patch.

Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES
Record: Immediate parent is sibling **7410e4548a17b** (“wifi: iwlwifi:
validate PNVM SKU TLV length”) — same author, same date, same check in
`iwl_pnvm_parse()`. Independent; this UEFI patch does not need that
hunk. Nearby **daec24a5ed5da** is a different length check in
`iwl_pnvm_complete_fn()`. Standalone as a 2/2 series member.

Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS
Record: Pengpeng Hou has these two iwlwifi validation commits in this
tree. Applied by **Miri Korenblit**, listed iwlwifi maintainer in
MAINTAINERS.

Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS
Record: Uses existing `tlv_sku_id`, `tlv_len`, `IWL_ERR`, `-EINVAL`. No
new helpers. Can apply standalone wherever
`iwl_uefi_reduce_power_parse()` still has this loop.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION
Record:
- **v2 (applied):**
  https://patch.msgid.link/20260715135916.24417-2-pengpeng@iscas.ac.cn
- **v1:** 2026-06-30,
  https://lore.kernel.org/all/2026063008051412.5-ccfa108-0020-wifi-
  iwlwifi-validate-UEFI--pengpeng@iscas.ac.cn/
- v1 used `tlv_len < 3 * sizeof(__le32)`; Miri asked for
  `sizeof(*tlv_sku_id)`; v2 did that. No NAK. b4 mbox for v2 is the
  patch only (no further replies).

Step 4.2: CHECK WHO REVIEWED THE PATCH
Record: To/Cc: Miri Korenblit, linux-wireless, linux-kernel. Maintainer
reviewed v1 and applied v2.

Step 4.3: SEARCH FOR THE BUG REPORT
Record: No syzbot, bugzilla, or user crash report. Author-found parser
hole. Syzbot CI on v2: KASAN build/boot passed; fuzz skipped.

Step 4.4: CHECK FOR RELATED PATCHES AND SERIES
Record: Pair with **7410e4548a17b** (`24417-1`, `iwl_pnvm_parse()`).
Same bug class, different file. This patch does not depend on that one.

Step 4.5: CHECK STABLE MAILING LIST HISTORY
Record: No stable-list discussion found for this subject. Absence of
`Cc: stable` is expected here.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF
Record: `iwl_uefi_reduce_power_parse()` only.

Step 5.2: TRACE CALLERS
Record:
- Declared in `fw/uefi.h` under `#ifdef CONFIG_EFI` (stub `-EOPNOTSUPP`
  otherwise).
- Only caller: `iwl_pnvm_load_reduce_power_to_trans()` in `fw/pnvm.c`.
- That is called from `iwl_pnvm_load()`, exported and used from
  `mvm/fw.c` and `mld/fw.c` during firmware/PNVM init.
- Not IRQ; process context during WiFi bring-up.

Step 5.3: TRACE CALLEES
Record: Reads UEFI blob from `iwl_uefi_get_reduced_power()` →
`iwl_uefi_get_verified_variable()` (`kmalloc`/`kmemdup` of EFI var). On
SKU match, `iwl_uefi_reduce_power_section()`. Fix only adds a length
check and error return.

Step 5.4: FOLLOW THE CALL CHAIN
Record: Device probe / firmware start → `iwl_pnvm_load()` → reduce-power
UEFI parse. Not a syscall parser. Trigger needs Intel iwlwifi,
`CONFIG_EFI`, runtime EFI `GetVariable`, and a Reduced Power variable
with a short PNVM_SKU TLV. Unprivileged userspace cannot normally forge
that; root/firmware can. Still a kernel OOB on bad firmware/BIOS data.

Step 5.5: SEARCH FOR SIMILAR PATTERNS
Record: Identical hole and fix in `iwl_pnvm_parse()` (`pnvm.c` lines
208–212 in this tree). Same systematic miss.

===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================

Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?
Record: Yes. `iwl_uefi_reduce_power_parse()` is in `uefi.c` from v5.14.
This tree is **v7.3-rc4**; the fix itself is already an ancestor (`git
merge-base --is-ancestor f051995c53958 HEAD` succeeded) and first
appeared in **v7.3-rc1**. The parser and the OOB path exist in this
lineage.

Step 6.2: CHECK FOR BACKPORT COMPLICATIONS
Record: **Clean apply** on this tree’s pre-image (original commit).
Context is the long-standing TLV loop; no local conflicts.

Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE
Record: This is the fix. Sibling PNVM check is also here. No earlier
substitute for the UEFI parser.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY
Record: **iwlwifi** (`drivers/net/wireless/intel/iwlwifi/`).
**IMPORTANT** — common Intel WiFi driver, not core mm/VFS, not staging.

Step 7.2: ASSESS SUBSYSTEM ACTIVITY
Record: Actively developed (UEFI/PNVM/regulatory churn through 2026).
The missing check is old (2021); this is hardening of mature parse
logic, not a bug in brand-new code.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

Step 8.1: DETERMINE WHO IS AFFECTED
Record: **Driver-specific + config-specific:** Intel iwlwifi +
`CONFIG_EFI` + platforms that expose the Reduced Power UEFI variable.

Step 8.2: DETERMINE THE TRIGGER CONDITIONS
Record: WiFi firmware/PNVM load with a short `IWL_UCODE_TLV_PNVM_SKU` in
that UEFI blob. Uncommon on good OEM tables; realistic with
corrupt/malicious EFI data. Not a normal unprivileged syscall.

Step 8.3: DETERMINE THE FAILURE MODE SEVERITY
Record: Out-of-bounds **read** of up to ~12 bytes. Can KASAN/oops if the
SKU TLV sits near the end of the `kmemdup` buffer; otherwise reads the
next TLV and can mis-match SKU / skip reduce-power. **HIGH** for the
true OOB case (crash on probe), not data corruption of user files.

Step 8.4: CALCULATE RISK-BENEFIT RATIO
Record:
- **Benefit:** high for affected laptops/APs — avoids OOB during WiFi
  init on bad UEFI data; check is cheap.
- **Risk:** very low — 6 lines, error path only, maintainer-acked form.
- **Ratio:** favorable.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

Step 9.1: COMPILE THE EVIDENCE
**For:**
- Real type-specific length hole; OOB read of `iwl_sku_id` (12 bytes) is
  visible in the code.
- Six-line, obviously correct check; v2 matches maintainer review
  (`sizeof(*tlv_sku_id)`).
- iwlwifi maintainer applied it; same fix already used in
  `iwl_pnvm_parse()`.
- Parser present since v5.14; this tree has it.
- Applies cleanly; no new API; no extra dependency for *this* hunk.

**Against:**
- No user/syzbot report; trigger is malformed UEFI, not a common
  syscall.
- Reduce-power table is not the data path; failed parse already degrades
  to skipping the image.
- `CONFIG_EFI` only.

**Unresolved:** lore.kernel.org HTML fetch returned 403; discussion
recovered via b4 mbox, msgid.link, and LKML mirrors. No stable-list
thread found.

Step 9.2: APPLY THE STABLE RULES CHECKLIST
1. Obviously correct and tested? **PASS** — size check before
   `data[0..2]`; v2 from maintainer review; in iwlwifi-next then
   mainline.
2. Fixes a real bug that affects users? **PASS** — OOB read of a kernel
   buffer parsed at WiFi init.
3. Important issue? **PASS** — OOB can oops; severity HIGH, not LOW
   cosmetics.
4. Small and contained? **PASS** — +6 lines, one function.
5. No new features or APIs? **PASS**.
6. Can apply to the local tree? **PASS** — this tree already contains
   the original commit; pre-image matches.

Step 9.3: CHECK FOR EXCEPTION CATEGORIES
Record: Not a device-ID/quirk/DT/docs exception. Ordinary memory-safety
fix.

Step 9.4: MAKE YOUR DECISION
This tree’s iwlwifi UEFI reduce-power parser has the hole; the patch is
a small, reviewed bounds check that prevents a real OOB read. That meets
stable rules for **this** checkout.

What it solves for this tree: `iwl_uefi_reduce_power_parse()` can read
12 bytes from a PNVM SKU TLV whose declared length is shorter, and can
walk off the UEFI blob when remaining length is also `< 12`. That
matters on Intel WiFi + EFI machines with a bad Reduced Power variable
(crash/KASAN on init). The change is six lines, no new ABI, no extra
commits required, and the sibling PNVM check is independent.

Risk vs benefit: very low regression risk vs preventing an OOB on a
widely used driver. Main caveat is the uncommon trigger; that does not
make the hole theoretical in the code.

Verification:
- [Phase 1] Subject/body/tags: validate SKU TLV length; SOB Hou +
  Korenblit; Link `24417-2`; no Fixes/Reported-by/Cc:stable
- [Phase 2] Diff: +6 in `iwl_uefi_reduce_power_parse()`; `if (tlv_len <
  sizeof(*tlv_sku_id)) return -EINVAL`
- [Phase 2] `struct iwl_sku_id` is `__le32 data[3]` in `fw/api/alive.h`;
  `iwl_ucode_tlv` is 8-byte header + `data[]` in `fw/file.h`
- [Phase 3] `git describe HEAD` / Makefile: v7.3-rc4 / 7.3.0-rc4
- [Phase 3] `git merge-base --is-ancestor f051995c53958 HEAD` → yes
- [Phase 3] Blame: parser from 9dad325f9d575 (v5.14-rc1); fix lines from
  f051995c53958 (v7.3-rc1)
- [Phase 3] Sibling 7410e4548a17b is patch 1/2 on `pnvm.c`, not a apply-
  prereq
- [Phase 4] `b4 dig -c f051995c53958`: v1 2026-06-30, v2 2026-07-15;
  mbox is the patch
- [Phase 4] LKML mirror: Miri “Please use sizeof(*tlv_sku_id)”; no NAK
- [Phase 4] Stable lore search: no discussion of this subject
- [Phase 5] Only caller `iwl_pnvm_load_reduce_power_to_trans` ←
  `iwl_pnvm_load` ← mvm/mld fw init; gated on CONFIG_EFI
- [Phase 5] Buffer from `iwl_uefi_get_reduced_power` / verified EFI
  variable (`kmalloc` then `kmemdup`)
- [Phase 6] Buggy parser present; fix already in this tree; would apply
  cleanly
- [Phase 7] iwlwifi, maintainer Miri Korenblit
- [Phase 8] Failure: OOB read / possible oops on WiFi init; HIGH;
  trigger EFI-malformed
- UNVERIFIED: lore.kernel.org HTTP 403 on direct thread fetch; content
  recovered from b4 and LKML mirrors

**YES**

 drivers/net/wireless/intel/iwlwifi/fw/uefi.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c
index 4ae4d215e633e..395973c3f2bf8 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c
@@ -248,6 +248,12 @@ int iwl_uefi_reduce_power_parse(struct iwl_trans *trans,
 			IWL_DEBUG_FW(trans,
 				     "Got IWL_UCODE_TLV_PNVM_SKU len %d\n",
 				     tlv_len);
+			if (tlv_len < sizeof(*tlv_sku_id)) {
+				IWL_ERR(trans, "invalid PNVM SKU TLV len: %u\n",
+					tlv_len);
+				return -EINVAL;
+			}
+
 			IWL_DEBUG_FW(trans, "sku_id 0x%0x 0x%0x 0x%0x\n",
 				     le32_to_cpu(tlv_sku_id->data[0]),
 				     le32_to_cpu(tlv_sku_id->data[1]),
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18] wifi: iwlwifi: mld: validate wake packet crypto overhead
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (28 preceding siblings ...)
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: validate UEFI reduced-power SKU TLV length Sasha Levin
@ 2026-10-19 13:51 ` Sasha Levin
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: mld: Do not cleanup FW state when the device is dead Sasha Levin
                   ` (10 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:51 UTC (permalink / raw)
  To: patches, stable
  Cc: Emmanuel Grumbach, Miri Korenblit, Sasha Levin, linux-wireless,
	linux-kernel

From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>

[ Upstream commit c5cb9dd220ba9fdcf4ba485ce3d1d36ca32ac00b ]

Wake packet parsing only accounted for FCS and missed per-key
IV/ICV overhead for protected data frames.

Prevent size underflow and bad packet trimming when
notifications are malformed or truncated.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Link: https://patch.msgid.link/20260717172958.e06595623533.Ie09494b7e34e5872b750fd90e325648ee469d0da@changeid
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local checkout is **Linux 7.3.0-rc4**. The iwlwifi MLD WoWLAN path
is present here, and this commit is a real memory-safety plus wake-
packet correctness fix for that path.

---

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: PARSE THE SUBJECT LINE**
Record: **[iwlwifi/mld]** **[validate]** — account for per-key IV/ICV
when parsing WoWLAN wake packets, and reject truncated/malformed sizes.

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- `Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>`
  (author; long-time iwlwifi developer)
- `Link: https://patch.msgid.link/20260717172958.e06595623533.Ie09494b7e
  34e5872b750fd90e325648ee469d0da@changeid`
- `Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>`
  (iwlwifi maintainer, committer)
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Acked-
  by:`, or `Cc: stable` (absence of Fixes/Cc:stable is expected for this
  review)
- No syzbot / KASAN / user crash tags

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** wake-packet parsing only subtracted FCS (4 bytes). It did not
  add the PTK/GTK IV and ICV lengths for protected data frames.
- **Symptom:** size underflow and incorrect trimming when the firmware
  wake-packet notification is malformed or truncated; userspace can get
  a bad or missing wakeup packet.
- **Version info:** none in the message. Code was introduced with iwlmld
  (`d1e879ec600f9`, v6.15).
- **Root cause (author):** missing per-key crypto overhead in
  `iwl_mld_set_wake_packet()`.

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not disguised. It is an explicit validation/correctness fix.
“Validate” plus “prevent size underflow” is a memory-safety fix, not a
cleanup.

---

## PHASE 2: DIFF ANALYSIS

**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `drivers/net/wireless/intel/iwlwifi/mld/d3.c` — **+57 / −6**
- New: `struct iwl_mld_wake_pkt_iter_data`,
  `iwl_mld_wake_pkt_key_iter()`
- Modified: `iwl_mld_set_wake_packet()`
- Scope: **single-file surgical fix** in the MLD D3/WoWLAN resume path

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:
1. **Header size:** previously cast `wake_packet` to `ieee80211_hdr`
   with no length check. Now `IWL_FW_CHECK` if `pkt_bufsize <
   sizeof(*hdr)` and return.
2. **Protected data frames:** previously `ivlen = 0`, `icvlen = 4` (FCS
   only). Now, if `ieee80211_has_protected()`, iterate keys and add
   `key->iv_len` / `key->icv_len`.
3. **Before `skb_put_data`:** new check `pkt_bufsize <= hdrlen + ivlen +
   icvlen`; skip copy if the buffer is too small.
4. **Non-data frames:** new check `pkt_bufsize <= fcslen` before
   subtracting FCS.
5. **Types:** `pkt_bufsize` / `expected_pktlen` / `truncated` changed
   from `int` to `u32` so underflow cannot go negative and then be
   passed as a huge `unsigned int` length.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record: **Memory safety (OOB / integer underflow) + logic/correctness**

Before, `skb_put_data()` takes `unsigned int len`. A signed
`pkt_bufsize` that goes negative after `pkt_bufsize -= hdrlen` or `-=
ivlen + icvlen` becomes a huge copy. `skb_put()` panics if `hdrlen`
exceeds the skb tailroom (`alloc_skb(pkt_bufsize)` then
`skb_put_data(..., hdrlen)`). Unchecked `hdr->frame_control` is an OOB
read if the firmware buffer is shorter than an 802.11 header.

Missing IV/ICV on protected frames (the common WPA2/WPA3 case) also mis-
trims the packet: `ieee80211_data_to_8023()` can fail, or userspace gets
a corrupted wake packet.

The fix matches the long-standing MVM path in
`drivers/net/wireless/intel/iwlwifi/mvm/d3.c` (IV/ICV from PTK vs GTK,
plus `IWL_FW_CHECK` on size). MLD uses `ieee80211_iter_keys()` because
it does not cache `gtk_ivlen`/`ptk_ivlen` like MVM.

**Step 2.4: ASSESS THE FIX QUALITY**
Record: **Obviously correct, minimal, low regression risk.** It copies
proven MVM logic. `ieee80211_iter_keys()` requires the wiphy mutex;
`iwl_mld_wowlan_resume()` already has `lockdep_assert_wiphy()`, and the
same resume path already calls `ieee80211_iter_keys()` in
`iwl_mld_update_sec_keys()`. If no matching key is found, `ivlen` stays
0 and `icvlen` stays 4 — same as the old path. Early return after
`alloc_skb` still sets `*_pkt`, and the caller `kfree_skb()`s it. No
public API change.

---

## PHASE 3: GIT HISTORY INVESTIGATION

**Step 3.1: BLAME THE CHANGED LINES**
Record: Buggy `iwl_mld_set_wake_packet()` came in **`d1e879ec600f9`**
(“wifi: iwlwifi: add iwlmld sub-driver”, 2025-02-16). Present since
**v6.15**. Not recent one-off code.

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No `Fixes:` tag. Introduction commit is `d1e879ec600f9`. `git
merge-base --is-ancestor d1e879ec600f9 HEAD` succeeds. Related later fix
in the same file: `c5aeb11489150` (“fix read in wake packet notification
handler”) is an **ancestor** of this commit and is independent (it only
reorders a length check in `iwl_mld_handle_wake_pkt_notif()`).

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record: Nearby D3 validation commits (`validate WoWLAN notif header`,
`validate D3_END notif size`) are separate. This patch is **1/8** of an
iwlwifi-next “updates” series; the other seven patches are unrelated
(scan-abort init, time-sync, BIOS move, MCC v2, etc.). **Standalone.**

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Emmanuel Grumbach is a core iwlwifi author. Same week he also
fixed MVM D3 FCS truncation (`9119aeeddc210`). Miri Korenblit committed
the patch. Strong maintainer provenance.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: Needs existing `IWL_FW_CHECK`, `ieee80211_iter_keys()`, and
`iwl_mld_set_wake_packet()`. All exist in this tree. **Can apply
standalone.**

---

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- `b4 dig -c c5cb9dd220ba9` → https://patch.msgid.link/20260717172958.e0
  6595623533.Ie09494b7e34e5872b750fd90e325648ee469d0da@changeid
- `b4 dig -a`: **v1 only** (`[PATCH iwlwifi-next 1/8]`)
- Cover: “A couple of fixes, features and cleanups.” This patch is one
  of the fixes.
- Saved mbox: **9 messages = cover + 8 patches, no review replies, no
  NAKs, no Cc: stable**
- HTTP lore fetch returned 403 (Anubis); discussion taken from the b4
  mbox instead

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record (`b4 dig -w`): Miri Korenblit, Johannes Berg
(`johannes@sipsolutions.net`), `linux-wireless@vger.kernel.org`,
Emmanuel Grumbach. Right lists/maintainers. Committed by Korenblit.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: No `Reported-by:` or bugzilla/syzbot link. Bug is described from
code inspection, not a user crash.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: Mixed 8-patch iwlwifi-next series. This hunk does not depend on
2/8–8/8. Related but independent: `c5aeb11489150` (wake-pkt notif
length), MVM D3 FCS fix `9119aeeddc210`.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: lore.kernel.org/stable search returned **403**. **UNVERIFIED**
whether stable@ already discussed this.

---

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1: KEY FUNCTIONS**
Record: `iwl_mld_wake_pkt_key_iter` (new), `iwl_mld_set_wake_packet`
(modified).

**Step 5.2: TRACE CALLERS**
Record:
- `iwl_mld_set_wake_packet()` ← `iwl_mld_report_wowlan_wakeup()` ←
  `iwl_mld_process_wowlan_status()` ← D3/WoWLAN resume
- Driver resume: `iwl_mld_resume()` → `iwl_mld_wowlan_resume()`
- mac80211: `ieee80211_reconfig()` → `drv_resume()` under
  `lockdep_assert_wiphy()`
- Context: process context on suspend/resume, not hardirq

**Step 5.3: TRACE CALLEES**
Record: `ieee80211_iter_keys`, `ieee80211_hdrlen`,
`ieee80211_has_protected`, `alloc_skb` / `skb_put_data`,
`ieee80211_data_to_8023`, `IWL_FW_CHECK` (log + boolean).

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: Reachable from userspace via WoWLAN (suspend with wowlan
enabled, then a wake packet). Needs `CONFIG_IWLMLD` and
`CONFIG_PM_SLEEP` (`iwlmld-$(CONFIG_PM_SLEEP) += d3.o`). Intel WiFi 7 /
MLD hardware. Not a syscall fuzz path; **laptop suspend/resume**.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: MVM `mvm/d3.c` already applied IV/ICV + size check. MLD was a
port that omitted that logic.

---

## PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: **Yes.** Tree is `v7.3-rc4-27-gf0100363d8c37` / `7.3.0-rc4`.
File `drivers/net/wireless/intel/iwlwifi/mld/d3.c` exists. Bug present
from v6.15 (`d1e879ec600f9`) until this fix. `git merge-base --is-
ancestor d1e879ec600f9 HEAD` is true. `v7.2` has MLD but **not** this
fix (`c5cb9dd220ba9` is not an ancestor of `v7.2`).

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: **Clean apply** on this tree. Surrounding
`iwl_mld_set_wake_packet()` matches the parent hunk. `IWL_FW_CHECK`
already used in this file.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: `c5aeb11489150` is in HEAD (notif length). No alternate fix for
IV/ICV in MLD `set_wake_packet`.

---

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: SUBSYSTEM AND CRITICALITY**
Record: **drivers/net/wireless/intel/iwlwifi/mld** — **IMPORTANT** (not
core mm/fs, but a widely used Intel WiFi opmode for current silicon).
WoWLAN is a production laptop path.

**Step 7.2: SUBSYSTEM ACTIVITY**
Record: **Active.** Many 2026 iwlwifi mld/mvm firmware-validation fixes.
Mature enough that MVM already had this logic; MLD lagged.

---

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: WHO IS AFFECTED**
Record: **Driver-specific / config-specific:** `CONFIG_IWLMLD=y/m` +
`CONFIG_PM_SLEEP`, Intel MLD firmware devices, WoWLAN users.

**Step 8.2: TRIGGER CONDITIONS**
Record:
- Common functional bug: WoWLAN wakeup by a **protected data frame**
  (typical on WPA2/WPA3). Unprivileged users do not inject firmware
  notifications; they can suspend with wowlan.
- Memory-safety path: truncated/malformed `WOWLAN_WAKE_PKT` notification
  (buggy firmware or short DMA). Intel FW is signed, so this is
  robustness vs. firmware bugs, not a generic local exploit.
- How common: every encrypted wake-packet resume hits the IV/ICV miss;
  overflow needs a short/inconsistent notification.

**Step 8.3: FAILURE MODE SEVERITY**
Record:
- Short buffer + `skb_put_data(hdrlen)` → **skb over-panic / OOB** —
  **HIGH**
- Signed underflow into `skb_put_data` → **memory corruption** —
  **HIGH**
- Unchecked header parse → **OOB read** — **HIGH**
- Wrong/missing wakeup packet to cfg80211 — **MEDIUM** (userspace WoWLAN
  diagnostics)

**Step 8.4: RISK-BENEFIT RATIO**
Record: **Benefit: high** for Intel MLD WoWLAN (crash/corruption
avoided, correct packet). **Risk: low** (one file, ~60 lines, same
pattern as MVM, wiphy lock already held). Ratio favors backport.

---

## PHASE 9: FINAL SYNTHESIS

**Step 9.1: COMPILE THE EVIDENCE**

**FOR:**
- Real underflow/OOB in firmware wake-packet parsing (`skb_put` /
  `memcpy`)
- Protected-frame IV/ICV omitted since iwlmld was added (v6.15)
- Same logic already used and proven in MVM `d3.c`
- Small, one file, no new APIs
- Maintainer-authored and maintainer-committed
- Standalone (1/8 of a mixed series, no deps on the rest)
- Code exists in this 7.3-rc4 tree; `IWL_FW_CHECK` and
  `ieee80211_iter_keys` already used on this path

**AGAINST:**
- No user `Reported-by` / syzbot
- WoWLAN-only; overflow needs a bad/truncated notification
- ~57 lines, new helper (still contained)
- Cover letter mixed fixes with features (this patch itself is a fix)

**UNRESOLVED:**
- lore.kernel.org HTTP 403; no extra review mail beyond the b4 mbox
- Whether stable@ already discussed it

**Step 9.2: STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — mirrors MVM; maintainer SOB;
   used `IWL_FW_CHECK` consistently
2. Fixes a real bug that affects users? **PASS** — wrong crypto
   stripping on encrypted wake packets; OOB on short buffers
3. Important issue? **PASS** — skb overflow / underflow is crash or
   memory corruption; HIGH
4. Small and contained? **PASS** — one file, +57/−6
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — file and helpers present,
   hunk matches

**Step 9.3: EXCEPTION CATEGORIES**
Record: None (not a device ID/quirk/DT/build/doc exception). Ordinary
driver bugfix.

**Step 9.4: DECISION**
This tree has the buggy MLD D3 path. The patch is a small, correct fix
for integer underflow and bad wake-packet trimming. It should be applied
here.

---

### What the commit solves for users of this tree

On Intel MLD (WiFi 7) WoWLAN resume, `iwl_mld_set_wake_packet()` treated
every data frame as having only a 4-byte FCS and never skipped 802.11
IV/ICV. Encrypted wake packets were mis-trimmed. Short or inconsistent
firmware notifications could make `pkt_bufsize` go negative (`int`) and
then be passed to `skb_put_data(..., unsigned int)`, or `skb_put` more
than `alloc_skb` reserved — kernel panic or memory corruption. The patch
adds per-key IV/ICV (via `ieee80211_iter_keys`) and `IWL_FW_CHECK` size
guards, matching MVM.

### Risk vs benefit

Low risk: one file, existing primitives, wiphy lock already asserted.
Benefit: avoid resume-path memory corruption and deliver a correct
wakeup packet on encrypted networks.

### Concerns

No external reproducer; trigger for the overflow is a truncated FW
notification. The IV/ICV miss still hits normal encrypted WoWLAN. No
series dependency. Apply is clean on this tree.

---

### Verification
- **[Phase 1]** Parsed commit `c5cb9dd220ba9`: SOB Grumbach + Korenblit;
  Link msgid; no Fixes/Reported-by/Cc:stable
- **[Phase 2]** Diff: `mld/d3.c` +57/−6; new key iterator; size checks;
  `int`→`u32`; IV/ICV from `key->iv_len`/`icv_len` (`u8` in
  `ieee80211_key_conf`)
- **[Phase 2]** Confirmed `skb_put_data()` uses `unsigned int len` and
  `skb_put()` (`include/linux/skbuff.h`)
- **[Phase 2]** Compared to `mvm/d3.c` ~1516–1555: same IV/ICV +
  `IWL_FW_CHECK` pattern
- **[Phase 3]** `git blame` on parent: buggy function from
  `d1e879ec600f9` (2025-02-16)
- **[Phase 3]** `git merge-base --is-ancestor d1e879ec600f9 HEAD` true;
  `c5cb9dd220ba9` not in `v7.2`; MLD present from `v6.15`
- **[Phase 3]** `c5aeb11489150` is ancestor, independent notif-length
  fix
- **[Phase 4]** `b4 dig -c/-a/-w/-m`: v1 1/8 iwlwifi-next; recipients
  Korenblit/Berg/linux-wireless; mbox has no replies/NAKs
- **[Phase 4]** WebFetch/curl lore: 403 — UNVERIFIED extra
  review/stable@ mail
- **[Phase 5]** Call chain: `ieee80211_reconfig` → `drv_resume` →
  `iwl_mld_wowlan_resume` (`lockdep_assert_wiphy`) →
  `iwl_mld_set_wake_packet`
- **[Phase 5]** `ieee80211_iter_keys` docs: wiphy mutex; already used in
  `iwl_mld_update_sec_keys()`
- **[Phase 6]** `git describe HEAD` → `v7.3-rc4-27-gf0100363d8c37`;
  `make kernelversion` → `7.3.0-rc4`; file present; `d3.o` behind
  `CONFIG_PM_SLEEP`
- **[Phase 7]** `CONFIG_IWLMLD` “Intel Wireless WiFi MLD Firmware
  support”
- **[Phase 8]** Failure mode verified from parent source: no
  `pkt_bufsize < sizeof(*hdr)` check; signed subtract then
  `skb_put_data`

**YES**

 drivers/net/wireless/intel/iwlwifi/mld/d3.c | 63 +++++++++++++++++++--
 1 file changed, 57 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/d3.c b/drivers/net/wireless/intel/iwlwifi/mld/d3.c
index 73fd4c69357ca..b75936125b46d 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/d3.c
@@ -53,6 +53,30 @@ struct iwl_mld_suspend_key_iter_data {
 	__le32 bigtk_cipher;
 };
 
+struct iwl_mld_wake_pkt_iter_data {
+	bool multicast;
+	u32 ivlen;
+	u32 icvlen;
+};
+
+static void
+iwl_mld_wake_pkt_key_iter(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+			  struct ieee80211_sta *sta,
+			  struct ieee80211_key_conf *key, void *_data)
+{
+	struct iwl_mld_wake_pkt_iter_data *data = _data;
+	bool is_group_key = !sta;
+
+	/* ignore anything that is not a PTK / GTK */
+	if (key->keyidx > 3)
+		return;
+	if (is_group_key != data->multicast)
+		return;
+
+	data->ivlen = key->iv_len;
+	data->icvlen = key->icv_len;
+}
+
 struct iwl_mld_mcast_key_data {
 	u8 key[WOWLAN_KEY_MAX_SIZE];
 	u8 len;
@@ -707,11 +731,17 @@ iwl_mld_set_wake_packet(struct iwl_mld *mld,
 			struct cfg80211_wowlan_wakeup *wakeup,
 			struct sk_buff **_pkt)
 {
-	int pkt_bufsize = wowlan_status->wake_packet_bufsize;
-	int expected_pktlen = wowlan_status->wake_packet_length;
+	u32 pkt_bufsize = wowlan_status->wake_packet_bufsize;
+	u32 expected_pktlen = wowlan_status->wake_packet_length;
 	const u8 *pktdata = wowlan_status->wake_packet;
 	const struct ieee80211_hdr *hdr = (const void *)pktdata;
-	int truncated = expected_pktlen - pkt_bufsize;
+	u32 truncated;
+
+	if (IWL_FW_CHECK(mld, pkt_bufsize < sizeof(*hdr),
+			 "pkt_bufsize is too short: %u\n", pkt_bufsize))
+		return;
+
+	truncated = expected_pktlen - pkt_bufsize;
 
 	if (ieee80211_is_data(hdr->frame_control)) {
 		int hdrlen = ieee80211_hdrlen(hdr->frame_control);
@@ -722,9 +752,18 @@ iwl_mld_set_wake_packet(struct iwl_mld *mld,
 		if (!pkt)
 			return;
 
-		skb_put_data(pkt, pktdata, hdrlen);
-		pktdata += hdrlen;
-		pkt_bufsize -= hdrlen;
+		if (ieee80211_has_protected(hdr->frame_control)) {
+			struct iwl_mld_wake_pkt_iter_data iter_data = {
+				.multicast =
+					is_multicast_ether_addr(hdr->addr1),
+			};
+
+			ieee80211_iter_keys(mld->hw, vif,
+					    iwl_mld_wake_pkt_key_iter,
+					    &iter_data);
+			ivlen = iter_data.ivlen;
+			icvlen += iter_data.icvlen;
+		}
 
 		/* if truncated, FCS/ICV is (partially) gone */
 		if (truncated >= icvlen) {
@@ -735,6 +774,13 @@ iwl_mld_set_wake_packet(struct iwl_mld *mld,
 			truncated = 0;
 		}
 
+		if (IWL_FW_CHECK(mld, pkt_bufsize <= hdrlen + ivlen + icvlen,
+				 "pkt_bufsize is too small %u\n", pkt_bufsize))
+			return;
+
+		skb_put_data(pkt, pktdata, hdrlen);
+		pktdata += hdrlen;
+		pkt_bufsize -= hdrlen;
 		pkt_bufsize -= ivlen + icvlen;
 		pktdata += ivlen;
 
@@ -756,6 +802,11 @@ iwl_mld_set_wake_packet(struct iwl_mld *mld,
 			fcslen -= truncated;
 			truncated = 0;
 		}
+
+		if (IWL_FW_CHECK(mld, pkt_bufsize <= fcslen,
+				 "pkt_bufsize is too small %u\n", pkt_bufsize))
+			return;
+
 		pkt_bufsize -= fcslen;
 		wakeup->packet = wowlan_status->wake_packet;
 		wakeup->packet_present_len = pkt_bufsize;
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18] wifi: iwlwifi: mld: Do not cleanup FW state when the device is dead
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (29 preceding siblings ...)
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: mld: validate wake packet crypto overhead Sasha Levin
@ 2026-10-19 13:51 ` Sasha Levin
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-5.10] wifi: p54: validate firmware record lengths Sasha Levin
                   ` (9 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:51 UTC (permalink / raw)
  To: patches, stable
  Cc: Ilan Peer, Miri Korenblit, Sasha Levin, linux-wireless,
	linux-kernel

From: Ilan Peer <ilan.peer@intel.com>

[ Upstream commit 1c031ac5a39ebcc3269eace8b606043adc398bfa ]

When a channel context is unassigned, there is a path to cleanup the FW
state in case of NON MLO connection: remove the link and add it again.
However, when the transport is dead, e.g., during device removal etc.,
this flow will fail and as a result the mld_vif->link[0] would be set to
NULL. Later, when the interface is removed, iwl_mld_remove_link() would
warn as the link is NULL.

Fix this by not doing the cleanup when the device is dead.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260715220243.89a0c44a72a3.I45cca8b84a25943d5771199af6b0155dbac77b58@changeid
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

Local tree is **Linux 7.3.0-rc4** (`v7.3-rc4-27-gf0100363d8c37`). The
candidate is `1c031ac5a39eb` and landed in `v7.3-rc1`. The iwlwifi MLD
path it fixes is present here (MLD since `v6.15-rc1`).

---

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: PARSE THE SUBJECT LINE**
Record: `[wifi: iwlwifi: mld:] [Do not / Fix] [skip non-MLO FW link
remove/re-add when the transport is dead]`

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
- `Signed-off-by: Ilan Peer <ilan.peer@intel.com>` (author)
- `Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>`
  (iwlwifi MLD maintainer)
- `Link: https://patch.msgid.link/20260715220243.89a0c44a72a3.I45cca8b84
  a25943d5771199af6b0155dbac77b58@changeid`
- No `Fixes:`, no `Reported-by:`, no `Tested-by:`, no `Reviewed-by:`, no
  `Acked-by:`, no `Cc: stable` (absence expected)

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** On non-MLO chanctx unassign, the driver remove/re-adds the
  link to reset FW state. If the transport is dead (device removal,
  etc.), that sequence fails and `mld_vif->link[0]` is left NULL.
- **Symptom:** Later `iwl_mld_remove_link()` during interface teardown
  hits `WARN_ON(!link)`.
- **Root cause:** FW cleanup is attempted after the device can no longer
  accept commands; the software link pointer is cleared on the failed
  re-add.
- **Version info:** none in the message. MLD itself dates to v6.15.

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not hidden. Explicitly a teardown bug: failed FW cleanup → NULL
link → `WARN_ON`.

---

## PHASE 2: DIFF ANALYSIS

**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `drivers/net/wireless/intel/iwlwifi/mld/mac80211.c` (+4 / −2)
- Function: `iwl_mld_unassign_vif_chanctx()`
- Scope: single-file surgical fix

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:
- **Before:** For non-MLO, non-AP, not associated, not in HW restart:
  always `iwl_mld_remove_link()` then `iwl_mld_add_link()`.
- **After:** Same, but also skip when `iwl_trans_is_dead(mld->trans)`.
- Path affected: chanctx unassign during device death / removal, not the
  normal associated-STA path (`WARN_ON_ONCE(vif->cfg.assoc)` already
  excludes that).

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record: **Logic / correctness** on a teardown path (NULL pointer →
`WARN_ON`).

Verified in `iwl_mld_remove_link()` / `iwl_mld_add_link()` in
`mld/link.c`:
1. `iwl_mld_remove_link()` always does
   `RCU_INIT_POINTER(mld_vif->link[link_id], NULL)` after the FW remove
   attempt.
2. `iwl_mld_add_link()` then talks to FW via `iwl_mld_add_link_to_fw()`.
   On failure it NULLs `mld_vif->link[]` again.
3. `iwl_mld_mac80211_remove_interface()` later calls
   `iwl_mld_remove_link(mld, &vif->bss_conf)`.
4. That function does `if (WARN_ON(!link || link->active)) return;`.

`iwl_trans_send_cmd()` also `WARN_ONCE`s if `trans->state !=
IWL_TRANS_FW_ALIVE`, so the skip can avoid extra warnings while sending
`LINK_CONFIG_CMD` on a dead device.

**Step 2.4: ASSESS THE FIX QUALITY**
Record:
- Obviously correct: same pattern as the existing
  `!mld->fw_status.in_hw_restart` skip.
- Minimal: one extra predicate using `iwl_trans_is_dead()` (present
  since v6.17).
- Regression risk is low: if the transport is dead, FW cleanup cannot
  succeed anyway.

---

## PHASE 3: GIT HISTORY INVESTIGATION

**Step 3.1: BLAME THE CHANGED LINES**
Record:
- Remove/re-add block introduced in `d1e879ec600f9` (“wifi: iwlwifi: add
  iwlmld sub-driver”, 2025-03-05) → first in **v6.15-rc1**.
- Dead-device check added by this candidate (`1c031ac5a39eb`,
  2026-07-16) → first in **v7.3-rc1**.

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No `Fixes:` tag. Buggy code is the original MLD unassign path,
not a later regression.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record: Nearby commits in the same iwlwifi-next pull are unrelated (FTM
abort, WoWLAN validation, mei overflow, etc.). No follow-up on this
exact condition after `1c031ac5a39eb`.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Ilan Peer is a regular Intel iwlwifi/MLD contributor. The patch
was committed by Miri Korenblit (MLD maintainer).

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record:
- Needs `iwl_trans_is_dead()` from `11c5cc9ec6d9e` (v6.17-rc1).
  **Present in this 7.3-rc4 tree.**
- Series membership (`14/15`) is packaging only; this hunk does not
  depend on the other 14 patches.
- Standalone: yes.

---

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- `b4 dig -c 1c031ac5a39eb`: https://patch.msgid.link/20260715220243.89a
  0c44a72a3.I45cca8b84a25943d5771199af6b0155dbac77b58@changeid
- Cover: `[PATCH iwlwifi-next 00/15] wifi: iwlwifi: updates -
  07-15-2026` — “Cleanups, features, and fixes from our internal tree.”
- `b4 dig -a`: single v1 series; committed version matches v1. No later
  revision.
- Mbox has 16 messages (cover + 15 patches). **No replies, NAKs, or
  review comments** on this patch.

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record (`b4 dig -w`): To/Cc were Miri Korenblit, Johannes Berg
(`johannes@sipsolutions.net`), `linux-wireless@vger.kernel.org`, Ilan
Peer. Maintainer-acked via Miri’s SOB; no public Reviewed-by.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: No `Reported-by` / bugzilla / syzbot. Looks like an internal
Intel find. Trigger is still concrete (dead transport during unassign).

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: Mixed 15-patch `iwlwifi-next` dump. This patch is self-contained
(only the unassign condition). Other series items are unrelated
mei/mvm/FTM/debug fixes.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: lore.kernel.org `/stable/` search blocked by Anubis (403).
**UNVERIFIED:** no confirmed prior stable-list discussion. b4/mbox
showed no `Cc: stable` and no reviewer nomination.

---

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1: IDENTIFY KEY FUNCTIONS**
Record: `iwl_mld_unassign_vif_chanctx` (modified). Callees of the
skipped block: `iwl_mld_remove_link`, `iwl_mld_add_link`. Later WARN
site: `iwl_mld_remove_link` from `iwl_mld_mac80211_remove_interface`.

**Step 5.2: TRACE CALLERS**
Record:
- mac80211 op `.unassign_vif_chanctx` (mac80211 core on vif/chanctx
  unbind — ifdown, disconnect, unbind, restart).
- `iwl_mld_switch_vif_chanctx_swap` /
  `iwl_mld_switch_vif_chanctx_reassign` (CSA/channel switch).

**Step 5.3: TRACE CALLEES**
Record: deactivate link, optional monitor sta removal, TLC phy update,
then optional remove/re-add. Remove/re-add issue `LINK_CONFIG_CMD` via
`iwl_mld_send_cmd` → `iwl_trans_send_cmd`.

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: Userspace-reachable: bring down `wlan0`, `rmmod iwlwifi`, PCI
unbind/reset. `STATUS_TRANS_DEAD` is set in `iwl_trans_pcie_reset()`
during PCI removal. Config: `CONFIG_IWLMLD` (BE200+ / Wi-Fi 7).

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: Same function already skips this cleanup on `in_hw_restart`.
`iwl_trans_is_dead()` is already used in `mld/mld.c`
(`iwl_mld_nic_error`). This is the same “don’t talk to a dead transport”
pattern.

---

## PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: **Yes.** `drivers/net/wireless/intel/iwlwifi/mld/mac80211.c`
`iwl_mld_unassign_vif_chanctx()` contains the remove/re-add path. Bug
present since v6.15; this checkout is 7.3-rc4.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: Clean apply. Surrounding condition matches the parent of
`1c031ac5a39eb`. Helper `iwl_trans_is_dead()` exists in `iwl-trans.h`.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: This is the only “cleanup FW state when the device is dead”
change on this path. `git merge-base --is-ancestor 1c031ac5a39eb HEAD`
is true because this is post-7.3-rc1 mainline; that is source presence,
not a reason to reject on merit.

---

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: `drivers/net/wireless/intel/iwlwifi/mld/` — Intel Wi-Fi 7
(BE200+) opmode. **IMPORTANT** (not core mm/net, but a widely shipped
wireless driver).

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: Actively developed (frequent MLD commits through 2026). The
buggy unassign cleanup has been there since the MLD introduction.

---

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: Users of Intel MLD devices (`CONFIG_IWLMLD`) with a non-MLO
interface, when the transport dies or the device is removed while a
chanctx is still assigned.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record: Device removal / PCI reset / unbind / `rmmod` with an active
non-MLO vif. Not every packet path; teardown is still a common
admin/user action. Unprivileged users typically cannot unbind PCI, but
can trigger iface down; the commit’s example is device removal.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record: `WARN_ON(!link)` in `iwl_mld_remove_link()` (stack dump,
`TAINT_WARN`; panic if `panic_on_warn`). Possible extra `WARN_ONCE` from
`iwl_trans_send_cmd()` for non-ALIVE state. Not a UAF or data-corruption
bug. **Severity: MEDIUM–HIGH** (WARN_ON on a real teardown path).

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record:
- **Benefit:** Stops a reproducible WARN_ON (and likely extra host-
  command WARNs) on Intel MLD device teardown.
- **Risk:** Very low — one boolean on an already-gated cleanup.
- **Ratio:** Favorable.

---

## PHASE 9: FINAL SYNTHESIS

**Step 9.1: COMPILE THE EVIDENCE**

**FOR:**
- Real teardown bug with a traced mechanism (failed remove/re-add → NULL
  `link[0]` → `WARN_ON`).
- WARN_ON is an explicit strong-yes class of fix.
- Four-line, obviously correct, same idea as the existing restart skip.
- MLD + `iwl_trans_is_dead()` exist in this 7.3-rc4 tree; patch applies
  cleanly.
- Intel Wi-Fi 7 hardware is in production laptops.

**AGAINST:**
- No public reporter/syzbot/`Fixes:` tag.
- Failure is WARN_ON, not oops/UAF/corruption by default.
- Sent in a mixed `iwlwifi-next` dump, not a dedicated -fixes mail.
- No mailing-list review comments (only maintainer SOB).

**UNRESOLVED:**
- Stable-list history (lore blocked).
- No independent user report found.

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — one predicate; in mainline
   since 7.3-rc1; maintainer SOB.
2. Fixes a real bug that affects users? **PASS** — WARN_ON on
   device/interface teardown for MLD hardware.
3. Important issue? **PASS** — WARN_ON on a reachable removal path (“oh,
   that’s not good” / WARN_ON class).
4. Small and contained? **PASS** — ~4 lines, one function.
5. No new features or APIs? **PASS** — uses existing
   `iwl_trans_is_dead()`.
6. Can apply to the local tree? **PASS** — code and helper are here;
   context matches.

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: None (not a device-ID/quirk/DT/build/doc exception). It is a
normal small driver bugfix.

**Step 9.4: MAKE YOUR DECISION**
This tree has the MLD unassign path. Skipping FW link recycle when the
transport is already dead prevents a real `WARN_ON` during removal, with
negligible regression risk.

---

## What the commit solves and why it matters here

On non-MLO Intel MLD interfaces, chanctx unassign recycles the FW link
(`remove` + `add`). If the transport is dead, `add` fails and
`mld_vif->link[0]` stays NULL. Interface removal then hits
`WARN_ON(!link)` in `iwl_mld_remove_link()`. Users see a kernel warning
(and a panic if `panic_on_warn` is set) when unbinding or resetting the
Wi-Fi device. This 7.3-rc4 tree includes that MLD code, so the fix
belongs here.

## Stable rules / risk vs benefit

The change is a one-condition skip, already used for HW restart, with no
API or behavior change for live devices. Benefit is avoiding teardown
WARNs on Intel Wi-Fi 7; risk is very low.

## Concerns

No `Fixes:`/`Reported-by`, and it rode in a mixed next-tree series.
Neither undercuts the code-level bug. Prerequisite `iwl_trans_is_dead()`
is already in this tree. No backport rework needed.

---

## Verification
- **[Phase 1]** Parsed tags: author Ilan Peer, SOB Miri Korenblit,
  msgid.link; no Fixes/Reported-by/Cc-stable.
- **[Phase 2]** Diff: +4/−2 in `iwl_mld_unassign_vif_chanctx`; adds
  `!iwl_trans_is_dead(mld->trans)`.
- **[Phase 2]** `iwl_mld_remove_link` always NULLs `mld_vif->link[]`;
  `iwl_mld_add_link` NULLs it again if `iwl_mld_add_link_to_fw` fails;
  `iwl_mld_remove_link` WARNs on NULL.
- **[Phase 2]** `iwl_trans_send_cmd` WARNs if `trans->state !=
  IWL_TRANS_FW_ALIVE`.
- **[Phase 3]** `git blame`: remove/re-add from `d1e879ec600f9`
  (v6.15-rc1); fix is `1c031ac5a39eb` (v7.3-rc1).
- **[Phase 3]** `git describe --contains --match 'v*'`: MLD
  `v6.15-rc1~...`; helper `11c5cc9ec6d9e` in `v6.17-rc1`; this commit
  `v7.3-rc1~...`.
- **[Phase 3]** `git merge-base --is-ancestor 1c031ac5a39eb HEAD` →
  ancestor (expected on 7.3-rc4).
- **[Phase 4]** `b4 dig -c`: lore/msgid thread; `-a`: v1 only; `-w`:
  Johannes Berg + linux-wireless; `-m`: 16 msgs, no replies/NAKs.
- **[Phase 4]** Cover letter: mixed “updates” series 14/15; this patch
  listed under Ilan Peer.
- **[Phase 4]** lore `/stable/` search: UNVERIFIED (Anubis 403).
  WebFetch lore: 403.
- **[Phase 5]** Callers: mac80211 `.unassign_vif_chanctx`, plus two
  `switch_vif_chanctx_*` helpers. Teardown via
  `iwl_mld_mac80211_remove_interface`.
- **[Phase 5]** `STATUS_TRANS_DEAD` set in `iwl_trans_pcie_reset()`
  (`pcie/gen1_2/trans.c`).
- **[Phase 6]** `git describe HEAD` / `make kernelversion`: **v7.3-rc4 /
  7.3.0-rc4**. Buggy MLD file present. `iwl_trans_is_dead()` present at
  `iwl-trans.h:1127`.
- **[Phase 8]** Failure mode: `WARN_ON(!link)` on iface removal after
  dead-transport unassign; severity MEDIUM–HIGH.
- **UNVERIFIED:** Prior discussion on the stable mailing list.

The fix is small, surgical, and meets the stable criteria for this tree.

**YES**

 drivers/net/wireless/intel/iwlwifi/mld/mac80211.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
index 5234229a070a7..4ea2d45d71e4e 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
@@ -1113,11 +1113,13 @@ void iwl_mld_unassign_vif_chanctx(struct ieee80211_hw *hw,
 	RCU_INIT_POINTER(mld_link->chan_ctx, NULL);
 
 	/* in the non-MLO case, remove/re-add the link to clean up FW state.
-	 * In MLO, it'll be done in drv_change_vif_link
+	 * In MLO, it'll be done in drv_change_vif_link.
+	 * Do not do so during restart or in case the device is dead.
 	 */
 	if (!ieee80211_vif_is_mld(vif) && !mld_vif->ap_sta &&
 	    !WARN_ON_ONCE(vif->cfg.assoc) &&
-	    vif->type != NL80211_IFTYPE_AP && !mld->fw_status.in_hw_restart) {
+	    vif->type != NL80211_IFTYPE_AP && !mld->fw_status.in_hw_restart &&
+	    !iwl_trans_is_dead(mld->trans)) {
 		iwl_mld_remove_link(mld, link);
 		iwl_mld_add_link(mld, link);
 	}
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] wifi: p54: validate firmware record lengths
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (30 preceding siblings ...)
  2026-10-19 13:51 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: mld: Do not cleanup FW state when the device is dead Sasha Levin
@ 2026-10-19 13:52 ` Sasha Levin
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: mld: drop connection on D3 resume failure Sasha Levin
                   ` (8 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:52 UTC (permalink / raw)
  To: patches, stable
  Cc: Heyang Tan, Christian Lamparter, Johannes Berg, Sasha Levin,
	chunkeey, linux-wireless, linux-kernel

From: Heyang Tan <thy15333007817@163.com>

[ Upstream commit db7b86bd97b380ece8fa39cfdd7502a9fd35e56f ]

The p54 firmware parser accesses component ID and component version
records without checking that their lengths cover the fields being read.
A malformed record can therefore make the parser read past the record.

Validate the component ID and component version record lengths before
accessing their data. The descriptor record is also checked against the
shortest descriptor length found in the supported firmware images.

Reject descriptor values that underflow the RX offset or produce an empty
RX range before updating the driver state.

Assisted-by: LLM Codex
Signed-off-by: Heyang Tan <thy15333007817@163.com>
Tested-by: Christian Lamparter <chunkeey@gmail.com>
Link: https://patch.msgid.link/20260918083349.891-1-thy15333007817@163.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **6.18.57**. The p54 firmware parser here still lacks
record-length checks, so this is a real bounds-check fix for this
series.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

Step 1.1: PARSE THE SUBJECT LINE
Record: `[wifi: p54:] [validate] firmware record lengths` — wireless p54
firmware parser; “validate” is a correctness/safety fix, not a feature.

Step 1.2: PARSE ALL COMMIT MESSAGE TAGS
Record:
- `Assisted-by: LLM Codex`
- `Signed-off-by: Heyang Tan <thy15333007817@163.com>` (author)
- `Tested-by: Christian Lamparter <chunkeey@gmail.com>` (original p54
  author; hardware test)
- `Link:
  https://patch.msgid.link/20260918083349.891-1-thy15333007817@163.com`
- `Signed-off-by: Johannes Berg <johannes.berg@intel.com>` (wireless
  maintainer)
- Pipeline-only (ignored): `[Upstream commit
  db7b86bd97b380ece8fa39cfdd7502a9fd35e56f]`, `Signed-off-by: Sasha
  Levin`
- No `Fixes:`, no `Cc: stable` (expected)
- No `Reported-by:`, no syzbot tag on the commit itself

Step 1.3: ANALYZE THE COMMIT BODY TEXT
Record:
- Bug: component ID and component version records are used without
  checking that `len` covers the fields read. A short record can make
  the parser read past the record.
- Extra: descriptor records are checked against the shortest known valid
  length (`0xa` words). Descriptor RX values that underflow `0x3500` or
  produce an empty RX window are rejected before driver state is
  updated.
- Symptom: out-of-bounds read of the firmware blob; invalid
  `rx_start`/`rx_end` (the old code even had `/* FIXME add sanity
  checking */`).
- Version info: none in the message. The parser dates to 2009 in this
  tree.

Step 1.4: DETECT HIDDEN BUG FIXES
Record: Not hidden. Explicit bounds and range checks. The descriptor
work implements the old FIXME.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

Step 2.1: INVENTORY THE CHANGES
Record:
- File: `drivers/net/wireless/intersil/p54/fwio.c` (+37 / −5)
- Function: `p54_parse_firmware()`
- Scope: single-file surgical fix

Step 2.2: UNDERSTAND THE CODE FLOW CHANGE
Record:
- `BR_CODE_COMPONENT_ID`: previously `be32_to_cpup(bootrec->data)` with
  no length check. After: reject if `len < sizeof(struct
  bootrec_comp_id)/sizeof(*bootrec->data)` i.e. `len < 1`.
- `BR_CODE_COMPONENT_VERSION`: previously `strnlen(..., 24)` even for a
  short record. After: require `len >= DIV_ROUND_UP(24, 4)` (= 6 words),
  then `strnlen` limited to `sizeof(struct bootrec_comp_ver)` (still 24;
  no functional change for valid records).
- `BR_CODE_DESCR`: previously stored `rx_start` and `rx_end - 0x3500`
  with an explicit FIXME. After: require `len >= 0xa`; compute
  `rx_start`/`rx_end` locally; reject if `rx_end < 0x3500` or `rx_end -
  0x3500 <= rx_start`; only then write `priv->rx_start` /
  `priv->rx_end`.

`len` is in **u32 words**, matching the existing loop `bootrec->data +
len <= end_data`.

Step 2.3: IDENTIFY THE BUG MECHANISM
Record:
- Category: memory safety (OOB read) + integer underflow / invalid RX
  window.
- Mechanism: the outer loop only keeps the *declared* record inside the
  blob. If `len` is 0 and the record is at the end,
  `be32_to_cpup(bootrec->data)` reads `*end_data` (past the firmware).
  `strnlen(..., 24)` can read up to 24 bytes past a short version
  record. `rx_end - 0x3500` wraps if `rx_end < 0x3500`;
  `p54_assign_address()` then uses that window as firmware memory.

Step 2.4: ASSESS THE FIX QUALITY
Record:
- Obviously correct for the OOB: don’t read fields the record does not
  contain.
- `len < 0xa` matches the packed descriptor through `padding2` (40 bytes
  / 10 words); `rx_mtu` remains gated on `len == 11`.
- Regression risk is low: checks only reject truncated/inconsistent
  records. Christian Lamparter tested PCI and USB, including firmware
  down to 2.5.2.0.
- Reviewer nits on v2 (`len != 1` vs `len < 1`, local `bootrec_comp_ver
  *`) are style; he called v2 “technically correct.” A later v3 only
  restyles the same checks and is not in this tree. v2 is what Johannes
  merged.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

Step 3.1: BLAME THE CHANGED LINES
Record: Unchecked parser body is from `76074e1670b197` (“p54: Move
firmware code”, 2009-06-23, Christian Lamparter). Present in this tree
(`git merge-base --is-ancestor` succeeded). The logic is older than that
(original p54 driver `eff1a59c48e3`, also in this tree).

Step 3.2: FOLLOW THE FIXES: TAG
Record: No `Fixes:` tag. N/A. Introducer is the 2009 move / original
2007 driver, both ancestors of HEAD.

Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES
Record (same directory, already in this tree):
- `da1b9a55ff116` / `d38f5d868a0a4`: p54 EEPROM/RX length checks
  (malicious USB / KASAN)
- `3bdcc4d61212b` / `d2fb6b588dc5b`: p54 EEPROM/PDA length checks (`Cc:
  stable`)
This patch is standalone, not patch X/Y. It does not depend on those
EEPROM fixes.

Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS
Record: Heyang Tan has this p54 fix and an unrelated octeontx2 debugfs
change. Not the subsystem maintainer. Weight comes from Christian’s
Tested-by and Johannes’s SOB.

Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS
Record: No new helpers or structs. Uses existing `bootrec_comp_id`,
`bootrec_comp_ver`, `bootrec_desc`. Standalone. `git diff v6.18.57
ac2ff9b564e82^ -- fwio.c` is empty, so it applies cleanly to this
series.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION
Record:
- `b4 dig -c db7b86bd97b380ece8fa39cfdd7502a9fd35e56f` →
  https://patch.msgid.link/20260918083349.891-1-thy15333007817@163.com
- Series: v2 submitted 2026-09-18 (this is the committed version).
- Christian Lamparter, 2026-09-19: tested USB (`isl3887usb` LM87) and
  PCI (LM86), plus older 2.5.2.0 firmware; `Tested-by`. Called the
  `sizeof`/`DIV_ROUND_UP` checks “technically correct”; asked for
  readability (`len != 1`, local version pointer). No NAK.
- v3 (2026-10-09) is that style follow-up (`len != 1`, `len < 6`, local
  pointer). Not the merged commit.
- Syzbot CI on v2: KASAN build/boot/fuzz passed (no new findings).
- Direct lore.kernel.org fetch returned 403; thread recovered via `b4
  dig -m`.

Step 4.2: CHECK WHO REVIEWED THE PATCH
Record (`b4 dig -w`): To `linux-wireless@`, Cc Christian Lamparter.
Johannes Berg merged it. Christian is the long-time p54 author.

Step 4.3: SEARCH FOR THE BUG REPORT
Record: No syzbot/bugzilla `Reported-by` on this commit. Bug is from
code inspection. Author later asked whether a CVE is appropriate (OOB
firmware parser). Christian’s answer to that CVE question was not
retrieved (UNVERIFIED). Practical trigger is a malformed firmware file,
not a BadUSB frame.

Step 4.4: CHECK FOR RELATED PATCHES AND SERIES
Record: Standalone v2. v3 is cosmetic and unmerged here. Related p54
length-check work is EEPROM/PDA, already in this tree.

Step 4.5: CHECK STABLE MAILING LIST HISTORY
Record: No useful `lore.kernel.org/stable` hit for this subject. No
known “do not backport” discussion.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF
Record: `p54_parse_firmware()` only.

Step 5.2: TRACE CALLERS
Record:
- `p54pci.c`: after firmware request, before upload
- `p54usb.c`: `p54u_start_ops()` after firmware load
- `p54spi.c`: `p54spi_request_firmware()` (`"3826.arm"`)
All probe/firmware-load paths, not the datapath.

Step 5.3: TRACE CALLEES
Record: `le32_to_cpu` / `be32_to_cpup` / `strnlen` / `wiphy_err`.
Descriptor fields feed `priv->rx_start`, `priv->rx_end`, `headroom`,
`tailroom`, `privacy_caps`, `rx_keycache_size`, `rx_mtu`.

Step 5.4: FOLLOW THE CALL CHAIN
Record: USB/PCI/SPI probe → `request_firmware[_nowait]` →
`p54_parse_firmware`. Reachable whenever p54 hardware is present and
firmware is loaded. Firmware comes from the host (`isl3886pci`,
`isl3887usb`, `3826.arm`, etc.), not from the USB packet stream.
Unprivileged users normally cannot plant that file; a bad file still
oopses/reads OOB in kernel.

Step 5.5: SEARCH FOR SIMILAR PATTERNS
Record: Same class as the p54 EEPROM/PDA length checks already in this
tree. `BR_CODE_EXPOSED_IF` in this same function still walks `exp_if`
from `len` without a per-record fit check; that is a leftover, not a
reason to drop this hunk.

===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================

Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?
Record: Yes. This checkout is `v6.18.57-155-gcdf239ca885b2`,
kernelversion `6.18.57`.
`v6.18.57:drivers/net/wireless/intersil/p54/fwio.c` still does
unvalidated `be32_to_cpup`, `strnlen(..., 24)`, and `rx_end - 0x3500`
with the FIXME. Bug introduced ~2009, long before 6.18.

Step 6.2: CHECK FOR BACKPORT COMPLICATIONS
Record: Clean apply. Pre-candidate `fwio.c` matches `v6.18.57`. No
refactor between mainline context and this series.

Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE
Record: EEPROM/PDA validation is already here; it does not cover this
firmware bootrec parser. No earlier version of this exact fix in
6.18.57.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY
Record: `drivers/net/wireless/intersil/p54` — old
Prism54/ISL38xx/STLC45xx (USB/PCI and Nokia N800/N810 SPI). Criticality:
PERIPHERAL, but real hardware and already-supported in 6.18.

Step 7.2: ASSESS SUBSYSTEM ACTIVITY
Record: Mature/low churn. Recent work is mostly bounds checks. A long-
standing parser hole is more, not less, relevant for stable.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

Step 8.1: DETERMINE WHO IS AFFECTED
Record: Users with p54 USB/PCI/SPI (`CONFIG_P54_*`) and a malformed or
truncated firmware image.

Step 8.2: DETERMINE THE TRIGGER CONDITIONS
Record: Device probe / firmware load. Common with p54 hardware; the
*malformed* case is uncommon (bad file, truncated image, attacker-
controlled firmware path). Not a hot-path race. Unprivileged trigger is
limited (firmware is host-provided).

Step 8.3: DETERMINE THE FAILURE MODE SEVERITY
Record:
- Short records near the end of the blob: kernel OOB read (KASAN-class).
  Severity HIGH for memory safety; practical exploitability is lower
  than the USB EEPROM bugs.
- `rx_end` underflow: wrapped firmware memory window used by
  `p54_assign_address()` / `p54_setup_mac()`. Severity MEDIUM–HIGH for
  driver malfunction / bad device addresses.
- Overall: HIGH memory-safety, not a universal panic on valid vendor
  firmware.

Step 8.4: CALCULATE RISK-BENEFIT RATIO
Record:
- Benefit: stops OOB reads and bogus RX windows on a parser this tree
  has had since 2009; same robustness class as p54 fixes already in
  6.18.y.
- Risk: ~40-line, error-path-only; hardware-tested; no API change.
- Ratio: favorable.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

Step 9.1: COMPILE THE EVIDENCE

FOR:
- Real OOB read in `p54_parse_firmware()` plus RX-range underflow the
  original code flagged with FIXME.
- Small, contained, no new API.
- Present in this 6.18 tree for ~17 years; applies cleanly.
- Tested-by original p54 author on PCI and USB, including old firmware.
- Merged by Johannes Berg.
- Same validation pattern as other p54 stable fixes already here.

AGAINST:
- Niche driver; trigger is a bad firmware file, not a malicious URB.
- No syzbot/CVE on this specific patch.
- v3 is a later style tweak (not a functional hole in v2).

UNRESOLVED:
- Christian’s reply on CVE classification not retrieved.
- lore.kernel.org HTTP fetch 403; thread obtained via b4 instead.

Step 9.2: APPLY THE STABLE RULES CHECKLIST
1. Obviously correct and tested? **PASS** — reviewer called v2
   technically correct; Tested-by on real devices.
2. Fixes a real bug that affects users? **PASS** — OOB read and invalid
   RX window on malformed firmware.
3. Important issue (crash, security, corruption, deadlock)? **PASS** —
   kernel OOB read / firmware-parser memory safety (HIGH). Not a
   universal oops on good firmware, but this class is accepted for
   stable.
4. Small and contained? **PASS** — one function, +37/−5.
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — identical pre-image to
   v6.18.57 `fwio.c`.

Step 9.3: CHECK FOR EXCEPTION CATEGORIES
Record: None (not a device ID, quirk, DT, build, or doc fix). Qualifies
as a normal bugfix.

Step 9.4: MAKE YOUR DECISION
Backport. The 6.18 parser still has the hole; the fix is small, tested,
and addresses a real OOB/underflow without depending on later refactors.

What it solves for this tree: `p54_parse_firmware()` can read past a
truncated component-ID/version record and can wrap `rx_end`. That hits
USB/PCI/SPI probe when firmware is loaded. Stable rules are met; risk is
low because valid images were tested and only invalid records are
rejected.

Verification:
- [Phase 1] Tags: Tested-by Christian Lamparter; SOB Johannes Berg; Link
  msgid 20260918083349.891-1; no Fixes/Cc:stable/Reported-by (expected).
- [Phase 2] Diff: +37/−5 in `p54_parse_firmware()`; ID `len < 1`,
  version `len < 6`, descriptor `len < 0xa` plus RX-range check.
  `bootrec_desc` packed size 42 bytes; `0xa` words covers fields used
  when `len != 11`.
- [Phase 3] `git blame` on parent: `76074e1670b197` (2009). `git merge-
  base --is-ancestor 76074e1670b197 HEAD` succeeded. No Fixes tag.
- [Phase 3] Related p54 length checks (`da1b9a55ff116`, `d38f5d868a0a4`,
  `3bdcc4d61212b`, `d2fb6b588dc5b`) are EEPROM/PDA, not this parser.
- [Phase 4] `b4 dig -c db7b86bd97b380ece8fa39cfdd7502a9fd35e56f`: v2
  lore thread; `-a` only v2 as committed series; `-w` linux-wireless +
  chunkeey. Christian: “technically correct” + Tested-by PCI/USB.
- [Phase 4] WebSearch: v3 is style-only; syzbot CI passed v2.
  lore.kernel.org WebFetch 403.
- [Phase 4] UNVERIFIED: Christian’s CVE-classification reply.
- [Phase 5] Callers: `p54pci.c:79`, `p54usb.c:872`, `p54spi.c:166` on
  firmware load. `rx_end` used in `p54_assign_address()` /
  `p54_setup_mac()`.
- [Phase 6] `git describe HEAD` → `v6.18.57-155-gcdf239ca885b2`; `make
  kernelversion` → `6.18.57`. Buggy code in
  `v6.18.57:drivers/net/wireless/intersil/p54/fwio.c`. `git diff
  v6.18.57 ac2ff9b564e82^ -- fwio.c` empty.
- [Phase 8] Failure mode: OOB read of firmware blob; wrapped RX window.
  Severity HIGH for memory safety, driver-specific trigger.

**YES**

 drivers/net/wireless/intersil/p54/fwio.c | 42 +++++++++++++++++++++---
 1 file changed, 37 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/intersil/p54/fwio.c b/drivers/net/wireless/intersil/p54/fwio.c
index 3baf8ab01e22b..4b8e6cf711d8f 100644
--- a/drivers/net/wireless/intersil/p54/fwio.c
+++ b/drivers/net/wireless/intersil/p54/fwio.c
@@ -52,6 +52,13 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
 		u32 code = le32_to_cpu(bootrec->code);
 		switch (code) {
 		case BR_CODE_COMPONENT_ID:
+			if (len < sizeof(struct bootrec_comp_id) /
+				sizeof(*bootrec->data)) {
+				wiphy_err(priv->hw->wiphy,
+					  "firmware component ID is too short\n");
+				return -EINVAL;
+			}
+
 			priv->fw_interface = be32_to_cpup((__be32 *)
 					     bootrec->data);
 			switch (priv->fw_interface) {
@@ -72,16 +79,41 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
 			}
 			break;
 		case BR_CODE_COMPONENT_VERSION:
+			if (len < DIV_ROUND_UP(sizeof(struct bootrec_comp_ver),
+					       sizeof(*bootrec->data))) {
+				wiphy_err(priv->hw->wiphy,
+					  "firmware component version is too short\n");
+				return -EINVAL;
+			}
+
 			/* 24 bytes should be enough for all firmwares */
-			if (strnlen((unsigned char *) bootrec->data, 24) < 24)
-				fw_version = (unsigned char *) bootrec->data;
+			if (strnlen((unsigned char *)bootrec->data,
+				    sizeof(struct bootrec_comp_ver)) <
+				    sizeof(struct bootrec_comp_ver))
+				fw_version = (unsigned char *)bootrec->data;
 			break;
 		case BR_CODE_DESCR: {
 			struct bootrec_desc *desc =
 				(struct bootrec_desc *)bootrec->data;
-			priv->rx_start = le32_to_cpu(desc->rx_start);
-			/* FIXME add sanity checking */
-			priv->rx_end = le32_to_cpu(desc->rx_end) - 0x3500;
+			u32 rx_start, rx_end;
+
+			/* 0xa is the shortest descriptor in supported firmware. */
+			if (len < 0xa) {
+				wiphy_err(priv->hw->wiphy,
+					  "firmware descriptor is too short\n");
+				return -EINVAL;
+			}
+
+			rx_start = le32_to_cpu(desc->rx_start);
+			rx_end = le32_to_cpu(desc->rx_end);
+			if (rx_end < 0x3500 || rx_end - 0x3500 <= rx_start) {
+				wiphy_err(priv->hw->wiphy,
+					  "firmware descriptor has invalid RX range\n");
+				return -EINVAL;
+			}
+
+			priv->rx_start = rx_start;
+			priv->rx_end = rx_end - 0x3500;
 			priv->headroom = desc->headroom;
 			priv->tailroom = desc->tailroom;
 			priv->privacy_caps = desc->privacy_caps;
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18] wifi: iwlwifi: mld: drop connection on D3 resume failure
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (31 preceding siblings ...)
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-5.10] wifi: p54: validate firmware record lengths Sasha Levin
@ 2026-10-19 13:52 ` Sasha Levin
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-6.6] wifi: wilc1000: validate monitor transmit frame headers Sasha Levin
                   ` (7 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:52 UTC (permalink / raw)
  To: patches, stable
  Cc: Ayala Beker, Emmanuel Grumbach, Miri Korenblit, Sasha Levin,
	linux-wireless, linux-kernel

From: Ayala Beker <ayala.beker@intel.com>

[ Upstream commit 4f5384b58b483e4aec576ce461dec45b41df18db ]

When FW crashes on D3 exit, iwl_mld_nic_error() sets
STATUS_RESET_PENDING and queues restart wk, but mac80211's resume
callback synchronously calls iwl_trans_stop_device() which clears
the flag. As a result restart wk skips sw_reset, and the FW error
recovery buffer is never read.

The new FW boots with empty BA state and initial sequence numbers,
while the AP still holds its A-MPDU RX reorder window.
This causes MPDUs to be dropped as IWL_RX_MPDU_REORDER_BA_OLD_SN until
ADDBA is renegotiated.

We don't know how long the firmware has been in an error state
or whether the AP still considers us associated, so keeping the
connection alive is not worth it.
Call ieee80211_resume_disconnect() when iwl_mld_wait_d3_notif() fails,
and let userspace reassociate.

Signed-off-by: Ayala Beker <ayala.beker@intel.com>
Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Link: https://patch.msgid.link/20260717172958.3e10c8498f53.Icf5644b42d79e984ecc16abfa873bd37f611e778@changeid
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

This is a real WoWLAN resume recovery bug in `iwlwifi` MLD: after a
firmware crash on D3 exit the driver keeps the association, so traffic
is dropped. The local tree is **7.3.0-rc4**
(`v7.3-rc4-27-gf0100363d8c37`); the MLD D3 path exists here, and the
three-line fix is self-contained.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

**Step 1.1: PARSE THE SUBJECT LINE**
Record: `[wifi: iwlwifi: mld:] [drop] [drop the association when
D3/WoWLAN resume fails to get firmware notifications]`

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- `Fixes:` — none (expected; not a negative signal)
- `Reported-by:` — none
- `Tested-by:` — none
- `Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>`
  (iwlwifi maintainer)
- `Acked-by:` — none
- `Link: https://patch.msgid.link/20260717172958.3e10c8498f53.Icf5644b42
  d79e984ecc16abfa873bd37f611e778@changeid`
- `Cc: stable@vger.kernel.org` — none (expected)
- `Signed-off-by: Ayala Beker <ayala.beker@intel.com>` (author)
- `Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>`
  (iwlwifi-next maintainer)
- No syzbot / kernel test robot tags

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** Firmware crash on D3 exit. `iwl_trans_fw_error()` →
  `iwl_trans_schedule_reset()` sets `STATUS_RESET_PENDING` and queues
  restart work. mac80211 resume then calls `iwl_trans_stop_device()`,
  which clears that flag, so restart work skips SW reset and never reads
  the FW error recovery buffer.
- **Symptom:** New firmware boots with empty BA state / initial SNs
  while the AP still has its A-MPDU RX reorder window. RX MPDUs are
  dropped as `IWL_RX_MPDU_REORDER_BA_OLD_SN` until ADDBA is
  renegotiated. Association state with the AP is also unknown.
- **Version info:** none in the message. MLD D3 code has existed since
  the MLD driver was added (in this history: `d1e879ec600f9`, present by
  v6.15).
- **Root cause (author):** keep-alive after a failed D3 resume is not
  safe; disconnect and let userspace reassociate.

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not a hidden cleanup. Explicit recovery/correctness fix for a
broken post-resume connection.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `drivers/net/wireless/intel/iwlwifi/mld/d3.c` (+3 / −0)
- Function: `iwl_mld_wowlan_resume()`
- Scope: single-file surgical fix (3 lines on the existing error path)

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record: Before, `iwl_mld_wait_d3_notif()` failure logged `"Couldn't get
the d3 notifs"` and `goto err`, which sets `in_hw_restart = true` and
returns `1`. mac80211 treats `1` as “full reconfig on wakeup” and
**keeps** the STA associated. After, if `bss_vif->cfg.assoc`, it also
calls `ieee80211_resume_disconnect(bss_vif)` so mac80211 tears the
connection down during resume reconfig. The same function already did
that on the success path when `keep_connection` is false.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record: `[Logic / correctness]` — failed D3 resume left a zombie
association. Firmware BA state is reset; AP reorder window is not.
`ieee80211_resume_disconnect()` sets
`IEEE80211_SDATA_DISCONNECT_RESUME`, taints keys, and
`ieee80211_sta_restart()` later calls `ieee80211_sta_connection_lost()`.
This matches MVM: `__iwl_mvm_resume()` always runs
`iwl_mvm_d3_disconnect_iter` unless `keep` is true (and `keep` stays
false on error).

**Step 2.4: ASSESS THE FIX QUALITY**
Record: Obviously correct and minimal. `ieee80211_resume_disconnect()`
is documented for the resume callback; `iwl_mld_wowlan_resume()` is
called only from `iwl_mld_resume()`. Must be used here rather than
`ieee80211_hw_restart_disconnect()`, which WARNs unless
`local->in_reconfig`. Guarded by `bss_vif->cfg.assoc`. Regression risk
is low: extra disconnect only when D3 notifs already failed, which is
already treated as a restart-needed error.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

**Step 3.1: BLAME THE CHANGED LINES**
Record: The `iwl_mld_wait_d3_notif()` error path comes from
`d1e879ec600f9` (“wifi: iwlwifi: add iwlmld sub-driver”, 2025-03-05).
Present in this tree; `git merge-base --is-ancestor d1e879ec600f9 v6.15`
succeeds. The bug is old relative to 7.3, not brand-new code.

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No `Fixes:` tag. Buggy behavior is the original MLD wowlan-
resume error path, not a later regression.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record: Recent `mld/d3.c` work is other WoWLAN validation (`validate
D3_END notif size`, `validate WoWLAN notif header`, wake-packet checks).
`ieee80211_resume_disconnect` on the *success* path was added in
`99f201a9a7d59` (keep_connection). No prerequisite refactor is required
for these three lines. No later commits on this file after
`4f5384b58b483`.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Ayala Beker is a regular Intel iwlwifi contributor (MVM and
MLD). Reviewed by Emmanuel Grumbach; applied by Miri Korenblit. Strong
maintainer signal.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: Submitted as **patch 4/8** of `iwlwifi-next` updates
(2026-07-17). Cover letter: “A couple of fixes, features and cleanups.”
Other patches (wake-packet validation, scan-abort init, MVM sync frames,
SAR define move, MCC v2, debug log, BIOS code move) do not change this
error path. Standalone: uses existing `ieee80211_resume_disconnect()`
and `bss_vif->cfg.assoc`.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record: `b4 dig -c 4f5384b58b483` → https://patch.msgid.link/20260717172
958.3e10c8498f53.Icf5644b42d79e984ecc16abfa873bd37f611e778@changeid
`b4 dig -a`: single v1 series, no v2/v3.
Mbox (`b4 dig -m`): 9 messages, cover + 8 patches, **no replies, NAKs,
or reviewer concerns**. `Reviewed-by: Emmanuel Grumbach` was already on
the submission. No `Cc: stable` in-thread.

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record: `b4 dig -w` recipients: Johannes Berg
(`johannes@sipsolutions.net`), `linux-wireless@vger.kernel.org`, Ayala
Beker, Emmanuel Grumbach, Miri Korenblit. Right maintainers/list.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: No `Reported-by` / bugzilla / syzbot. Bug is described from
driver/firmware analysis, not a public user report.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: Mixed iwlwifi-next dump; this hunk does not depend on 1–3 or
5–8.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: lore.kernel.org HTTP 403 from this environment. No stable-list
discussion verified. `b4` thread does not mention stable.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

**Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF**
Record: `iwl_mld_wowlan_resume()`; calls
`ieee80211_resume_disconnect()`.

**Step 5.2: TRACE CALLERS**
Record:
- `iwl_mld_wowlan_resume()` ← `iwl_mld_resume()` in `mld/mac80211.c`
  (mac80211 `.resume`)
- `iwl_mld_resume()` ← `drv_resume()` in `ieee80211_reconfig()` when
  `local->wowlan`
- `iwl_mld_wait_d3_notif()` also used by `iwl_mld_no_wowlan_resume()`;
  this patch does **not** change that path (no-wowlan resume is handled
  in `iwl_mld_mac80211_start()`; mac80211 already cleaned state)

**Step 5.3: TRACE CALLEES**
Record: `ieee80211_resume_disconnect()` →
`ieee80211_reconfig_disconnect(..., IEEE80211_SDATA_DISCONNECT_RESUME)`
→ set sdata flag + `KEY_FLAG_TAINTED`. Later `ieee80211_sta_restart()` →
`ieee80211_sta_connection_lost()`.

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: Userspace/system suspend with WoWLAN → resume →
`ieee80211_reconfig()` → `iwl_mld_resume()`. If wait for D3 notifs
fails, return 1 still triggers full reconfig **and** (with this patch)
disconnect. Reachable on laptops with Intel MLD (Wi-Fi 7) firmware and
WoWLAN. Unprivileged users do not trigger it directly; any user who
suspends the machine can.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: MVM already disconnects on D3 resume unless `keep` is true
(`iwl_mvm_d3_disconnect_iter`). Same `ieee80211_resume_disconnect()`
already used in this function when wowlan status says not to keep the
connection. MLD also has `iwl_mld_restart_disconnect_iter` for invalid
recovery blobs during `iwl_mld_send_recovery_cmd()` — a different path,
and it does not cover “recovery buffer never read.”

===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: Yes. Tree is **7.3.0-rc4**.
`drivers/net/wireless/intel/iwlwifi/mld/d3.c` and
`iwl_mld_wowlan_resume()` exist (`CONFIG_IWLMLD`). Error path introduced
with MLD (`d1e879ec600f9`, in v6.15+). `ieee80211_vif.cfg.assoc` exists
in this tree.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: Clean apply on this tree. Context around the wait-d3-notif error
path matches the hunk. No conflicting local changes.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: No other commit greps as an alternate fix for “D3 resume
failure” disconnect in MLD. MVM already had the equivalent behavior;
this fills the MLD gap.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: `[drivers/net/wireless/intel/iwlwifi/mld]` `[IMPORTANT]` — not
core mm/VFS, but Intel Wi-Fi 7 (MLD) on laptops; WoWLAN resume is a
common path.

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: Actively developed (frequent mld/d3.c changes). Bug is in
original wowlan-resume error handling, not a one-off new feature.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: Driver/config-specific: `CONFIG_IWLMLD` + `CONFIG_PM_SLEEP`,
Intel MLD firmware, WoWLAN enabled. Typical: recent Intel Wi-Fi 7
laptops.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record: Not every resume. Trigger is D3-exit firmware failure
(crash/timeout so D3 notifs never arrive). Timing-dependent around
firmware error vs resume `stop_device`. Not a syscall smash; any
suspend/resume with WoWLAN can hit it if FW dies on the way out of D3.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record: Not a panic. User-visible **broken Wi-Fi after sleep**:
interface still associated, MPDUs dropped as old SN, possible stale
association if the AP already dropped the client. Severity **HIGH**
(serious connectivity failure on a common laptop path), not CRITICAL (no
oops/deadlock/corruption).

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record: Benefit high for affected users (restores a clean reassociate
instead of a zombie session). Risk very low (3 lines, existing API,
error path only, same pattern as MVM and the local success path). Ratio
strongly favors applying it.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

**Step 9.1: COMPILE THE EVIDENCE**

FOR:
- Real post-resume connectivity bug (dropped MPDUs / unknown
  association), not style
- Matches MVM’s long-standing “disconnect unless keep” D3 resume
  behavior
- 3-line, obviously correct use of `ieee80211_resume_disconnect()` from
  the resume callback
- Reviewed by Emmanuel Grumbach; applied by Miri Korenblit; To: Johannes
  Berg
- Buggy path present in this 7.3 tree since MLD introduction
- Standalone; series-mates are unrelated
- Tiny error-path change; disconnect is conservative when firmware state
  is untrustworthy

AGAINST:
- No crash, UAF, or CVE; not every resume
- No user `Reported-by` / syzbot
- Mixed “fixes, features and cleanups” series (this patch itself is a
  fix)
- Lore HTTP 403; no independent stable-list confirmation

UNRESOLVED:
- Could not read lore/stable HTML (403). Thread contents were recovered
  via `b4 dig -m`.

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — uses the documented resume-
   disconnect API; maintainer Reviewed-by
2. Fixes a real bug that affects users? **PASS** — WoWLAN resume leaves
   a dead/stale association
3. Important issue? **PASS** — serious connectivity loss after suspend,
   not a panic but user-visible and persistent until reassoc/ADDBA
4. Small and contained? **PASS** — 3 lines, one function
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — MLD D3 resume code is here;
   context matches

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: None (not a device ID/quirk/DT/build/docs exception). Qualifies
as a normal bugfix.

**Step 9.4: MAKE YOUR DECISION**
The local 7.3 tree has the MLD wowlan-resume error path. Without this
change, a firmware crash on D3 exit keeps the mac80211 association
through reconfig while BA state is reset, so traffic dies until ADDBA.
Disconnect-on-failure is the same policy MVM already uses and is a
three-line, low-risk fix.

Verification:
- [Phase 1] Parsed tags: Reviewed-by Emmanuel Grumbach; Link msgid; no
  Fixes/Reported-by/Cc-stable
- [Phase 1] Body: FW D3-exit crash → reset flag cleared by
  `iwl_trans_stop_device()` → empty BA vs AP reorder window → OLD_SN
  drops
- [Phase 2] Diff: +3 lines in `iwl_mld_wowlan_resume()` after
  `iwl_mld_wait_d3_notif()` failure
- [Phase 2] Confirmed `goto err` already sets `in_hw_restart` and
  returns 1; mac80211 `drv_resume()` res==1 does full reconfig and keeps
  association
- [Phase 2] Confirmed success path already calls
  `ieee80211_resume_disconnect()` when `keep_connection` is false
  (`99f201a9a7d59`)
- [Phase 2] Confirmed MVM `__iwl_mvm_resume()` disconnects all STATION
  vifs unless `keep` (false on error)
- [Phase 3] `git describe HEAD` / `make kernelversion`: v7.3-rc4 /
  7.3.0-rc4
- [Phase 3] `git blame`: error path from `d1e879ec600f9` (MLD intro);
  `git merge-base --is-ancestor d1e879ec600f9 v6.15` true
- [Phase 3] `git merge-base --is-ancestor 4f5384b58b483 v7.2` false
  (landed in 7.3 cycle)
- [Phase 3] No Fixes tag; no later d3.c commits after this one
- [Phase 3] Series 4/8 of mixed iwlwifi-next; parent is unrelated MVM
  patch; standalone
- [Phase 3] `iwl_trans_fw_error()` → `iwl_trans_schedule_reset()` sets
  `STATUS_RESET_PENDING`; `iwl_trans_stop_device()` clears it — matches
  the described mechanism (nic_error itself sets `in_hw_restart`, not
  the bit)
- [Phase 4] `b4 dig -c`: lore msgid match; `b4 dig -a`: v1 only; `b4 dig
  -w`: Johannes + linux-wireless + Intel iwlwifi maintainers
- [Phase 4] mbox: 9 messages, no replies/NAKs; cover lists this as a fix
  among mixed patches
- [Phase 4] lore.kernel.org WebFetch/curl 403 — UNVERIFIED via HTML;
  thread recovered with b4
- [Phase 5] Callers: `iwl_mld_resume` ← mac80211 wowlan resume;
  `ieee80211_sta_restart` honors `IEEE80211_SDATA_DISCONNECT_RESUME`
- [Phase 5] `agg.c` drops frames when `IWL_RX_MPDU_REORDER_BA_OLD_SN` is
  set
- [Phase 6] File and `iwl_mld_wait_d3_notif` error path present;
  `bss_vif->cfg.assoc` valid in this tree
- [Phase 7] iwlwifi MLD, important for Intel Wi-Fi 7 laptops
- [Phase 8] Failure: zombie association / packet drops after suspend,
  severity HIGH; fix risk very low
- UNVERIFIED: public stable@ discussion (lore HTTP 403)

The patch is a small, maintainer-reviewed recovery fix for a real WoWLAN
resume failure on hardware this tree already supports.

**YES**

 drivers/net/wireless/intel/iwlwifi/mld/d3.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/d3.c b/drivers/net/wireless/intel/iwlwifi/mld/d3.c
index b75936125b46d..69d8afda9fcd9 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/d3.c
@@ -2077,6 +2077,9 @@ int iwl_mld_wowlan_resume(struct iwl_mld *mld)
 	ret = iwl_mld_wait_d3_notif(mld, &resume_data, true);
 	if (ret) {
 		IWL_ERR(mld, "Couldn't get the d3 notifs %d\n", ret);
+
+		if (bss_vif->cfg.assoc)
+			ieee80211_resume_disconnect(bss_vif);
 		goto err;
 	}
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18-6.6] wifi: wilc1000: validate monitor transmit frame headers
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (32 preceding siblings ...)
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: mld: drop connection on D3 resume failure Sasha Levin
@ 2026-10-19 13:52 ` Sasha Levin
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-5.10] iwlwifi: dvm: add missing cleaup for on error path Sasha Levin
                   ` (6 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:52 UTC (permalink / raw)
  To: patches, stable
  Cc: Mariano Baragiola, Johannes Berg, Sasha Levin, ajay.kathat,
	claudiu.beznea, linux-wireless, linux-kernel

From: Mariano Baragiola <mbaragiola@linux.com>

[ Upstream commit 9d96e037ff90a2fc81a841b2002d500a5a4a5351 ]

wilc_wfi_mon_xmit() reads the radiotap length before ensuring that the
fixed header is present. After stripping that header, it reads the frame
type and all three 802.11 addresses without checking how much frame data
remains.

A truncated monitor injection can therefore cause out-of-bounds reads.
Validate the radiotap header first, use the common 802.11 helper to check
the variable header length, and require a complete three-address header
before using the addresses. This covers QoS and four-address data headers
while rejecting short control headers that this path cannot classify.

Signed-off-by: Mariano Baragiola <mbaragiola@linux.com>
Link: https://patch.msgid.link/20260728192610.2236361-1-mbaragiola@linux.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

This is a **5.15.221** tree (`pending-5.15`). The buggy
`wilc_wfi_mon_xmit()` path is present, the OOB is real, and the fix is a
small validation change that belongs here.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

Step 1.1: PARSE THE SUBJECT LINE
Record: **[wifi: wilc1000:] [validate] [check radiotap and 802.11
headers before reading them on monitor TX]**

Step 1.2: PARSE ALL COMMIT MESSAGE TAGS
From the candidate message:
- **Link:** `https://patch.msgid.link/20260728192610.2236361-1-
  mbaragiola@linux.com`
- **Signed-off-by:** Mariano Baragiola (author)
- **Signed-off-by:** Johannes Berg (wireless maintainer; accepted the
  patch)
- No `Fixes:` / `Cc: stable` / `Reported-by` / `Reviewed-by` in the
  candidate text (absence is expected here)

Original mailing-list submission (verified via `b4 mbox` / Openwall, not
the candidate markers) also had:
- **Fixes:** `c5c77ba18ea6 ("staging: wilc1000: Add SDIO/SPI 802.11
  driver")`
- **Cc:** `stable@vger.kernel.org`
- **To:** Ajay Singh, Claudiu Beznea (WILC maintainers)
- **Cc:** linux-wireless, linux-kernel

Step 1.3: ANALYZE THE COMMIT BODY TEXT
Record:
- **Bug:** `wilc_wfi_mon_xmit()` calls
  `ieee80211_get_radiotap_len(skb->data)` before the skb is known to
  contain a radiotap header, then after `skb_pull()` reads frame type
  and three 802.11 addresses with no remaining-length check.
- **Symptom:** truncated monitor injection causes **out-of-bounds
  reads**.
- **Root cause:** missing bounds checks on radiotap length and 802.11
  header length.
- **Fix:** validate radiotap version/length, use
  `ieee80211_get_hdrlen_from_skb()`, require a full 3-address header,
  drop short frames.
- **Version info:** none in the body. Original `Fixes:` points at the
  2015 driver introduction.

Step 1.4: DETECT HIDDEN BUG FIXES
Record: **Not hidden.** The message names OOB reads and describes the
missing checks. The new `drop:` path also stops returning `-1` from
`ndo_start_xmit` without freeing the skb.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

Step 2.1: INVENTORY THE CHANGES
Record:
- **File:** `drivers/net/wireless/microchip/wilc1000/mon.c` only (~+25 /
  -5)
- **Function:** `wilc_wfi_mon_xmit()`
- **Scope:** single-file surgical fix

Step 2.2: UNDERSTAND THE CODE FLOW CHANGE
Local code today (verified in this tree):

```156:195:drivers/net/wireless/microchip/wilc1000/mon.c
        rtap_len = ieee80211_get_radiotap_len(skb->data);
        if (skb->len < rtap_len)
                return -1;

        skb_pull(skb, rtap_len);

        if (skb->data[0] == 0xc0 &&
is_broadcast_ether_addr(&skb->data[4])) {
                // ...
        }
        skb->dev = mon_priv->real_ndev;

        ether_addr_copy(srcadd, &skb->data[10]);
        ether_addr_copy(bssid, &skb->data[16]);
```

Record:
- **Radiotap:** before: read `it_len` with no minimum-size or version
  check, then `return -1` (invalid `netdev_tx_t`, skb not consumed).
  After: require `sizeof(*rtap_hdr)`, `it_version == 0`, `rtap_len >=
  sizeof(*rtap_hdr)`, else drop and free.
- **802.11 header:** before: `skb->data[0]`, `&skb->data[4]`,
  `&skb->data[10]`, `&skb->data[16]` with no length check. After:
  `ieee80211_get_hdrlen_from_skb()` and `hdr_len >= sizeof(struct
  ieee80211_hdr_3addr)` (24 bytes).
- **Deauth match:** `data[0] == 0xc0` replaced by
  `ieee80211_is_deauth(hdr->frame_control)`; broadcast dest uses
  `hdr->addr1`.
- **Address copy:** hardcoded offsets 10/16 replaced by `hdr->addr2` /
  `hdr->addr3` (same layout, now only after a 24-byte header is proven
  present).
- **Drop path:** `dev_kfree_skb(skb); return NETDEV_TX_OK;` — correct TX
  contract.

Step 2.3: IDENTIFY THE BUG MECHANISM
Record: **(d) Memory safety / (g) logic.** Category: **buffer overflow /
out-of-bounds read**.
- `ieee80211_get_radiotap_len()` does `get_unaligned_le16(&hdr->it_len)`
  at offset 2. A 0–1 byte skb is already an OOB read.
- If `skb->len == rtap_len`, `skb_pull()` leaves an empty skb;
  `data[0]`, `data[4]`, `data[10]`, `data[16]` are then OOB.
- Need 22 bytes after radiotap for addr3 (`data[16..21]`); nothing
  enforced that.

Step 2.4: ASSESS THE FIX QUALITY
Record: **Obviously correct and minimal.** Uses existing helpers.
Dropping short control headers is intentional (this path needs
addr2/addr3). QoS/4-address data still pass because their hdrlen is ≥ 24
and addr2/addr3 stay at the same offsets.
- **Regression risk:** low. Valid full 3-address injects unchanged.
  Short frames that previously hit OOB are now dropped.
- **Not introduced:** deauth path still does not free the original skb;
  `skb2` allocation failure still returns `-ENOMEM`. Pre-existing.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

Step 3.1: BLAME THE CHANGED LINES
Record: The TX path is from **c5c77ba18ea6** (`staging: wilc1000: Add
SDIO/SPI 802.11 driver`, 2015-05-24). Length check `skb->len < rtap_len`
is from **60959e53f839** (2016). Address copies from **870709141599**
(2019). Bug has been in this driver for the whole 5.15 lifetime.

Step 3.2: FOLLOW THE FIXES: TAG
Record: Original submission tagged **Fixes: c5c77ba18ea6**. `git merge-
base --is-ancestor c5c77ba18ea6 HEAD` succeeded. Introduced in
**v4.2-rc1**. Present in this tree.

Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES
Record: `mon.c` on this branch is only a handful of commits (staging
move, strlcpy, error-path cleanup, netdev register crash). **No prior
monitor-header validation.** Other wilc1000 OOB fixes **are** already
here (`validate assoc response length`, `fix out-of-bounds read in P2P
public action frames`, `fix RX buffer OOB-write`, etc.). This patch is
**standalone**, subject `[PATCH]` not `X/Y`.

Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS
Record: No other Mariano Baragiola wilc1000 commits in this tree.
Johannes Berg’s SOB is the maintainer acceptance. WILC maintainers were
on To:.

Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS
Record: Functional helpers all exist here:
- `ieee80211_get_radiotap_len()` — `include/net/ieee80211_radiotap.h`
- `ieee80211_get_hdrlen_from_skb()` — `net/wireless/util.c`
  (`EXPORT_SYMBOL`)
- `ieee80211_is_deauth()`, `struct ieee80211_hdr_3addr` —
  `include/linux/ieee80211.h`
- `NETDEV_TX_OK` — `include/linux/netdevice.h`
- Includes already pulled via `cfg80211.h` → `netdev.h`

**One backport tweak:** `struct ieee80211_radiotap_header_fixed` is
**not** in 5.15 (`git merge-base --is-ancestor 57be3d3562ca HEAD`
failed). That type was added in 2024 (`wifi: radiotap: Avoid -Wflex-
array-member-not-at-end warnings`) for a compiler warning. In this tree
`sizeof(struct ieee80211_radiotap_header)` is **8** (flex array has size
0) — same as the fixed header. Substitute `struct
ieee80211_radiotap_header *rtap_hdr`. **Can apply standalone** with that
one-identifier change.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION
Record:
- **Lore/msgid:** `20260728192610.2236361-1-mbaragiola@linux.com`
  (2026-07-28)
- **b4 mbox:** **1 message in the thread** — no review replies, no NAK,
  no v2
- **Openwall:** same single-patch post
- Johannes applied it (SOB on the committed version). Single-revision,
  no later unapplied vN.
- Author nominated **Cc: stable** and **Fixes:** on the original post.

Step 4.2: CHECK WHO REVIEWED THE PATCH
Record: To: Ajay Singh, Claudiu Beznea. Cc: linux-wireless, linux-
kernel, stable. Applied by **Johannes Berg**. No on-list Reviewed-by
found.

Step 4.3: SEARCH FOR THE BUG REPORT
Record: No syzbot/bugzilla tag. Bug is from code inspection of the TX
path. Reachable from userspace `ndo_start_xmit` on the monitor netdev
(creating that iface is `NL80211_IFTYPE_MONITOR` in
`add_virtual_intf()`).

Step 4.4: CHECK FOR RELATED PATCHES AND SERIES
Record: Standalone. Related wilc1000 OOB work in the same period (P2P
public action, assoc-response length) is already on this 5.15 branch;
this commit is a different file/path.

Step 4.5: CHECK STABLE MAILING LIST HISTORY
Record: lore.kernel.org/stable returned HTTP 403. Original patch **was**
Cc’d to stable@. No evidence of a NAK against backporting. UNVERIFIED:
later stable-list debate beyond that CC.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF
Record: **`wilc_wfi_mon_xmit()`** only.

Step 5.2: TRACE CALLERS
Record: Registered as `.ndo_start_xmit` on the monitor netdev created by
`wilc_wfi_init_mon_interface()` from `add_virtual_intf()` when type is
`NL80211_IFTYPE_MONITOR`. Call context: process, packet TX (inject). Not
IRQ.

Step 5.3: TRACE CALLEES
Record: `ieee80211_get_radiotap_len`, `skb_pull`,
`ieee80211_get_hdrlen_from_skb`, `ieee80211_is_deauth`,
`is_broadcast_ether_addr`, `ether_addr_copy`, `mon_mgmt_tx`,
`wilc_mac_xmit` (consumes skb; `dev_kfree_skb` on its error paths),
`dev_kfree_skb`, `netif_rx`.

Step 5.4: FOLLOW THE CALL CHAIN
Record: nl80211 add monitor iface (typically `CAP_NET_ADMIN`) → inject
on that netdev → `wilc_wfi_mon_xmit()`. **Userspace-reachable** on
systems with WILC1000 and a monitor interface. Not a theoretical dead
path.

Step 5.5: SEARCH FOR SIMILAR PATTERNS
Record: Same driver already received several length-check OOB fixes on
this branch. `ieee80211_get_hdrlen_from_skb()` is the usual helper (e.g.
ath9k). This is the same class of bug, not a one-off style cleanup.

===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================

Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?
Record: **Yes.** `drivers/net/wireless/microchip/wilc1000/mon.c` lines
156–195. Introduced 2015; driver left staging in 2020 (`5625f965d7644`,
ancestor of HEAD). **5.15.221** has the bug.

Step 6.2: CHECK FOR BACKPORT COMPLICATIONS
Record: Context around `wilc_wfi_mon_xmit()` matches the hunks.
**Expected difficulty: minor** — rename
`ieee80211_radiotap_header_fixed` → `ieee80211_radiotap_header`. No
other missing APIs.

Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE
Record: **This fix is not in the tree** (`git log --grep="validate
monitor transmit"` on that path is empty). Other wilc1000 OOB fixes do
not cover this TX path.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY
Record: **wifi / wilc1000**
(`drivers/net/wireless/microchip/wilc1000/`). **PERIPHERAL/IMPORTANT for
its users:** IoT/embedded SDIO/SPI WiFi (Kconfig: “usually found in IoT
devices”). Not core mm/VFS, but a supported in-tree driver on 5.15 LTS,
which is exactly where those boards stay.

Step 7.2: ASSESS SUBSYSTEM ACTIVITY
Record: Actively receiving stable OOB/UAF fixes on this branch. Mature
driver, old bug.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

Step 8.1: DETERMINE WHO IS AFFECTED
Record: **Driver-specific / config-specific** (`CONFIG_WILC1000_SDIO` or
`CONFIG_WILC1000_SPI`), monitor interface in use.

Step 8.2: DETERMINE THE TRIGGER CONDITIONS
Record: Inject a short radiotap or short 802.11 frame on the monitor
netdev. Easy to hit once the iface exists. Creating it is privileged;
injection is still a **kernel** OOB, not a userspace-only issue.

Step 8.3: DETERMINE THE FAILURE MODE SEVERITY
Record: **OOB read** of skb/adjacent kernel memory; KASAN crash or info
leak into classification/TX. Invalid `ndo_start_xmit` `-1` can also
confuse the stack and leak the skb. **Severity: HIGH** (memory safety /
crash). Not a silent FS corruption, but in the sanitizer/OOB class that
stable regularly takes.

Step 8.4: CALCULATE RISK-BENEFIT RATIO
Record:
- **Benefit:** high for WILC1000 + monitor users; closes a long-standing
  OOB on a reachable TX path.
- **Risk:** very low (~20 lines, drop path only for invalid frames, one
  type-name tweak).
- **Ratio:** favorable.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

Step 9.1: COMPILE THE EVIDENCE

**FOR backporting:**
- Real OOB reads in `ndo_start_xmit` on truncated injects (code-
  verified).
- Bug present since 2015; this 5.15 tree has the exact buggy code.
- Small, obviously correct validation; wireless maintainer SOB.
- Author Cc’d stable and tagged Fixes: c5c77ba18ea6 (in tree).
- Same driver already gets OOB backports on this branch.
- Helpers exist; drop path also fixes a wrong TX return / skb leak.

**AGAINST:**
- Niche IoT driver, monitor path, typically privileged setup.
- `ieee80211_radiotap_header_fixed` missing (one-line substitution).
- No syzbot/user crash log; no on-list review besides maintainer merge.

**UNRESOLVED:**
- lore.kernel.org HTTP 403; no extra review comments beyond the
  1-message thread.
- Whether Johannes dropped Fixes/Cc: stable when applying (candidate
  text lacks them; original mail had them).

Step 9.2: APPLY THE STABLE RULES CHECKLIST
1. Obviously correct and tested? **PASS** — bounds checks + existing
   helpers; maintainer applied it.
2. Fixes a real bug that affects users? **PASS** — OOB on monitor
   inject.
3. Important issue? **PASS** — kernel OOB read / crash; HIGH.
4. Small and contained? **PASS** — one function, ~20 lines.
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — with
   `ieee80211_radiotap_header` instead of `_fixed`.

Step 9.3: CHECK FOR EXCEPTION CATEGORIES
Record: Not a device-ID/quirk/DT/docs exception. It is a **memory-safety
OOB fix**, which is core stable material.

Step 9.4: MAKE YOUR DECISION
The bug exists in this 5.15 tree, the failure is an OOB read on a
userspace-reachable TX path, and the fix is small. The missing `_fixed`
type is not a missing prerequisite; it is the same 8-byte header under
the older name.

Verification:
- [Phase 1] Parsed candidate tags: Link msgid, SOB Mariano Baragiola,
  SOB Johannes Berg; no Fixes in candidate text
- [Phase 1] b4 mbox + Openwall: original mail had Fixes: c5c77ba18ea6
  and Cc: stable@vger.kernel.org
- [Phase 2] Diff: one function `wilc_wfi_mon_xmit`; radiotap/802.11
  length checks + drop path
- [Phase 2] Local `mon.c` confirmed: `ieee80211_get_radiotap_len` then
  `return -1`; then `data[0]/[4]/[10]/[16]` with no length check
- [Phase 2] `ieee80211_get_radiotap_len` reads `it_len` at offset 2
  without a size check
- [Phase 3] blame: path from c5c77ba18ea6 (2015); `git merge-base --is-
  ancestor c5c77ba18ea6 HEAD` true
- [Phase 3] `git log --grep="validate monitor transmit" -- wilc1000`
  empty — fix not present
- [Phase 3] `57be3d3562ca` (`ieee80211_radiotap_header_fixed`) is
  **not** an ancestor
- [Phase 3] compiled `sizeof(struct ieee80211_radiotap_header)` with FAM
  = 8
- [Phase 3] `ieee80211_get_hdrlen_from_skb`, `ieee80211_is_deauth`,
  `ieee80211_hdr_3addr`, `NETDEV_TX_OK` all exist
- [Phase 4] b4 mbox: 1-message thread, no NAK/v2; To: WILC maintainers
- [Phase 4] lore.kernel.org 403 — UNVERIFIED further review thread
- [Phase 5] caller is monitor `.ndo_start_xmit`; iface created from
  `add_virtual_intf()` MONITOR
- [Phase 5] `wilc_mac_xmit` frees skb on its error paths
- [Phase 6] `git describe HEAD` → p-5.15-2-g6703e5d2f3a29; `make
  kernelversion` → 5.15.221
- [Phase 6] driver not staging here (`5625f965d7644` is ancestor)
- [Phase 8] Failure mode: OOB read on truncated monitor TX, severity
  HIGH
- UNVERIFIED: later stable@ discussion after the original Cc

The patch is a real, small OOB fix for code this tree still has.
Backport with `struct ieee80211_radiotap_header` in place of
`ieee80211_radiotap_header_fixed`.

**YES**

 drivers/net/wireless/microchip/wilc1000/mon.c | 30 +++++++++++++++----
 1 file changed, 25 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/microchip/wilc1000/mon.c b/drivers/net/wireless/microchip/wilc1000/mon.c
index c3d27aaec2974..c0fde3b0d8aab 100644
--- a/drivers/net/wireless/microchip/wilc1000/mon.c
+++ b/drivers/net/wireless/microchip/wilc1000/mon.c
@@ -142,6 +142,9 @@ static int mon_mgmt_tx(struct net_device *dev, const u8 *buf, size_t len)
 static netdev_tx_t wilc_wfi_mon_xmit(struct sk_buff *skb,
 				     struct net_device *dev)
 {
+	struct ieee80211_radiotap_header_fixed *rtap_hdr;
+	struct ieee80211_hdr_3addr *hdr;
+	unsigned int hdr_len;
 	u32 rtap_len, ret = 0;
 	struct wilc_wfi_mon_priv  *mon_priv;
 	struct sk_buff *skb2;
@@ -153,13 +156,26 @@ static netdev_tx_t wilc_wfi_mon_xmit(struct sk_buff *skb,
 	if (!mon_priv)
 		return -EFAULT;
 
+	if (skb->len < sizeof(*rtap_hdr))
+		goto drop;
+
+	rtap_hdr = (void *)skb->data;
+	if (rtap_hdr->it_version)
+		goto drop;
+
 	rtap_len = ieee80211_get_radiotap_len(skb->data);
-	if (skb->len < rtap_len)
-		return -1;
+	if (rtap_len < sizeof(*rtap_hdr) || skb->len < rtap_len)
+		goto drop;
 
 	skb_pull(skb, rtap_len);
+	hdr_len = ieee80211_get_hdrlen_from_skb(skb);
+	if (hdr_len < sizeof(*hdr))
+		goto drop;
 
-	if (skb->data[0] == 0xc0 && is_broadcast_ether_addr(&skb->data[4])) {
+	hdr = (void *)skb->data;
+
+	if (ieee80211_is_deauth(hdr->frame_control) &&
+	    is_broadcast_ether_addr(hdr->addr1)) {
 		skb2 = dev_alloc_skb(skb->len + sizeof(*cb_hdr));
 		if (!skb2)
 			return -ENOMEM;
@@ -191,8 +207,8 @@ static netdev_tx_t wilc_wfi_mon_xmit(struct sk_buff *skb,
 	}
 	skb->dev = mon_priv->real_ndev;
 
-	ether_addr_copy(srcadd, &skb->data[10]);
-	ether_addr_copy(bssid, &skb->data[16]);
+	ether_addr_copy(srcadd, hdr->addr2);
+	ether_addr_copy(bssid, hdr->addr3);
 	/*
 	 * Identify if data or mgmt packet, if source address and bssid
 	 * fields are equal send it to mgmt frames handler
@@ -207,6 +223,10 @@ static netdev_tx_t wilc_wfi_mon_xmit(struct sk_buff *skb,
 	}
 
 	return ret;
+
+drop:
+	dev_kfree_skb(skb);
+	return NETDEV_TX_OK;
 }
 
 static const struct net_device_ops wilc_wfi_netdev_ops = {
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] iwlwifi: dvm: add missing cleaup for on error path
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (33 preceding siblings ...)
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-6.6] wifi: wilc1000: validate monitor transmit frame headers Sasha Levin
@ 2026-10-19 13:52 ` Sasha Levin
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: validate PNVM SKU TLV length Sasha Levin
                   ` (5 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:52 UTC (permalink / raw)
  To: patches, stable
  Cc: Haoxiang Li, Miri Korenblit, Sasha Levin, linux-wireless,
	linux-kernel

From: Haoxiang Li <lihaoxiang@isrc.iscas.ac.cn>

[ Upstream commit 94280e6e0c69a5327e377803732f494d8b5a74cd ]

In iwlagn_tx_agg_start(), call iwlagn_dealloc_agg_txq()
to clear bit on error path.

Signed-off-by: Haoxiang Li <lihaoxiang@isrc.iscas.ac.cn>
Link: https://patch.msgid.link/20260401030555.541685-1-lihaoxiang@isrc.iscas.ac.cn
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The local tree is **7.3.0-rc4**. The DVM TX path still has this
aggregation-queue leak, and the fix is a three-line error-path dealloc.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

**Step 1.1: PARSE THE SUBJECT LINE**

Record: **[iwlwifi: dvm:] [add] [missing cleanup for error path in
`iwlagn_tx_agg_start()`]**
Subsystem: Intel iwlwifi DVM (legacy AGN firmware:
1000/2000/5000/6000-series).
Action: “add missing cleanup” — that is error-path recovery, not a
feature.

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**

Record:
- **Fixes:** none (expected)
- **Reported-by / Tested-by / Reviewed-by / Acked-by:** none
- **Cc: stable:** none (expected)
- **Link:** https://patch.msgid.link/20260401030555.541685-1-
  lihaoxiang@isrc.iscas.ac.cn
- **Signed-off-by:** Haoxiang Li (author); Miri Korenblit (iwlwifi
  maintainer, committer)
- Ignore pipeline SOBs if present; none here besides author/maintainer

Notable: no syzbot, no user crash report. Maintainer SOB is a quality
signal.

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**

Record:
- **Bug:** `iwlagn_tx_agg_start()` allocates an aggregation TX queue
  (`iwlagn_alloc_agg_txq()` sets a bit in `priv->agg_q_alloc`) then
  calls `iwl_sta_tx_modify_enable_tid()`. On failure it returned without
  clearing that bit.
- **Symptom:** leaked AMPDU hardware queue; later starts get `-ENOSPC`
  (“No free aggregation queue”).
- **Version info:** none in the message.
- **Root cause (author):** missing `iwlagn_dealloc_agg_txq()` on that
  error path.

**Step 1.4: DETECT HIDDEN BUG FIXES**

Record: **Yes, a real bug fix phrased as cleanup.** It adds rollback
after a failed firmware command. Not style-only.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

**Step 2.1: INVENTORY THE CHANGES**

Record:
- File: `drivers/net/wireless/intel/iwlwifi/dvm/tx.c`  **+3 / -1** (4
  lines touched)
- Function: `iwlagn_tx_agg_start()`
- Scope: **single-file surgical error-path fix**

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**

Record:
- **Before:** `txq_id = iwlagn_alloc_agg_txq(...)` (sets bit in
  `agg_q_alloc`). If `iwl_sta_tx_modify_enable_tid()` fails, return
  `ret` immediately. Bit stays set. `tid_data->agg.txq_id` is never
  stored; `agg.state` stays `IWL_AGG_OFF`.
- **After:** same failure path calls `iwlagn_dealloc_agg_txq(priv,
  txq_id)` (clears bit, resets `queue_to_mac80211[q]`) then returns.
- Path: **error path only**. Success path unchanged.

**Step 2.3: IDENTIFY THE BUG MECHANISM**

Record:
- **Category:** error-path **resource leak** (bitmap / HW TX queue), not
  a memory UAF.
- **Mechanism:** `iwlagn_alloc_agg_txq()` does `test_and_set_bit(q,
  priv->agg_q_alloc)`. DVM has **20** queues (`IWLAGN_NUM_QUEUES`),
  AMPDU starts at **11** (`IWLAGN_FIRST_AMPDU_QUEUE`) → **9**
  aggregation queues. `iwl_sta_tx_modify_enable_tid()` sends
  `REPLY_ADD_STA` via `iwl_send_add_sta()`; that can return send-cmd
  errors or `-EIO` if firmware status is not `ADD_STA_SUCCESS_MSK`.
- **Why stop cannot recover:** `iwlagn_tx_agg_stop()` only deallocates
  if `tid_data->agg.txq_id` is set and `test_bit(txq_id, agg_q_alloc)`.
  On this failure, `txq_id` was never written into `tid_data` and state
  is still `IWL_AGG_OFF` (stop’s default branch returns 0). Bitmap is
  cleared on nic restart (`memset(priv->agg_q_alloc, 0, ...)` in the
  restart path in `dvm/main.c`), so the leak lasts until firmware
  restart/reload.

**Step 2.4: ASSESS THE FIX QUALITY**

Record:
- **Obviously correct:** dealloc is the inverse of alloc; same helper is
  already used in stop/flush/DELBA.
- **Minimal:** one call on the existing error return.
- **Regression risk: very low.** v1 also deallocated on
  `IWL_EMPTYING_HW_QUEUE_ADDBA` (delayed start, not an error).
  Maintainer Miriam Korenblit rejected that; v2 (this commit) only
  deallocs on the real error. Unlocking/locking unchanged. No API
  change.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

**Step 3.1: BLAME THE CHANGED LINES**

Record:
- Alloc call: Johannes Berg, `1479177ba69023` / `9eae88fa9a02e3`
  (**2012**, contained in **v3.5-rc1**).
- Failed `iwl_sta_tx_modify_enable_tid()` return: Emmanuel Grumbach
  `288712a6ccf47b` (2011) / Wey-Yi Guy `74bcdb33e99f49` (2010).
- Bug has been in DVM for ~14 years. Code is mature, not brand-new.

**Step 3.2: FOLLOW THE FIXES: TAG**

Record: **No Fixes: tag.** Not applicable. Introducer is the 2012 queue-
mapping work, which is in this tree.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**

Record:
- Recent DVM `tx.c`: this fix, kernel-doc, rename churn. No prerequisite
  refactor of `iwlagn_alloc_agg_txq` / `iwlagn_dealloc_agg_txq`.
- Standalone; not “patch X/Y”.
- No later follow-up on `dvm/tx.c` after `94280e6e0c69a` in this
  checkout.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**

Record:
- Haoxiang Li: this is the only iwlwifi commit in this tree (external
  contributor).
- Committer Miri Korenblit is an iwlwifi maintainer (many iwlwifi
  commits). Johannes Berg (wireless maintainer) was on To/Cc.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**

Record: **None.** Uses existing `iwlagn_dealloc_agg_txq()` (present
since the 2012 alloc/dealloc pair). Applies standalone.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**

Record:
- **b4 dig -c 94280e6e0c69a:** https://patch.msgid.link/20260401030555.5
  41685-1-lihaoxiang@isrc.iscas.ac.cn
- **b4 dig -a:**
  - v1: 2026-03-30 https://patch.msgid.link/20260330012620.2715796-1-
    lihaoxiang@isrc.iscas.ac.cn
  - v2 (applied): 2026-04-01
- **v1 extra hunk:** `iwlagn_dealloc_agg_txq()` also on
  `IWL_EMPTYING_HW_QUEUE_ADDBA`. Miriam: “I don't think that this is an
  error case?” — correct; that state holds the queue while draining
  before ADDBA.
- **v2:** only the firmware-command error path. Changelog: “remove an
  unnecessary error handling. Thanks, Miriam!”
- **Markus Elfring** on v2: asked for Fixes/stable tags and a subject
  typo fix; pointed at `stable-kernel-rules.rst`.
- **Johannes Berg** replied to Markus (typo/process nit), did not NAK
  the patch.
- **No NAKs** on the remaining hunk. Applied by Miri Korenblit
  2026-07-14.

**Step 4.2: CHECK WHO REVIEWED THE PATCH**

Record (**b4 dig -w**): Haoxiang Li; Miri Korenblit; Johannes Berg;
linux-wireless; linux-kernel. Right maintainers and list.

**Step 4.3: SEARCH FOR THE BUG REPORT**

Record: **No syzbot/bugzilla report.** Found by code review of the error
path. Trigger is real: `iwl_send_add_sta()` can fail.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**

Record: Standalone 1-patch series (v1→v2). Not part of a larger DVM
rework.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**

Record: lore.kernel.org HTTP fetch returned **403**; `b4` on stable
search did not yield a thread. **UNVERIFIED** whether stable@ discussed
this. Markus pointed at stable rules on linux-wireless; that is not a
maintainer Cc:stable.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

**Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF**

Record: `iwlagn_tx_agg_start()`; helpers involved:
`iwlagn_alloc_agg_txq()`, `iwlagn_dealloc_agg_txq()`,
`iwl_sta_tx_modify_enable_tid()`.

**Step 5.2: TRACE CALLERS**

Record:
- `iwlagn_tx_agg_start()` ← `iwlagn_mac_ampdu_action()` on
  `IEEE80211_AMPDU_TX_START` (`dvm/mac80211.c`).
- That is the mac80211 `.ampdu_action` op — **userspace-reachable** via
  HT AMPDU session setup (normal AP association), under `priv->mutex`,
  if `sku_cap_11n_enable` and TX AMPDU enabled.

**Step 5.3: TRACE CALLEES**

Record:
- `iwl_sta_tx_modify_enable_tid()` → `iwl_send_add_sta()` →
  `iwl_dvm_send_cmd()`; firmware may fail.
- `iwlagn_dealloc_agg_txq()`: `clear_bit` + `queue_to_mac80211[q] =
  IWL_INVALID_MAC80211_QUEUE`. No lock inside; alloc uses
  `test_and_set_bit`. Same as stop/flush.

**Step 5.4: FOLLOW THE CALL CHAIN**

Record: cfg80211/mac80211 AMPDU TX start → iwlwifi DVM. Reachable on DVM
hardware during HT association. Not a debug-only path.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**

Record: Dealloc already on stop, flush, and DELBA-empty. This start-
error path was the missing one. No sibling DVM function with the same
hole found.

===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**

Record:
- Tree: **7.3.0-rc4** (`v7.3-rc4-27-gf0100363d8c37`), `VERSION=7
  PATCHLEVEL=3`.
- File and functions exist:
  `drivers/net/wireless/intel/iwlwifi/dvm/tx.c`, `CONFIG_IWLDVM`.
- Pre-fix parent of `94280e6e0c69a` still has `if (ret) return ret;`
  with no dealloc (verified via `git show 94280e6e0c69a^:...`).
- Bug introduced **v3.5**; present in this tree’s DVM.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**

Record: **Clean apply.** Surrounding `iwlagn_tx_agg_start()` matches the
hunk. No conflicting DVM TX rewrite in this checkout.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**

Record: No other commit on this leak. `67105abd6195a` is a different DVM
leak (`iwl_op_mode_dvm_start()`).

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**

Record: **iwlwifi DVM** (`drivers/net/wireless/intel/iwlwifi/dvm/`).
**IMPORTANT** for users of those Intel AGN adapters; not mm/net core.
DVM is legacy vs MVM/MLD but still built (`config IWLDVM`).

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**

Record: DVM is maintenance-mode (few commits); iwlwifi overall is
active. Long-lived bug in old code, not a brand-new feature.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

**Step 8.1: DETERMINE WHO IS AFFECTED**

Record: **Driver-specific / config-specific:** `CONFIG_IWLDVM` and
1000/2000/5000/6000-class Intel WiFi. Still present on older
laptops/embedded boards that LTS kernels serve.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**

Record:
- Trigger: AMPDU TX start + failed `REPLY_ADD_STA` (firmware error,
  timeout, device going down).
- Not every packet; **error path**. Unprivileged users can cause AMPDU
  setup by using WiFi, but failure needs firmware/cmd error.
- After **9** leaks, all agg queues are gone until nic restart.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**

Record:
- **Failure:** AMPDU TX queues exhausted → aggregation start fails
  (`-ENOSPC`); throughput drop, not oops/UAF/corruption.
- Restart path zeros `agg_q_alloc`, so a firmware restart recovers.
- **Severity: MEDIUM–HIGH** (resource leak of a tiny pool; user-visible
  WiFi degradation; not a panic).

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**

Record:
- **Benefit:** restores AMPDU after firmware command failures on DVM
  hardware; small pool makes leaks matter.
- **Risk:** very low (3 lines, existing helper, v2 reviewed by iwlwifi
  maintainer).
- **Ratio:** favorable.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

**Step 9.1: COMPILE THE EVIDENCE**

**FOR:**
- Real leak: alloc bit never cleared if `iwl_sta_tx_modify_enable_tid()`
  fails.
- Stop/flush cannot free it because `tid_data->agg.txq_id` was never
  set.
- Only 9 AMPDU queues; leak is quickly fatal for aggregation.
- 3-line, obviously correct; uses existing dealloc.
- Maintainer (Miri) reviewed v1, dropped the wrong extra dealloc,
  applied v2.
- Johannes Berg was CC’d; no NAK of the remaining change.
- Code present in this 7.3-rc4 tree since v3.5; applies cleanly.
- Matches the stable “error-path resource leak” pattern.

**AGAINST:**
- Not a crash, UAF, or security bug.
- DVM is legacy; fewer users than MVM/MLD.
- Trigger is an error path, not every AMPDU start.
- No Fixes/Cc:stable/syzbot (absence is expected and not a negative).
- Elfring asked for tags; they were never added.

**UNRESOLVED:**
- lore.kernel.org WebFetch 403; stable@ discussion not independently
  confirmed.
- How often ADD_STA fails in the field: not quantified (only that the
  fail path exists in `iwl_send_add_sta()`).

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**

1. Obviously correct and tested? **PASS** — inverse of alloc;
   maintainer-corrected v2; in mainline since Jul 2026.
2. Fixes a real bug that affects users? **PASS** — leaked HW agg queues;
   AMPDU start then fails.
3. Important issue? **PASS** at resource-leak / WiFi-breakage level (not
   panic). Queue pool of 9 makes it operationally important for DVM.
4. Small and contained? **PASS** — +3/-1, one function.
5. No new features or APIs? **PASS**.
6. Can apply to the local tree? **PASS** — DVM `iwlagn_tx_agg_start()`
   is here and matches.

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**

Record: Not a device-ID/quirk/DT/build/doc exception. Ordinary error-
path leak fix.

**Step 9.4: MAKE YOUR DECISION**

This belongs in this tree: DVM is present, the leak is real, and the fix
is a tiny, reviewed rollback. AMPDU queue exhaustion is a serious
functional failure for remaining DVM hardware, and regression risk is
negligible.

What it solves for users of this tree: failed `REPLY_ADD_STA` during TX
aggregation start no longer permanently consumes one of nine AMPDU
queues until firmware restart.

Verification:
- [Phase 1] Tags: Link msgid 20260401030555.541685-1; SOB Haoxiang Li +
  Miri Korenblit; no Fixes/Reported-by/Cc:stable
- [Phase 2] Diff: +3/-1 in `iwlagn_tx_agg_start()`; adds
  `iwlagn_dealloc_agg_txq()` when `iwl_sta_tx_modify_enable_tid()` fails
- [Phase 2] Confirmed alloc sets `agg_q_alloc` bit; dealloc clears it
  (`tx.c` 463–482)
- [Phase 2] `iwl_send_add_sta()` can return cmd error or `-EIO` (`sta.c`
  82–123)
- [Phase 2] 9 AMPDU queues: `IWLAGN_FIRST_AMPDU_QUEUE=11`,
  `IWLAGN_NUM_QUEUES=20`
- [Phase 2] Stop cannot recover: `txq_id` not stored, state stays
  `IWL_AGG_OFF`
- [Phase 3] Blame: alloc path from 2012 (`9eae88fa9a02e3` /
  `1479177ba69023`), contained in v3.5-rc1
- [Phase 3] No Fixes: tag; no later follow-up on `dvm/tx.c` after this
  commit
- [Phase 3] Author has no other iwlwifi commits; Miri is iwlwifi
  maintainer
- [Phase 4] `b4 dig -c 94280e6e0c69a`: lore patch-id match for v2
- [Phase 4] `b4 dig -a`: v1 2026-03-30, v2 2026-04-01 (applied)
- [Phase 4] v1 mbox: extra dealloc on `IWL_EMPTYING_HW_QUEUE_ADDBA`;
  Miriam rejected it
- [Phase 4] `b4 dig -w`: Miri + Johannes + linux-wireless
- [Phase 4] Markus pointed at stable-kernel-rules; Johannes replied to
  that nit only
- [Phase 4] UNVERIFIED: stable@ archive (HTTP 403)
- [Phase 5] Caller: `iwlagn_mac_ampdu_action()`
  `IEEE80211_AMPDU_TX_START`
- [Phase 6] `make kernelversion` / Makefile: 7.3.0-rc4; `git describe
  HEAD`: v7.3-rc4-27-gf0100363d8c37
- [Phase 6] Pre-fix source from `94280e6e0c69a^` lacks dealloc
- [Phase 6] `CONFIG_IWLDVM` still in Kconfig; restart path zeros
  `agg_q_alloc` (`main.c` ~1021)
- [Phase 8] Failure: AMPDU queue exhaustion / `-ENOSPC`, not oops;
  severity MEDIUM–HIGH

**YES**

 drivers/net/wireless/intel/iwlwifi/dvm/tx.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/tx.c b/drivers/net/wireless/intel/iwlwifi/dvm/tx.c
index a7806776a51eb..1a0167f67c7bd 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/tx.c
@@ -604,8 +604,10 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
 	}
 
 	ret = iwl_sta_tx_modify_enable_tid(priv, sta_id, tid);
-	if (ret)
+	if (ret) {
+		iwlagn_dealloc_agg_txq(priv, txq_id);
 		return ret;
+	}
 
 	spin_lock_bh(&priv->sta_lock);
 	tid_data = &priv->tid_data[sta_id][tid];
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18] wifi: iwlwifi: validate PNVM SKU TLV length
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (34 preceding siblings ...)
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-5.10] iwlwifi: dvm: add missing cleaup for on error path Sasha Levin
@ 2026-10-19 13:52 ` Sasha Levin
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-6.6] wifi: rsi: Fix types to appease CFI Sasha Levin
                   ` (4 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:52 UTC (permalink / raw)
  To: patches, stable
  Cc: Pengpeng Hou, Miri Korenblit, Sasha Levin, linux-wireless,
	linux-kernel

From: Pengpeng Hou <pengpeng@iscas.ac.cn>

[ Upstream commit 7410e4548a17bd868dfc60b48f2e78eacde3ad78 ]

iwl_pnvm_parse() reads an iwl_sku_id from an
IWL_UCODE_TLV_PNVM_SKU payload after only checking that the generic TLV
payload is present.

A short type-specific payload can therefore make the three data[] reads
extend beyond the TLV. Reject SKU TLVs shorter than the structure before
accessing it.

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Link: https://patch.msgid.link/20260715135916.24417-1-pengpeng@iscas.ac.cn
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

This checkout is mainline **7.3.0-rc4**. The candidate is a six-line
bounds check in `iwl_pnvm_parse()` that rejects a short
`IWL_UCODE_TLV_PNVM_SKU` payload before reading `struct iwl_sku_id`.
That is a real out-of-bounds read on truncated PNVM data, and the parser
(and the surrounding length-check style) is present in this tree.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

**Step 1.1: PARSE THE SUBJECT LINE**
Record: **[wifi: iwlwifi]** **[validate]** **reject PNVM SKU TLVs
shorter than `struct iwl_sku_id` before reading `data[0..2]`**
- Subsystem: `wifi: iwlwifi`
- Verb: “validate” — defensive length check, i.e. a bounds fix, not a
  feature

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record (from `git log -1 --format='%B' 7410e4548a17b`):
- **Fixes:** none (expected for this review)
- **Reported-by / Tested-by / Reviewed-by / Acked-by:** none
- **Cc: stable:** none (expected)
- **Link:**
  `https://patch.msgid.link/20260715135916.24417-1-pengpeng@iscas.ac.cn`
  (v2, patch 1 of a 2-patch series)
- **Signed-off-by:** Pengpeng Hou (author); Miri Korenblit (iwlwifi
  maintainer, applied it)
- Notable: no syzbot, no CVE, no user crash report. Maintainer SOB is a
  strong quality signal.

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** `iwl_pnvm_parse()` treats a present generic TLV payload as
  enough, then reads three `__le32` SKU words.
- **Symptom:** short type-specific payload → `tlv_sku_id->data[0..2]`
  reads past the TLV (and, if remaining file bytes `< 12`, past the
  allocated buffer).
- **Version info:** none in the message.
- **Root cause:** missing type-specific minimum length vs `sizeof(struct
  iwl_sku_id)`.
- **Fix:** `if (tlv_len < sizeof(*tlv_sku_id)) return -EINVAL` before
  the three reads.

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not disguised. Explicit bounds validation. Same class as the
existing `tlv_len < sizeof(...)` checks on `IWL_UCODE_TLV_PNVM_VERSION`
and `IWL_UCODE_TLV_HW_TYPE` in `iwl_pnvm_handle_section()`.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `drivers/net/wireless/intel/iwlwifi/fw/pnvm.c` — **+6 / −0**
- Function: `iwl_pnvm_parse()`
- Scope: **single-file surgical fix**

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Verified against `7410e4548a17b^` and current `pnvm.c`:

Before: after `len < tlv_len` (payload fits in remaining buffer), a
`IWL_UCODE_TLV_PNVM_SKU` TLV is cast to `struct iwl_sku_id` and
`data[0]`, `data[1]`, `data[2]` are read with **no** `tlv_len >= 12`
check.

After: if `tlv_len < sizeof(*tlv_sku_id)` (12 bytes), log and `return
-EINVAL`. Valid Intel PNVM SKU TLVs are unchanged.

Path: firmware-init parse of PNVM from BIOS, `.pnvm` file, or embedded
`.ucode` — error path only for a short SKU TLV.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record: **[Memory safety: buffer over-read / OOB]**

`struct iwl_sku_id` is `{ __le32 data[3]; } __packed`
(`fw/api/alive.h`). Generic check is `len < tlv_len` only.

Concrete OOB (verified): file size 10, header 8 bytes, `tlv_len=0`,
`tlv_type=PNVM_SKU`. After the header, `len=2`. `2 < 0` is false, then
12 bytes are read from a 2-byte remainder → **true kernel buffer over-
read**. If remainder ≥ 12 but `tlv_len < 12`, the read stays in the file
but past this TLV (wrong SKU / wrong section match).

**Step 2.4: ASSESS THE FIX QUALITY**
Record: Obviously correct and matches sibling TLV checks. No
API/lock/refcount change. Regression risk: **very low**. Valid SKU TLV
length is 12; those still parse. A short SKU now fails closed (`-EINVAL`
→ `fail_to_parse_pnvm_image`), which is the intended defense.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

**Step 3.1: BLAME THE CHANGED LINES**
Record:
- SKU TLV loop: **6972592850c00e** (`iwlwifi: read and parse PNVM file`,
  Luca Coelho, 2020-10-08) — first in **v5.10-rc1**.
- `struct iwl_sku_id` cast / `data[0..2]` compares: **3a68ae0fa2ec13**
  (2025) — same 12-byte read, still unchecked.
- Length check: **7410e4548a17b** (this commit, 2026-07-15), first
  contained in **v7.3-rc1**.

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No `Fixes:` tag. Introducer is 6972592850c00e; `git merge-base
--is-ancestor 6972592850c00e HEAD` succeeded. Bug is old, not post-
branch.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record:
- **f051995c53958** — same author, patch 2/2, same check in
  `iwl_uefi_reduce_power_parse()` (`uefi.c`). Not a prerequisite for
  this hunk.
- **daec24a5ed5da** — nearby `iwl_pnvm_complete_fn` payload-length
  check; independent.
- `iwl_pnvm_handle_section()` already length-checks other TLV types.
  This fills the SKU hole in the outer parser.
- Standalone: applies without patch 2.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Pengpeng Hou has these two iwlwifi commits here (SKU length in
`pnvm.c` and `uefi.c`). Applied by **Miri Korenblit**, listed in
MAINTAINERS as Intel wireless maintainer.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: Uses existing `tlv_len`, `tlv_sku_id`, `IWL_ERR`, `-EINVAL`. No
new helpers. **Applies standalone.**

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- `b4 dig -c 7410e4548a17b` →
  https://patch.msgid.link/20260715135916.24417-1-pengpeng@iscas.ac.cn
- `b4 dig -a`: **v1** 2026-06-30 (`3 * sizeof(__le32)`); **v2**
  2026-07-15 (`sizeof(*tlv_sku_id)`).
- v1 mbox: Miri: `Sizeof(*tlv_sku_id)` — no NAK, no stable debate.
- Applied version is v2. WebFetch to lore returned **403**; discussion
  recovered via `b4 mbox`.

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record (`b4 dig -w`): To/Cc Pengpeng Hou, **Miri Korenblit**, linux-
wireless, linux-kernel. Right maintainer and list. Miri both reviewed v1
and signed off v2.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: No Reported-by, syzbot, or bugzilla. Issue is from code
inspection. Trigger is malformed/truncated PNVM, not a published user
crash.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: v2 msgid `...24417-1...` is patch 1/2. Patch 2 is f051995c53958
on `uefi.c`. This commit does not need patch 2.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: `WebFetch https://lore.kernel.org/stable/?q=...` returned
**403**. **UNVERIFIED** whether stable@ discussed it. No `Cc: stable` on
the patch.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

**Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF**
Record: **`iwl_pnvm_parse()`** only (static).

**Step 5.2: TRACE CALLERS**
Record (grep in this tree):
- `iwl_pnvm_parse()` ← `iwl_pnvm_load_pnvm_to_trans()`
- ← `iwl_pnvm_load()` (exported)
- ← `iwl_mvm` `mvm/fw.c` and `iwl_mld` `mld/fw.c` after firmware alive

Called on WiFi bring-up / fw restart for AX210+ when SKU_ID is non-zero
— **common device-init path**, process context, not IRQ.

**Step 5.3: TRACE CALLEES**
Record: `le32_to_cpu`, `IWL_DEBUG_FW`/`IWL_ERR`,
`iwl_pnvm_handle_section()` on SKU match. New path only returns
`-EINVAL`. Image sources: UEFI/BIOS, `firmware_request_nowarn()`
`.pnvm`, or embedded `fw->pnvm_data`.

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: `iwl_mvm_load_rt_fw` / `iwl_mld_run_fw_init_sequence` →
`iwl_pnvm_load` → parse. Unprivileged userspace cannot feed an arbitrary
blob without replacing firmware (usually root). Truncated/corrupt
firmware or bad BIOS PNVM is still a realistic field case. **Reachable
on every Intel AX210+ bring-up that has PNVM.**

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: Same `tlv_len < sizeof(*tlv_sku_id)` in
`iwl_uefi_reduce_power_parse()` (`uefi.c`, added by patch 2).
`iwl_pnvm_handle_section()` already length-checks VERSION/HW_TYPE. `iwl-
drv.c` does similar TLV size checks for ucode.

===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: **Yes.** `drivers/net/wireless/intel/iwlwifi/fw/pnvm.c`
`iwl_pnvm_parse()` SKU handling is here (lines 201–234). Introduced
v5.10; this tree is 7.3-rc4. Unfixed form is `7410e4548a17b^`; HEAD
already includes the six-line check (commit is an ancestor of HEAD;
first tag **v7.3-rc1**). That is origin history, not a stable-queue
marker.

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: On this tree the hunk is already applied and matches the
candidate. Context (`reduced_cap_sku`, `sku_id[]` compare) is present.
**Clean apply** here. Older stables may still need a trivial context
tweak; that is out of scope for *this* checkout.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: This exact check is already in HEAD. No alternate SKU-length
fix. UEFI twin is a separate commit. No competing fix to skip this one
on merit.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: **iwlwifi firmware/PNVM loader**
(`drivers/net/wireless/intel/iwlwifi/`). **IMPORTANT** (not mm/net core;
Intel WiFi is extremely common).

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: Active (`iwlwifi-next` merges, PNVM source/embed work). Parser
itself dates to 2020; this is a late bounds check on old logic, not a
fix to brand-new code.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: **Driver-specific** — Intel iwlwifi with PNVM (AX210 and later;
BIOS/external/embedded). Large laptop/desktop population.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record: PNVM blob with `IWL_UCODE_TLV_PNVM_SKU` and `length < 12`
(truncated file, corrupt UEFI, bad image). Not every boot with good
linux-firmware. Unprivileged trigger only if firmware can be replaced
without privilege (normally no). Timing: not a race.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record: **OOB read** of up to 12 bytes. Can KASAN-oops if the remaining
buffer is short; otherwise reads past the TLV into neighboring bytes
(wrong SKU match). **Severity: HIGH** (memory safety / possible oops),
not a guaranteed panic on healthy firmware.

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record:
- **Benefit:** High for a 6-line check: stops a real over-read in a
  widely used driver; same pattern as neighboring TLV checks.
- **Risk:** Very low; fail closed on invalid TLV; valid 12-byte SKU
  unchanged.
- **Ratio:** Strongly favors applying it.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

**Step 9.1: COMPILE THE EVIDENCE**

FOR:
- Real OOB read: `tlv_len` can be 0–11 while the code reads 12 bytes.
- iwlwifi PNVM parse exists in this tree since v5.10; bug is not newer
  than this branch.
- 6 lines, one function, fail closed — obviously correct.
- Maintainer (Miri) requested `sizeof(*tlv_sku_id)` and applied v2.
- Completes length checks already used for other PNVM TLV types.
- Intel AX210+ WiFi is a large user base; PNVM comes from
  files/UEFI/embedded ucode, which can be truncated.

AGAINST:
- No syzbot/CVE/user oops in the message.
- Typical trigger is malformed firmware, often needing root to plant.
- Part of a 2-patch series (UEFI twin is independent, not required).
- HEAD already contains 7410e4548a17b because this *is* the 7.3 mainline
  line that merged iwlwifi-next — not used as a “already queued for
  stable” reason.

UNRESOLVED:
- lore.kernel.org HTTP 403; stable@ discussion not fetched. Review
  recovered via `b4`.

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — maintainer-reviewed v2;
   logic matches existing TLV checks.
2. Fixes a real bug that affects users? **PASS** — OOB read in PNVM
   parse on short SKU TLV.
3. Important (crash, security, corruption, deadlock)? **PASS** — buffer
   over-read / possible oops; HIGH, not theoretical.
4. Small and contained? **PASS** — +6 lines, one file.
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — code and context are here
   (already the applied form).

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: None of device-ID / quirk / DT / build / docs. Ordinary memory-
safety fix.

**Step 9.4: MAKE YOUR DECISION**
This tree has `iwl_pnvm_parse()` and the SKU TLV path. The bug is a
missing type-specific length check, present since PNVM parsing landed.
The fix is minimal, reviewed, and fail-closed. That meets stable rules
for *this* checkout’s iwlwifi code.

------------------------------------------------
What the commit solves for users of this tree
------------------------------------------------
On Intel WiFi bring-up, PNVM is parsed from BIOS, a `.pnvm` file, or
embedded ucode. A SKU TLV shorter than 12 bytes made the driver read
`data[0..2]` past the TLV and, if the buffer was also short, past the
allocation. That is a kernel over-read (KASAN/oops) or a wrong SKU
comparison. The patch rejects those TLVs with `-EINVAL` before the
reads. Valid 12-byte SKU TLVs are unchanged.

Risk vs benefit: six lines on an error path vs a real OOB in a common
driver — benefit dominates. No prerequisites. Patch 2 (`uefi.c`) is the
same idea elsewhere, not required here.

Verification:
- [Phase 1] Tags: Link to msgid 24417-1; SOB Pengpeng Hou, Miri
  Korenblit; no Fixes/Reported-by/Cc: stable
- [Phase 2] Diff: +6 in `iwl_pnvm_parse()`; parent lacks the check;
  `iwl_sku_id` is 3×`__le32`
- [Phase 2] OOB: `tlv_len=0` with remaining `len=2` still passes `len <
  tlv_len`, then 12-byte read
- [Phase 3] Blame: 6972592850c00e (v5.10-rc1) introduced SKU parse; `git
  merge-base --is-ancestor` yes
- [Phase 3] No Fixes tag; sibling f051995c53958 is uefi.c only
- [Phase 4] `b4 dig -c 7410e4548a17b`: lore msgid 24417-1; v1→v2; Miri
  asked for `sizeof(*tlv_sku_id)`
- [Phase 4] `b4 dig -w`: linux-wireless + Miri; WebFetch lore/stable
  **403** (UNVERIFIED)
- [Phase 5] Callers: `iwl_pnvm_load` → mvm/mld fw alive; sources BIOS /
  fs / embedded
- [Phase 6] `git describe HEAD` = **v7.3-rc4-27-gf0100363d8c37**; `make
  kernelversion` = **7.3.0-rc4**; buggy parser present; fix already
  ancestor (v7.3-rc1)
- [Phase 7] iwlwifi, Miri listed in MAINTAINERS
- [Phase 8] Failure: OOB read / possible oops on short SKU TLV; severity
  HIGH; risk very low
- UNVERIFIED: stable@ mailing-list thread (HTTP 403)

**YES**

 drivers/net/wireless/intel/iwlwifi/fw/pnvm.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c
index 5de3a9c0b3ef0..f623f1b679367 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c
@@ -205,6 +205,12 @@ static int iwl_pnvm_parse(struct iwl_trans *trans, const u8 *data,
 			IWL_DEBUG_FW(trans,
 				     "Got IWL_UCODE_TLV_PNVM_SKU len %d\n",
 				     tlv_len);
+			if (tlv_len < sizeof(*tlv_sku_id)) {
+				IWL_ERR(trans, "invalid PNVM SKU TLV len: %u\n",
+					tlv_len);
+				return -EINVAL;
+			}
+
 			IWL_DEBUG_FW(trans, "sku_id 0x%0x 0x%0x 0x%0x\n",
 				     le32_to_cpu(tlv_sku_id->data[0]),
 				     le32_to_cpu(tlv_sku_id->data[1]),
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18-6.6] wifi: rsi: Fix types to appease CFI
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (35 preceding siblings ...)
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: validate PNVM SKU TLV length Sasha Levin
@ 2026-10-19 13:52 ` Sasha Levin
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18] wifi: mt76: mt7603: restore hardware PS buffering after a service period Sasha Levin
                   ` (3 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:52 UTC (permalink / raw)
  To: patches, stable
  Cc: Stefan Hansson, Johannes Berg, Sasha Levin, linux-wireless,
	linux-kernel

From: Stefan Hansson <newbyte@postmarketos.org>

[ Upstream commit da308f6e471252ae5e8009dcea16bc5e9c9dc5dd ]

Avoids errors like:

    CFI failure at kthread+0x124/0x1cc (target: rsi_coex_scheduler_thread+0x0/0x1b4 [redpine_91x]; expected type: 0x89fb613d)

As seen in the aforementioned error this was tested using the downstream
redpine_91x driver found in the Librem 5's downstream source tree.
However, it appears that this driver is a modified version of the rsi
driver found in mainline Linux and as such I decided to port the changes
here too.

Signed-off-by: Stefan Hansson <newbyte@postmarketos.org>
Link: https://patch.msgid.link/20260804-rsi-cfi-fix-v2-1-59679a520240@postmarketos.org
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

I have enough to decide: this is a 6.12 tree, the mismatched kthread
types are present, and a CFI failure here is a default kernel BUG.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

Step 1.1: PARSE THE SUBJECT LINE
Record: [wifi: rsi] [Fix] [Correct kthread callback types so Clang CFI
accepts them]

Step 1.2: PARSE ALL COMMIT MESSAGE TAGS
Record:
- Signed-off-by: Stefan Hansson &lt;newbyte@postmarketos.org&gt;
  (author)
- Link: https://patch.msgid.link/20260804-rsi-cfi-
  fix-v2-1-59679a520240@postmarketos.org
- Signed-off-by: Johannes Berg &lt;johannes.berg@intel.com&gt; (linux-
  wireless maintainer)
- No Fixes: tag (expected)
- No Cc: stable (expected)
- No Reported-by / Tested-by / Reviewed-by / Acked-by on the committed
  message
- Ignore any pipeline “Upstream commit” / “Signed-off-by: Sasha Levin”
  markers (none present in the provided message)

Notable: maintainer SOB; author is from postmarketOS; testing mentioned
in the body, not as Tested-by.

Step 1.3: ANALYZE THE COMMIT BODY TEXT
Record:
- Bug: CFI type mismatch when kthread starts
  `rsi_coex_scheduler_thread`.
- Symptom: `CFI failure at kthread+0x124/0x1cc (target:
  rsi_coex_scheduler_thread+0x0/0x1b4 [redpine_91x]; expected type:
  0x89fb613d)`
- Version info: none. Tested on Librem 5 downstream `redpine_91x`,
  described as a modified rsi driver; author ported the same type fix to
  mainline rsi.
- Root cause (from message + code): thread helpers are not `int (*)(void
  *)` as `kthread_run()` requires; `rsi_create_kthread()` takes `void
  *func_ptr`, so the compiler cannot catch it.

Step 1.4: DETECT HIDDEN BUG FIXES
Record: Not a disguised cleanup. The subject says “Fix types”; it is a
real CFI/runtime type-check failure, not style-only.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

Step 2.1: INVENTORY THE CHANGES
Record:
- `drivers/net/wireless/rsi/rsi_91x_coex.c` —
  `rsi_coex_scheduler_thread`
- `drivers/net/wireless/rsi/rsi_91x_main.c` — `rsi_tx_scheduler_thread`
- `drivers/net/wireless/rsi/rsi_91x_sdio_ops.c` — `rsi_sdio_rx_thread`
- `drivers/net/wireless/rsi/rsi_91x_usb_ops.c` — `rsi_usb_rx_thread`
- `drivers/net/wireless/rsi/rsi_common.h` — `rsi_create_kthread`
- `drivers/net/wireless/rsi/rsi_sdio.h` / `rsi_usb.h` — prototypes
- Scope: 7 files, 15 insertions / 11 deletions. Single-driver surgical
  type fix.

Step 2.2: UNDERSTAND THE CODE FLOW CHANGE
Record:
- Before: thread functions are `void foo(struct rsi_common *common)` and
  are passed through `void *func_ptr` into `kthread_run()`.
- After: they are `int foo(void *data)` with `struct rsi_common *common
  = data;`. `rsi_create_kthread()` takes `int (*func_ptr)(void *data)`.
- Bodies are unchanged. They still end in
  `kthread_complete_and_exit(...)`, which is `__noreturn`.
- Path: kthread creation at driver init / coex attach, not an error-only
  path.

Step 2.3: IDENTIFY THE BUG MECHANISM
Record: [Type / CFI mismatch]
- `kthread()` does `ret = threadfn(data)` with type `int (*)(void *)`
  (`kernel/kthread.c`).
- Clang CFI hashes that type. `void (*)(struct rsi_common *)` has a
  different hash → CFI failure.
- Default `CONFIG_CFI_CLANG` (non-permissive) treats that as
  `BUG_TRAP_TYPE_BUG` (`kernel/cfi.c`).
- Fix: match the kthread callback ABI so the type hash matches.

Step 2.4: ASSESS THE FIX QUALITY
Record:
- Obviously correct: this is the documented kthread callback type.
- Minimal: signatures + one local cast; no locking/API/behavior change.
- Regression risk: very low. `kthread_complete_and_exit` is
  `__noreturn`, so no missing `return 0`. Johannes initially worried
  about “control reaches end of non-void function”; that does not apply.
- Red flags: none.

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

Step 3.1: BLAME THE CHANGED LINES
Record:
- `rsi_tx_scheduler_thread` / `rsi_create_kthread`: `dad0d04fa7ba41`
  (“rsi: Add RS9113 wireless driver”, 2014-03-17) — present since the
  driver was added.
- `rsi_coex_scheduler_thread`: `2108df3c4b1856` (“rsi: add coex
  support”, 2018-03-13).
- Long-lived bug, not recent churn.

Step 3.2: FOLLOW THE FIXES: TAG
Record: No Fixes: tag. Buggy pattern is original driver code, not a
later regression.

Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES
Record:
- Related in-tree: `16d9f674c6198` “wifi: rsi: fix kthread lifetime race
  between self-exit and external-stop” (already in this tree). That
  changes stop/wait, not signatures. No prerequisite conflict.
- This CFI fix is not in the tree (`git log --grep` on
  `drivers/net/wireless/rsi` found nothing).
- Standalone; v2 only added kernel-doc, not extra code deps.

Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS
Record: Stefan Hansson is not the rsi maintainer; patch is from
postmarketOS/Librem 5. Applied by Johannes Berg. No other rsi CFI
commits by this author in this tree.

Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS
Record: None. Uses existing `kthread_run` / `kthread_complete_and_exit`.
Can apply standalone.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION
Record:
- `b4 dig -c &lt;sha&gt;` not usable (candidate SHA not in this
  checkout).
- `b4 mbox` on msgid `20260804-rsi-cfi-
  fix-v2-1-59679a520240@postmarketos.org`: v2, 1-message thread.
- v1: https://patch.msgid.link/20260802-rsi-cfi-
  fix-v1-1-5821d2cb54ee@postmarketos.org
- v2 vs v1: kernel-doc only (`@common` → `@data`, `Return: 0`).
- Reviewers: Jeff Johnson (kernel-doc / From: vs SOB mismatch; said he
  was going to R-B after fixing many Android CFI type bugs). Johannes
  Berg first complained about nipa kernel-doc, then confirmed it builds,
  then applied v2. No NAK. No Cc: stable in review.

Step 4.2: CHECK WHO REVIEWED THE PATCH
Record: Recipients: linux-wireless, linux-kernel, phone-devel,
postmarketos/upstreaming. Maintainer Johannes Berg applied it. Jeff
Johnson (Qualcomm/ath) reviewed v1.

Step 4.3: SEARCH FOR THE BUG REPORT
Record: No syzbot/bugzilla. Concrete CFI log from Librem 5 downstream
`redpine_91x`. Same mismatch exists in mainline rsi (verified in this
tree).

Step 4.4: CHECK FOR RELATED PATCHES AND SERIES
Record: Single patch, v1→v2 kernel-doc only. Not a multi-patch series.

Step 4.5: CHECK STABLE MAILING LIST HISTORY
Record: lore.kernel.org/stable search returned 403. Web search found no
stable-list discussion of this CFI fix. No evidence it was rejected for
stable.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF
Record: `rsi_coex_scheduler_thread`, `rsi_tx_scheduler_thread`,
`rsi_sdio_rx_thread`, `rsi_usb_rx_thread`, `rsi_create_kthread`.

Step 5.2: TRACE CALLERS
Record:
- `rsi_create_kthread()` → `kthread_run(func_ptr, common, ...)`
- Callers: `rsi_91x_init` (Tx-Thread), `rsi_coex_attach` (Coex-Tx-
  Thread), SDIO probe (`rsi_sdio_rx_thread`), USB init
  (`rsi_usb_rx_thread`).
- Context: process context at probe/init, not IRQ.

Step 5.3: TRACE CALLEES
Record: `rsi_wait_event` / `rsi_reset_event`, TX/RX processing, then
`kthread_complete_and_exit`. No alloc/lock changes.

Step 5.4: FOLLOW THE CALL CHAIN
Record: Userspace-reachable via loading the rsi USB/SDIO module and
bringing the interface up. With CFI, failure is at kthread start
(`threadfn(data)` in `kthread()`), i.e. as soon as the driver creates
its threads.

Step 5.5: SEARCH FOR SIMILAR PATTERNS
Record: All four rsi kthread entry points had the same wrong type; this
patch fixes all of them. Precedent in-tree: `e1ea6db35fc3b` “wifi:
brcmsmac: avoid function pointer casts” (KCFI / clang-16). Jeff Johnson
noted many similar Android CFI callback-type fixes.

===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================

Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?
Record: Yes. Local tree is **6.12.111** (`git describe`:
`p-6.12-2-gd38d58a4e0359`). Current signatures are still `void
foo(struct rsi_common *)` and `void *func_ptr`. Introduced 2014/2018;
both are ancestors of HEAD. CFI exists here: `CONFIG_CFI_CLANG` in
`arch/Kconfig`; arm64/x86_64/arm select `ARCH_SUPPORTS_CFI_CLANG`.

Step 6.2: CHECK FOR BACKPORT COMPLICATIONS
Record: Context matches the patch hunks. Expected apply: **clean**.
Nearby `16d9f674c6198` does not touch these signatures.

Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE
Record: Kthread lifetime UAF fix is here; this CFI type fix is not. No
alternate CFI workaround in rsi.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY
Record: [wifi rsi / `drivers/net/wireless/rsi`] [PERIPHERAL] —
Redpine/Silabs RS911x USB/SDIO. Used on some phones/SBCs (Librem 5). Not
core mm/net. No dedicated MAINTAINERS entry; linux-wireless (Johannes
Berg) applied it.

Step 7.2: ASSESS SUBSYSTEM ACTIVITY
Record: Mature, low-churn driver with occasional stable-worthy fixes
(OOB, kthread UAF). Bug is old, not from recent refactor.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

Step 8.1: DETERMINE WHO IS AFFECTED
Record: Driver-specific + config-specific: `CONFIG_RSI_91X` and
`CONFIG_CFI_CLANG`. Default CFI is not permissive. CFI is common on
Android GKI and hardened/mobile builds; not in this tree’s arch
defconfigs.

Step 8.2: DETERMINE THE TRIGGER CONDITIONS
Record: Driver probe / thread create. Common if you have the hardware
and CFI. Unprivileged users do not set this up; loading the driver
(boot/hotplug) is enough. Not a race.

Step 8.3: DETERMINE THE FAILURE MODE SEVERITY
Record: Non-permissive CFI → `BUG_TRAP_TYPE_BUG` → kernel oops/panic
when the thread starts. WiFi (and coex BT) does not come up. Severity:
**HIGH** for CFI+rsi; **none** without CFI (wrong types happen to work
on normal ABIs).

Step 8.4: CALCULATE RISK-BENEFIT RATIO
Record:
- Benefit: prevents CFI panics on rsi probe; restores WiFi on CFI
  kernels.
- Risk: very low (~15 lines, type-only, no behavior change without CFI).
- Ratio: favorable. Small correctness fix, real crash for the configs
  that hit it.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

Step 9.1: COMPILE THE EVIDENCE
FOR:
- Real CFI failure log; default CFI is a kernel BUG.
- Buggy signatures are in this 6.12 tree and date to 2014/2018.
- Tiny, obviously correct ABI match to `kthread_run`.
- Applies cleanly; no deps.
- Johannes Berg applied v2; Jeff Johnson reviewed v1.
- Same class as other KCFI function-type fixes (e.g. brcmsmac).
- Real hardware path (Librem 5 / postmarketOS).

AGAINST:
- Only crashes with `CONFIG_CFI_CLANG`; most generic 6.12 distro configs
  leave CFI off.
- Niche driver; tested on downstream `redpine_91x`, not a mainline rsi
  repro (mainline still has the same types).
- No Fixes:/Cc: stable (not a negative by itself).
- No syzbot.

UNRESOLVED:
- Could not `b4 dig -c` a mainline SHA (commit not in this checkout).
- lore.kernel.org fetches returned 403; reviews recovered from
  openwall/lkml.iu.edu/spinics.
- No stable-list discussion found.

Step 9.2: APPLY THE STABLE RULES CHECKLIST
1. Obviously correct and tested? **PASS** — types match kthread API; CFI
   failure observed; maintainer applied v2.
2. Fixes a real bug that affects users? **PASS** — CFI kernels panic at
   rsi thread start.
3. Important issue? **PASS** — kernel BUG/panic (HIGH for CFI+rsi).
4. Small and contained? **PASS** — 7 files, ~26 lines, one driver.
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — 6.12.111 has the buggy code;
   context matches.

Step 9.3: CHECK FOR EXCEPTION CATEGORIES
Record: Not a device-ID/quirk/DT/docs exception. Closest: type-
correctness / CFI crash fix (normal stable bugfix).

Step 9.4: MAKE YOUR DECISION
This is a real, user-visible panic on CFI-enabled 6.12 systems that use
rsi, not a compiler-warning cleanup. The local tree has CFI and the
mismatched callbacks. The change is a surgical signature fix with
negligible regression risk. That meets the stable bar for this tree.

===============================================================
What the commit solves (for this tree)
===============================================================

On 6.12, `kthread()` indirectly calls the thread function as `int
(*)(void *)`. rsi hid `void (*)(struct rsi_common *)` behind `void
*func_ptr`. With `CONFIG_CFI_CLANG`, that is a type-hash mismatch and a
kernel BUG as soon as Tx/Rx/coex threads start. The patch makes the
callbacks match the kthread ABI. Without CFI the mismatch is latent;
with CFI it is a crash. Benefit vs risk is strongly in favor of
backporting.

Verification:
- [Phase 1] Parsed subject/tags/body: CFI failure log; SOB Hansson +
  Johannes Berg; Link to v2 msgid; no Fixes/Cc:stable/Reported-by
- [Phase 2] Diff: four thread fns `void (struct rsi_common *)` → `int
  (void *)`; `rsi_create_kthread` `void *` → `int (*)(void *)`; ~15/+11
  lines
- [Phase 2] `include/linux/kthread.h`: `kthread_run` /
  `kthread_create_on_node` take `int (*threadfn)(void *data)`
- [Phase 2] `kernel/kthread.c:389`: `ret = threadfn(data);` — CFI-
  checked indirect call
- [Phase 2] `kernel/cfi.c`: default non-permissive path returns
  `BUG_TRAP_TYPE_BUG`; `CFI_PERMISSIVE` is warn-only
- [Phase 2] `kthread_complete_and_exit` is `__noreturn` in
  `include/linux/kthread.h:101`
- [Phase 3] blame: `dad0d04fa7ba41` (2014) and `2108df3c4b1856` (2018);
  both ancestors of HEAD
- [Phase 3] `git log --grep='wifi: rsi: Fix types to appease CFI' --
  drivers/net/wireless/rsi`: not in this tree
- [Phase 3] Related `16d9f674c6198` kthread lifetime fix is already
  here; no signature overlap
- [Phase 4] `b4 mbox` msgid: v2 saved; v2 changelog = kernel-doc only;
  v1 Link in changelog
- [Phase 4] Jeff Johnson v1 review (openwall): kernel-doc; would R-B;
  Android CFI type-fix experience
- [Phase 4] Johannes Berg (lkml.iu.edu): nipa kernel-doc confusion, then
  confirmed build, applied
- [Phase 4] lore.kernel.org WebFetch: 403; stable-list discussion
  UNVERIFIED via lore
- [Phase 5] Callers: `rsi_91x_init`, `rsi_coex_attach`, SDIO probe, USB
  init — all `rsi_create_kthread`
- [Phase 6] `git describe HEAD` = `p-6.12-2-gd38d58a4e0359`; `make
  kernelversion` = 6.12.111
- [Phase 6] Current rsi files still have the old signatures; patch
  context matches
- [Phase 6] `CONFIG_CFI_CLANG` present; arm64/x86_64/arm support CFI
- [Phase 7] rsi has no MAINTAINERS stanza; linux-wireless took the patch
- [Phase 8] Failure mode: CFI BUG at kthread start, HIGH for CFI+rsi
- UNVERIFIED: mainline SHA (not in this checkout); whether Android GKI
  6.12 enables rsi; live mainline rsi CFI repro (same types verified
  here)

**YES**

 drivers/net/wireless/rsi/rsi_91x_coex.c     | 3 ++-
 drivers/net/wireless/rsi/rsi_91x_main.c     | 7 ++++---
 drivers/net/wireless/rsi/rsi_91x_sdio_ops.c | 3 ++-
 drivers/net/wireless/rsi/rsi_91x_usb_ops.c  | 7 ++++---
 drivers/net/wireless/rsi/rsi_common.h       | 2 +-
 drivers/net/wireless/rsi/rsi_sdio.h         | 2 +-
 drivers/net/wireless/rsi/rsi_usb.h          | 2 +-
 7 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_coex.c b/drivers/net/wireless/rsi/rsi_91x_coex.c
index 372eaaa2b9efc..05525d5e2edb1 100644
--- a/drivers/net/wireless/rsi/rsi_91x_coex.c
+++ b/drivers/net/wireless/rsi/rsi_91x_coex.c
@@ -50,8 +50,9 @@ static void rsi_coex_sched_tx_pkts(struct rsi_coex_ctrl_block *coex_cb)
 	} while (coex_q != RSI_COEX_Q_INVALID);
 }
 
-static void rsi_coex_scheduler_thread(struct rsi_common *common)
+static int rsi_coex_scheduler_thread(void *data)
 {
+	struct rsi_common *common = data;
 	struct rsi_coex_ctrl_block *coex_cb = common->coex_cb;
 	u32 timeout = EVENT_WAIT_FOREVER;
 
diff --git a/drivers/net/wireless/rsi/rsi_91x_main.c b/drivers/net/wireless/rsi/rsi_91x_main.c
index 2112d8d277a99..0b4d691580054 100644
--- a/drivers/net/wireless/rsi/rsi_91x_main.c
+++ b/drivers/net/wireless/rsi/rsi_91x_main.c
@@ -246,12 +246,13 @@ EXPORT_SYMBOL_GPL(rsi_read_pkt);
 /**
  * rsi_tx_scheduler_thread() - This function is a kernel thread to send the
  *			       packets to the device.
- * @common: Pointer to the driver private structure.
+ * @data: Pointer to the driver private structure.
  *
- * Return: None.
+ * Return: 0.
  */
-static void rsi_tx_scheduler_thread(struct rsi_common *common)
+static int rsi_tx_scheduler_thread(void *data)
 {
+	struct rsi_common *common = data;
 	struct rsi_hw *adapter = common->priv;
 	u32 timeout = EVENT_WAIT_FOREVER;
 
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
index 597b238e22949..18a28aa974460 100644
--- a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
+++ b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
@@ -62,8 +62,9 @@ int rsi_sdio_master_access_msword(struct rsi_hw *adapter, u16 ms_word)
 
 static void rsi_rx_handler(struct rsi_hw *adapter);
 
-void rsi_sdio_rx_thread(struct rsi_common *common)
+int rsi_sdio_rx_thread(void *data)
 {
+	struct rsi_common *common = data;
 	struct rsi_hw *adapter = common->priv;
 	struct rsi_91x_sdiodev *sdev = adapter->rsi_dev;
 
diff --git a/drivers/net/wireless/rsi/rsi_91x_usb_ops.c b/drivers/net/wireless/rsi/rsi_91x_usb_ops.c
index 25c2b232394a6..e899631b9aed2 100644
--- a/drivers/net/wireless/rsi/rsi_91x_usb_ops.c
+++ b/drivers/net/wireless/rsi/rsi_91x_usb_ops.c
@@ -21,12 +21,13 @@
 /**
  * rsi_usb_rx_thread() - This is a kernel thread to receive the packets from
  *			 the USB device.
- * @common: Pointer to the driver private structure.
+ * @data: Pointer to the driver private structure.
  *
- * Return: None.
+ * Return: 0.
  */
-void rsi_usb_rx_thread(struct rsi_common *common)
+int rsi_usb_rx_thread(void *data)
 {
+	struct rsi_common *common = data;
 	struct rsi_hw *adapter = common->priv;
 	struct rsi_91x_usbdev *dev = adapter->rsi_dev;
 	int status;
diff --git a/drivers/net/wireless/rsi/rsi_common.h b/drivers/net/wireless/rsi/rsi_common.h
index c40f8101febcb..4f6738ba72be2 100644
--- a/drivers/net/wireless/rsi/rsi_common.h
+++ b/drivers/net/wireless/rsi/rsi_common.h
@@ -58,7 +58,7 @@ static inline void rsi_reset_event(struct rsi_event *event)
 
 static inline int rsi_create_kthread(struct rsi_common *common,
 				     struct rsi_thread *thread,
-				     void *func_ptr,
+				     int (*func_ptr)(void *data),
 				     u8 *name)
 {
 	init_completion(&thread->completion);
diff --git a/drivers/net/wireless/rsi/rsi_sdio.h b/drivers/net/wireless/rsi/rsi_sdio.h
index 7c91b126b350f..eb2b7f36a7e4c 100644
--- a/drivers/net/wireless/rsi/rsi_sdio.h
+++ b/drivers/net/wireless/rsi/rsi_sdio.h
@@ -134,5 +134,5 @@ int rsi_sdio_master_access_msword(struct rsi_hw *adapter, u16 ms_word);
 void rsi_sdio_ack_intr(struct rsi_hw *adapter, u8 int_bit);
 int rsi_sdio_determine_event_timeout(struct rsi_hw *adapter);
 int rsi_sdio_check_buffer_status(struct rsi_hw *adapter, u8 q_num);
-void rsi_sdio_rx_thread(struct rsi_common *common);
+int rsi_sdio_rx_thread(void *data);
 #endif
diff --git a/drivers/net/wireless/rsi/rsi_usb.h b/drivers/net/wireless/rsi/rsi_usb.h
index 961851748bc4c..78067eaffe8b1 100644
--- a/drivers/net/wireless/rsi/rsi_usb.h
+++ b/drivers/net/wireless/rsi/rsi_usb.h
@@ -81,5 +81,5 @@ static inline int rsi_usb_event_timeout(struct rsi_hw *adapter)
 	return EVENT_WAIT_FOREVER;
 }
 
-void rsi_usb_rx_thread(struct rsi_common *common);
+int rsi_usb_rx_thread(void *data);
 #endif
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18] wifi: mt76: mt7603: restore hardware PS buffering after a service period
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (36 preceding siblings ...)
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-6.6] wifi: rsi: Fix types to appease CFI Sasha Levin
@ 2026-10-19 13:52 ` Sasha Levin
  2026-10-19 13:53 ` [PATCH AUTOSEL 6.18-5.15] wifi: iwlwifi: mvm: reset the smart fifo state upon FW stop Sasha Levin
                   ` (2 subsequent siblings)
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:52 UTC (permalink / raw)
  To: patches, stable
  Cc: Felix Fietkau, Sasha Levin, lorenzo, ryder.lee, matthias.bgg,
	angelogioacchino.delregno, linux-wireless, linux-kernel,
	linux-arm-kernel, linux-mediatek

From: Felix Fietkau <nbd@nbd.name>

[ Upstream commit 636a883e2feef5e4ff95695d3c372ceff03960f5 ]

Releasing buffered frames has to turn off the PSE redirect for the
station, otherwise the released frames are looped straight back into the
driver PS queue. Nothing ever turns it back on: mt7603_sta_ps() only runs
on an observed PM bit transition, and MT_WCID_FLAG_PS keeps mt76 from
reporting the same state twice. After the first service period the
hardware therefore treats a dozing station as awake and transmits at it
directly, which is where the retry storms and the packet loss reported
against U-APSD clients come from.

Re-arm hardware buffering from mt7603_mac_work() for every station that
is still known to be asleep, once the PSD queue has drained and the
released frames have passed the redirect stage. Frames that are still
queued belong to the service period that was just served, so unlike on a
sleep transition they must not be pulled back with mt7603_filter_tx().

Track the sleep state separately from the WTBL state, so a station that
wakes up while the re-arm is pending is not put back to sleep.

Link: https://patch.msgid.link/20260801145334.1166751-7-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

I have enough to judge this against 5.15.221: the bug is in this tree,
the fix is real, and it needs a small mechanical backport rather than
missing code.

---

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: PARSE THE SUBJECT LINE**
Record: **[wifi: mt76: mt7603:] [restore] [re-arm hardware PS buffering
after a U-APSD/PS-Poll service period]**

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- `Link: https://patch.msgid.link/20260801145334.1166751-7-nbd@nbd.name`
  — this is **patch 07/10** of Felix Fietkau’s series
- `Signed-off-by: Felix Fietkau <nbd@nbd.name>` — mt76 maintainer
  (ignore any Sasha Levin SOB)
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Acked-
  by:`, or `Cc: stable` (absence expected)

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** Releasing buffered frames disables PSE redirect
  (`mt7603_wtbl_set_ps(..., false)`). Nothing turns it back on:
  `mt7603_sta_ps()` only runs on a PM-bit edge, and `MT_WCID_FLAG_PS`
  suppresses duplicate notifications.
- **Symptom:** After the first service period the HW treats a dozing STA
  as awake, TX goes to a sleeping radio → **retry storms and packet
  loss** on U-APSD clients.
- **Root cause:** Missing re-arm of hardware PS buffering after an SP;
  sleep state was conflated with WTBL PS state.
- **Fix:** Re-arm from `mt7603_mac_work()` once the PSD queue has
  drained; do not `mt7603_filter_tx()` on that re-arm; track
  `ps_sleeping` separately.

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not a disguised cleanup. This is an explicit functional bug fix.

---

## PHASE 2: DIFF ANALYSIS - LINE BY LINE

**Step 2.1: INVENTORY THE CHANGES**
Record:
- `mac.c`: +~70 / −~7 — split `mt7603_wtbl_set_ps`, add
  `__mt7603_wtbl_set_ps`, `mt7603_wtbl_sta_ps`,
  `mt7603_wtbl_restore_ps`, `mt7603_mac_ps_check`; call it from
  `mt7603_mac_work`
- `main.c`: 1 line — `mt7603_sta_ps()` uses `mt7603_wtbl_sta_ps`
- `mt7603.h`: `u8 ps_sleeping` plus two prototypes
- Scope: **single-driver surgical fix** (~72/7, 3 files)

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:
- Before: `mt7603_wtbl_set_ps(true)` enables PSE redirect + `filter_tx`;
  `false` disables both. `release_buffered_frames` / PS-response TX
  force `false` and never restore.
- After: `sta_ps` also sets `ps_sleeping`. Temporary WTBL-off (SP)
  leaves `ps_sleeping` true. `mac_work` (100 ms) walks stations; if `!ps
  && ps_sleeping` and PSD is empty, re-enables redirect **without**
  pulling in-flight SP frames back via `filter_tx`.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record: **Logic / hardware-state correctness.** HW PS filter left off
after an SP. Not UAF/leak/race in the sanitizer sense; it is a driver
state-machine bug with airtime/retry fallout.

**Step 2.4: ASSESS THE FIX QUALITY**
Record: Quality is high. `ps_sleeping` is updated under `ps_lock`;
`restore_ps` re-checks it under the same lock so a wakeup cannot put the
STA back to sleep. `filter=false` on restore is required so SP frames
are not recycled. Risk: extra WTBL/PSE MMIO from mac_work (low; only
stations that need re-arm). No public API change.

---

## PHASE 3: GIT HISTORY INVESTIGATION

**Step 3.1: BLAME THE CHANGED LINES**
Record:
- `mt7603_wtbl_set_ps` from `c8846e1015022d` (2019-02-26) — initial
  MT7603 driver, **in this tree**
- The off-without-restore came from `f25e813bf48dce` (2019-03-07) “clear
  ps filtering mode before releasing buffered frames” — **in this tree**
  (`git merge-base --is-ancestor` exit 0). That commit is what made SPs
  work at all; it never re-armed.

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No `Fixes:` tag. Bug-introducing commit is `f25e813bf48dce`,
present here.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record: Candidate is `636a883e2feef` (not in HEAD). Series around it:
1. `a547b414bf7ea` — **new feature** `MT_DRV_HW_PS_BUFFERING` (other
   chips)
2–3. mt7915/mt7996 MCU PS sync
4. EOSP bit in `mt76_release_buffered_frames`
5. `fix U-APSD service period termination` (mt7603 `main.c`)
6. tell mac80211 when PS queue is empty
7. **this commit**
8. file buffered frames under the reported TID
9–10. mt76 link-id / mt7996 OOB

This commit does **not** call anything those others add. Sibling 4–6 fix
other U-APSD bugs; they are complementary, not compile/runtime
prerequisites.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Felix Fietkau is the mt76 maintainer and original mt7603 author.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: Mainline uses `mt76_wcid_ptr` (`dc66a129adf1f`, 2025, **not
here**) and 4-arg `mt7603_filter_tx(dev, sta->vif->idx, idx, ...)`
(`fe0ea395f0a35`, 2023, **not here**). In 5.15, `msta->vif` is **never
assigned**. A correct backport is: 3-arg `mt7603_filter_tx(dev, idx,
false)` and `rcu_dereference(dev->mt76.wcid[i])`. Logic does not need
those later commits.

---

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- `b4 dig -c 636a883e2feef` →
  https://patch.msgid.link/20260801145334.1166751-7-nbd@nbd.name
- Series v1 only (`b4 dig -a`): `[PATCH 01/10] wifi: mt76: add PS
  buffering support for HW-managed TIM drivers`
- Thread: no NAK on patch 07; only kbuild noise on patch 10
  (`ieee80211_txq_aql_pending`), unrelated to mt7603
- lore.kernel.org HTTP 403 for WebFetch/curl; discussion recovered via
  `b4 dig -m`

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record: `b4 dig -w`: Felix Fietkau, `linux-wireless@vger.kernel.org`. No
extra Reviewed-by. Author is the subsystem maintainer.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: OpenWrt **mt76#1080** (closed 2026-08-01, same day as this
series): MT7628AN AP, iPhone/U-APSD, Wi-Fi “hangs”, thousands of TX
retries, packet loss; workaround was forcing legacy b/g. Related reports
#865, #576, #390, #841, #375, #26. PR #1084: EOSP helped iPhone freezes;
**retries/loss remained as a separate bug**. Commit text matches that
remaining failure (“retry storms and the packet loss reported against
U-APSD clients”).

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: 10-patch series. 01 is a new mt76 feature; 07 is a standalone
mt7603 HW-PS re-arm. Full iPhone/U-APSD recovery also wants 04–06/08; 07
still fixes a distinct, real bug.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: **UNVERIFIED** — lore.kernel.org/stable returned 403.

---

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1: IDENTIFY KEY FUNCTIONS**
Record: `mt7603_wtbl_set_ps` → `__mt7603_wtbl_set_ps`; added
`mt7603_wtbl_sta_ps`, `mt7603_wtbl_restore_ps`, `mt7603_mac_ps_check`;
`mt7603_sta_ps`; `mt7603_mac_work`.

**Step 5.2: TRACE CALLERS**
Record (this tree):
- `mt7603_sta_ps` ← `mt76_check_sta()` via `drv->sta_ps` on RX PM-bit
  change
- `mt7603_wtbl_set_ps(false)` still used by
  `mt7603_release_buffered_frames` and `mt7603_tx_prepare_skb` (PS
  response) — those are the paths that drop HW buffering
- `mt7603_mac_work` — delayed work every `MT7603_WATCHDOG_TIME` (100 ms)

**Step 5.3: TRACE CALLEES**
Record: PSE_RTA write + poll, optional `mt7603_filter_tx`, WTBL1
POWER_SAVE bit, `ps_lock`. Restore skips `filter_tx`.

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: Userspace-reachable: STA in PS/U-APSD associated to an
mt7603/MT7628 AP → mac80211 `.release_buffered_frames` / PS-Poll. **Yes,
unprivileged clients trigger this.**

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: Same “turn off PS to release frames” exists in `tx_prepare_skb`;
`ps_sleeping` covers that too because it is only cleared on a real wake.

---

## PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: **Yes.** Tree is **5.15.221** (`pending-5.15`,
`p-5.15-2-g6703e5d2f3a29`).
- `mt7603_release_buffered_frames` still does `mt7603_wtbl_set_ps(dev,
  msta, false)` (`main.c:434`)
- `mt76_check_sta` still uses `MT_WCID_FLAG_PS` to skip duplicate
  `sta_ps`
- `636a883e2feef` is **not** an ancestor of HEAD

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: `git show 636a883e2feef | git apply --check` **fails**. Needed
adaptations:
1. `mt7603_filter_tx(dev, sta->vif->idx, idx, false)` →
   `mt7603_filter_tx(dev, idx, false)` (3-arg; `msta->vif` unused here)
2. `mt76_wcid_ptr(dev, i)` → `rcu_dereference(dev->mt76.wcid[i])`
3. `mac_work` context differs (`mt76_tx_status_check` arity,
   `aggr_stats` location) — insertion after `mt7603_edcca_check` is
   still valid

`main.c` hunk and `ps_sleeping` field apply. **Backport difficulty:
minor rework, not a redesign.**

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: No `ps_sleeping` / `mac_ps_check` / `wtbl_restore_ps` in this
tree. Older PS commits here (`e004b70066002`, `9dc27bcbe78c5`,
`d55aa5e17461b`) do not re-arm after an SP.

---

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: **drivers/net/wireless/mediatek/mt76/mt7603** —
**PERIPHERAL/IMPORTANT for that hardware.** MT7603E/MT7628 is common on
low-end APs/routers (`CONFIG_MT7603E`). Not core mm/fs, but AP mode with
phones is a primary use.

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: Mature driver (landed 2019). Little 5.15-era churn; the bug is
long-lived.

---

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: **Driver-specific:** mt7603/MT7628 in AP mode with power-
save/U-APSD clients (iPhones and similar).

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record: First PS-Poll or U-APSD SP after the client dozes. Common on
phones (Instagram/video in #1080). Unprivileged associated STAs trigger
it.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record: **HIGH** (not kernel oops). Retry storms, packet loss, AP
“hangs” vs PS clients; wasted airtime can hurt the whole BSS. Users had
to force legacy b/g.

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record: **Benefit: high** for that hardware. **Risk: low–medium**
(contained MMIO + lock; `ps_sleeping` handles races). Blind 4-arg/`vif`
apply would be wrong here; a 3-arg + `rcu_dereference` backport is safe.

---

## PHASE 9: FINAL SYNTHESIS

**Step 9.1: COMPILE THE EVIDENCE**

**FOR:**
- Real, old bug in this tree (`f25e813bf48dce`, 2019)
- User-visible: retry storms, loss, Wi-Fi hangs with U-APSD/iPhone
  (OpenWrt #1080 and several older issues)
- Small, mt7603-only, maintainer-authored, logic is clear
- Standalone vs series patches 01–06
- Trigger is normal AP + phone PS

**AGAINST:**
- 07/10 in a series that also adds a new mt76 feature
- Does not apply cleanly (filter_tx arity, `mt76_wcid_ptr`, mac_work
  context)
- Full U-APSD repair also wants 04–06; 07 is not the entire story
- Not a kernel crash/security/corruption bug

**UNRESOLVED:** stable@ lore (HTTP 403). No Tested-by on the commit
itself; OpenWrt #1080 was closed the day the series landed.

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — maintainer fix; matches a
   long-standing user report
2. Fixes a real bug that affects users? **PASS**
3. Important issue? **PASS** — AP unusable with PS phones / BSS retry
   storms (HIGH, not oops)
4. Small and contained? **PASS** — ~70 lines, one driver
5. No new features or APIs? **PASS** — internal state + helpers
6. Can apply to the local tree? **PASS** with a small backport (not a
   clean cherry-pick)

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: None (not a device ID/quirk/DT/build/doc exception). Qualifies
as a normal driver bug fix.

**Step 9.4: MAKE YOUR DECISION**
The buggy “disable PSE redirect on SP, never re-arm” path is in
5.15.221. That is a real AP-mode failure for mt7603/MT7628, not a new-
stack issue. The patch is the right fix and is adaptable without pulling
the HW_PS_BUFFERING feature series.

---

### What the commit solves and why it matters here
After a service period, mt7603 leaves hardware PS buffering off. The AP
then TX’s at a dozing client → retries and loss. That code has been in
this tree since 2019. MT7628 APs with phones hit it in the real world.

### Stable rules
Meets the bar: real bug, contained, no new API. Needs a mechanical
backport (`filter_tx` 3-arg, `rcu_dereference` instead of
`mt76_wcid_ptr`), which is allowed.

### Risk vs benefit
Benefit is high for mt7603 AP users; risk is low if the backport does
**not** use `sta->vif` (unset in 5.15). Sibling EOSP/TIM patches would
help more U-APSD cases but are not required for this re-arm.

### Concerns
Cherry-pick will not apply as-is. Do not copy the 4-argument
`mt7603_filter_tx(..., sta->vif->idx, ...)` call into this tree.

---

Verification:
- [Phase 1] Subject/body/tags: restore HW PS after SP; Link is 07/10;
  maintainer SOB only
- [Phase 2] Diff: ~72/7 in mt7603 mac.c/main.c/mt7603.h; `ps_sleeping` +
  mac_work re-arm
- [Phase 3] `git describe HEAD` / Makefile: 5.15.221, branch
  `pending-5.15`
- [Phase 3] `git merge-base --is-ancestor 636a883e2feef HEAD` → not in
  tree
- [Phase 3] blame: `c8846e1015022d` (driver), `f25e813bf48dce` (clear PS
  before release) — both ancestors of HEAD
- [Phase 3] Related series commits listed; 01 is new feature; 07 does
  not call those APIs
- [Phase 4] `b4 dig -c 636a883e2feef` / `-a` / `-w` / `-m`: lore thread,
  v1-only series, wireless list, no NAK on 07
- [Phase 4] OpenWrt mt76#1080 / #1084: retry storms + iPhone U-APSD;
  issue closed 2026-08-01
- [Phase 5] Callers verified in 5.15: `sta_ps`,
  `release_buffered_frames`, `tx_prepare_skb`, `mac_work` 100 ms
- [Phase 6] Local `mt7603_wtbl_set_ps` / `release_buffered_frames` still
  match the bug; `mt76_wcid_ptr` absent; `filter_tx` is 3-arg;
  `msta->vif` never set
- [Phase 6] `git apply --check` of 636a883e2feef fails on filter_tx/wcid
  helper; main.c hunk would apply
- [Phase 8] Failure mode: retry storms / packet loss / AP hang vs PS
  clients, severity HIGH
- UNVERIFIED: stable@ mailing-list discussion (lore 403)

**YES**

 .../net/wireless/mediatek/mt76/mt7603/mac.c   | 73 +++++++++++++++++--
 .../net/wireless/mediatek/mt76/mt7603/main.c  |  2 +-
 .../wireless/mediatek/mt76/mt7603/mt7603.h    |  4 +
 3 files changed, 72 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
index 6387f9e61060a..85c727fc44e6f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
@@ -235,16 +235,17 @@ void mt7603_wtbl_set_smps(struct mt7603_dev *dev, struct mt7603_sta *sta,
 	sta->smps = enabled;
 }
 
-void mt7603_wtbl_set_ps(struct mt7603_dev *dev, struct mt7603_sta *sta,
-			bool enabled)
+static void
+__mt7603_wtbl_set_ps(struct mt7603_dev *dev, struct mt7603_sta *sta,
+		     bool enabled, bool filter)
 {
 	int idx = sta->wcid.idx;
 	u32 addr;
 
-	spin_lock_bh(&dev->ps_lock);
+	lockdep_assert_held(&dev->ps_lock);
 
 	if (sta->ps == enabled)
-		goto out;
+		return;
 
 	mt76_wr(dev, MT_PSE_RTA,
 		FIELD_PREP(MT_PSE_RTA_TAG_ID, idx) |
@@ -255,7 +256,7 @@ void mt7603_wtbl_set_ps(struct mt7603_dev *dev, struct mt7603_sta *sta,
 
 	mt76_poll(dev, MT_PSE_RTA, MT_PSE_RTA_BUSY, 0, 5000);
 
-	if (enabled)
+	if (enabled && filter)
 		mt7603_filter_tx(dev, sta->vif->idx, idx, false);
 
 	addr = mt7603_wtbl1_addr(idx);
@@ -264,8 +265,34 @@ void mt7603_wtbl_set_ps(struct mt7603_dev *dev, struct mt7603_sta *sta,
 		 enabled * MT_WTBL1_W3_POWER_SAVE);
 	mt76_clear(dev, MT_WTBL1_OR, MT_WTBL1_OR_PSM_WRITE);
 	sta->ps = enabled;
+}
 
-out:
+void mt7603_wtbl_set_ps(struct mt7603_dev *dev, struct mt7603_sta *sta,
+			bool enabled)
+{
+	spin_lock_bh(&dev->ps_lock);
+	__mt7603_wtbl_set_ps(dev, sta, enabled, enabled);
+	spin_unlock_bh(&dev->ps_lock);
+}
+
+void mt7603_wtbl_sta_ps(struct mt7603_dev *dev, struct mt7603_sta *sta, bool ps)
+{
+	spin_lock_bh(&dev->ps_lock);
+	sta->ps_sleeping = ps;
+	__mt7603_wtbl_set_ps(dev, sta, ps, ps);
+	spin_unlock_bh(&dev->ps_lock);
+}
+
+void mt7603_wtbl_restore_ps(struct mt7603_dev *dev, struct mt7603_sta *sta)
+{
+	spin_lock_bh(&dev->ps_lock);
+	/*
+	 * Frames that are already queued for the station belong to the service
+	 * period that has just been served, so unlike on a sleep transition
+	 * they must not be pulled back into the PS queue.
+	 */
+	if (sta->ps_sleeping)
+		__mt7603_wtbl_set_ps(dev, sta, true, false);
 	spin_unlock_bh(&dev->ps_lock);
 }
 
@@ -1816,6 +1843,39 @@ mt7603_false_cca_check(struct mt7603_dev *dev)
 	mt7603_adjust_sensitivity(dev);
 }
 
+/*
+ * Releasing buffered frames turns off the PSE redirect for a station, since
+ * the released frames would otherwise be looped back into the driver PS queue
+ * again. mac80211 never tells us when the service period is over, so hardware
+ * buffering has to be re-armed here for every station that is still known to
+ * be asleep. Waiting for the PSD queue to drain makes sure that the released
+ * frames have already passed the redirect stage.
+ */
+static void
+mt7603_mac_ps_check(struct mt7603_dev *dev)
+{
+	int i;
+
+	if (dev->mphy.q_tx[MT_TXQ_PSD]->queued)
+		return;
+
+	rcu_read_lock();
+	for (i = 0; i < MT7603_WTBL_STA; i++) {
+		struct mt76_wcid *wcid = mt76_wcid_ptr(dev, i);
+		struct mt7603_sta *msta;
+
+		if (!wcid || !wcid->sta)
+			continue;
+
+		msta = container_of(wcid, struct mt7603_sta, wcid);
+		if (msta->ps || !msta->ps_sleeping)
+			continue;
+
+		mt7603_wtbl_restore_ps(dev, msta);
+	}
+	rcu_read_unlock();
+}
+
 void mt7603_mac_work(struct work_struct *work)
 {
 	struct mt7603_dev *dev = container_of(work, struct mt7603_dev,
@@ -1830,6 +1890,7 @@ void mt7603_mac_work(struct work_struct *work)
 	dev->mphy.mac_work_count++;
 	mt76_update_survey(&dev->mphy);
 	mt7603_edcca_check(dev);
+	mt7603_mac_ps_check(dev);
 
 	for (i = 0, idx = 0; i < 2; i++) {
 		u32 val = mt76_rr(dev, MT_TX_AGG_CNT(i));
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/main.c b/drivers/net/wireless/mediatek/mt76/mt7603/main.c
index f8a43d9f72f95..04e3966ab047f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/main.c
@@ -410,7 +410,7 @@ mt7603_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps)
 	struct sk_buff_head list;
 
 	mt76_stop_tx_queues(&dev->mphy, sta, true);
-	mt7603_wtbl_set_ps(dev, msta, ps);
+	mt7603_wtbl_sta_ps(dev, msta, ps);
 	if (ps)
 		return;
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
index 55a034ccbacd9..c43ddd3e693c0 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
@@ -80,6 +80,7 @@ struct mt7603_sta {
 	u8 smps;
 
 	u8 ps;
+	u8 ps_sleeping;
 };
 
 struct mt7603_vif {
@@ -229,6 +230,9 @@ int mt7603_wtbl_set_key(struct mt7603_dev *dev, int wcid,
 			struct ieee80211_key_conf *key);
 void mt7603_wtbl_set_ps(struct mt7603_dev *dev, struct mt7603_sta *sta,
 			bool enabled);
+void mt7603_wtbl_sta_ps(struct mt7603_dev *dev, struct mt7603_sta *sta,
+			bool ps);
+void mt7603_wtbl_restore_ps(struct mt7603_dev *dev, struct mt7603_sta *sta);
 void mt7603_wtbl_set_smps(struct mt7603_dev *dev, struct mt7603_sta *sta,
 			  bool enabled);
 void mt7603_filter_tx(struct mt7603_dev *dev, int mac_idx, int idx, bool abort);
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18-5.15] wifi: iwlwifi: mvm: reset the smart fifo state upon FW stop
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (37 preceding siblings ...)
  2026-10-19 13:52 ` [PATCH AUTOSEL 6.18] wifi: mt76: mt7603: restore hardware PS buffering after a service period Sasha Levin
@ 2026-10-19 13:53 ` Sasha Levin
  2026-10-19 13:53 ` [PATCH AUTOSEL 6.18-5.10] wifi: mac80211: ibss: read deauth reason_code after frame length check Sasha Levin
  2026-10-19 13:53 ` [PATCH AUTOSEL 6.18-5.10] wifi: brcmfmac: validate msgbuf flowring IDs before use Sasha Levin
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:53 UTC (permalink / raw)
  To: patches, stable
  Cc: Emmanuel Grumbach, Miri Korenblit, Sasha Levin, linux-wireless,
	linux-kernel

From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>

[ Upstream commit a51cc8131214870af92abbceab64877b27e690c2 ]

The smart fifo is a feature in the firmware configured by the driver.
The driver keeps a state to remember what was the last configuration
sent to the firmware. Obviously, if the firmware stops, we need to
reconfigure the smart fifo. Since we didn't reset that state upon
firmware stop, we thought the firmware is already properly
configured and we didn't send the smart fifo configuration command
as part of the init sequence.

Reset the smart fifo state in iwl_mvm_stop_device() so that we
will properly send the command during the init that will come
later.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Link: https://patch.msgid.link/20260714165826.7d3c5efe2d1a.I16b23c328a677257257f695fa6f439e41fbcd081@changeid
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: PARSE THE SUBJECT LINE**
Record: **[iwlwifi/mvm] [reset] [clear cached smart-fifo state when
firmware is stopped]**

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- **Fixes:** none (expected for this review)
- **Reported-by / Tested-by / Reviewed-by / Acked-by:** none
- **Link:** `https://patch.msgid.link/20260714165826.7d3c5efe2d1a.I16b23
  c328a677257257f695fa6f439e41fbcd081@changeid`
- **Cc: stable:** none (expected)
- **Signed-off-by:** Emmanuel Grumbach (author; Intel iwlwifi), Miri
  Korenblit (iwlwifi maintainer, committer)
- No syzbot, no CVE, no stack trace

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** Driver caches last smart-fifo config in `mvm->sf_state`.
  Firmware stop does not clear that cache.
- **Symptom:** After firmware is stopped and started again, init skips
  `REPLY_SF_CFG_CMD` because the driver thinks firmware is already
  configured.
- **Version info:** none
- **Root cause:** Stale driver-side firmware-config cache after the
  firmware image is gone.

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not a disguised cleanup. It is an explicit correctness fix for
stale cached firmware state.

---

## PHASE 2: DIFF ANALYSIS

**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `drivers/net/wireless/intel/iwlwifi/mvm/ops.c` (+1 / −0)
- Function: `iwl_mvm_stop_device()`
- Scope: single-file, one-line surgical fix

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record:
- **Before:** `iwl_mvm_stop_device()` cleared
  `IWL_MVM_STATUS_FIRMWARE_RUNNING`, paused TCM, stopped the transport,
  and freed paging. `sf_state` was left as-is.
- **After:** Immediately after clearing FIRMWARE_RUNNING, set
  `mvm->sf_state = SF_UNINIT`.
- Path: every firmware stop (mac stop, restart cleanup, D3 switch, init-
  ucode teardown, load error paths). Not an error-only path.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record: **Logic / correctness — stale cached firmware configuration**

Verified skip in `iwl_mvm_sf_config()`:

```183:188:drivers/net/wireless/intel/iwlwifi/mvm/sf.c
        /*
  - If an associated AP sta changed its antenna configuration, the state
  - will remain FULL_ON but SF parameters need to be reconsidered.
         */
        if (new_state != SF_FULL_ON && mvm->sf_state == new_state)
                return 0;
```

Init always tries to configure SF:

```1761:1763:drivers/net/wireless/intel/iwlwifi/mvm/fw.c
        ret = iwl_mvm_sf_update(mvm, NULL, false);
        if (ret)
                IWL_ERR(mvm, "Failed to initialize Smart Fifo\n");
```

With `changed_vif == NULL` and no active MACs, that becomes
`SF_INIT_OFF`. If `sf_state` is still `SF_INIT_OFF` from the previous
firmware life, the command is skipped and new firmware keeps reset
defaults.

**Step 2.4: ASSESS THE FIX QUALITY**
Record:
- Obviously correct: firmware is gone, cached config must be invalid.
- Minimal: one assignment under `mvm->mutex` (`lockdep_assert_held`).
- Regression risk: very low. On firmware with
  `IWL_UCODE_TLV_API_SMART_FIFO_OFFLOAD` (commit `ff04f78ce38d7`, 2024),
  `iwl_mvm_sf_update()` already returns 0 and never sends the command;
  resetting the cache is a no-op there.

---

## PHASE 3: GIT HISTORY INVESTIGATION

**Step 3.1: BLAME THE CHANGED LINES**
Record:
- Surrounding `iwl_mvm_stop_device()` body: `cf5b462768474` (2020, moved
  out of line).
- Smart FIFO and `sf_state` skip logic: `1f3b0ff8eccef` (“iwlwifi: mvm:
  Add Smart FIFO support”, 2013-12-17, contained in v3.14-rc1).
- Bug has been present for a long time; not recent code.

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No `Fixes:` tag. Buggy pattern is the original 2013 SF cache
plus the skip-if-same-state optimization, not a recent regression.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record:
- Nearby same-author series (same Change-Id date 20260714165826):
  - `0a00c3ec2db76` device_powered_off → `iwl_mvm_restart_cleanup()`
    (independent)
  - `71ac392d8b5c2` MLD analogue (different driver)
- This patch does not depend on those.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Emmanuel Grumbach is a long-time Intel iwlwifi core author. Miri
Korenblit is the listed iwlwifi maintainer. High confidence in the
diagnosis.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: Standalone. Needs only `mvm->sf_state` and `SF_UNINIT`, both
present here. No new helpers or struct fields.

---

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- `b4 dig -c a51cc81312148`: matched `[PATCH iwlwifi-next 13/15]`
- URL: `https://patch.msgid.link/20260714143119.7d3c5efe2d1a.I16b23c328a
  677257257f695fa6f439e41fbcd081@changeid`
- `b4 dig -a`: v1 (`20260714143119`) and v2 (`20260714165826`, the
  applied Link:). This hunk is identical in v1/v2.
- Series title: “wifi: iwlwifi: updates - 07-14-2026” (15 patches mixing
  features and fixes). This one is self-contained.
- Saved mbox had the series posts, no replies/NAKs on this patch. No
  `Cc: stable` in review.

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record (`b4 dig -w`): To Johannes Berg; Cc linux-
wireless@vger.kernel.org and Emmanuel Grumbach. Committed by maintainer
Miri Korenblit. No extra Reviewed-by on this patch.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: No Reported-by, bugzilla, or syzbot. Failure mode is inferred
from code + commit text, not a user crash report.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: Patch 13/15. Follow-ups 14/15 and 15/15 are related
stop/recovery cleanup but not prerequisites. This line is independently
correct.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: lore.kernel.org/stable search blocked by anti-bot (403).
UNVERIFIED whether it was previously requested or rejected for stable.

---

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1: KEY FUNCTIONS**
Record: `iwl_mvm_stop_device()` (modified). Related:
`iwl_mvm_sf_config()`, `iwl_mvm_sf_update()`, `iwl_mvm_up()`.

**Step 5.2: TRACE CALLERS**
Record: `iwl_mvm_stop_device()` is called from:
- `ops.c` NVM/init-ucode teardown
- `mac80211.c` `iwl_mvm_restart_cleanup()`, `__iwl_mvm_mac_start()`
  fast-resume fail, `__iwl_mvm_mac_stop()`
- `fw.c` `iwl_mvm_up()` / `iwl_mvm_load_d3_fw()` error paths
- `d3.c` `iwl_mvm_switch_to_d3()`

Reachable from interface down, rfkill/stop, suspend (non-fast), firmware
restart, and probe/init teardown. Common laptop WiFi paths.

**Step 5.3: TRACE CALLEES**
Record: Stop path tears down firmware/transport. The new line only
writes a field; no new I/O.

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: Userspace `ip link set wlan0 down/up`, rfkill, suspend/resume,
and mac80211 restart all hit this. Bug is reachable without special
debug options.

Nuance (verified): `SF_FULL_ON` is never skipped, so association still
sends SF config. The missed command is the init/unassociated
`SF_INIT_OFF` after a stop that left `sf_state == SF_INIT_OFF` (typical
after disconnect then ifdown, or never-associated then wifi toggle).
During `IWL_MVM_STATUS_IN_HW_RESTART`, `iwl_mvm_sf_update()` returns
early anyway; this reset still makes post-restart updates send when
restart completes.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: Same series resets other driver state after firmware death
(`device_powered_off`, MLD recovery). `sf_state` was the one cache not
cleared on stop. No duplicate fix already present besides this commit.

---

## PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record:
- Local tree: `git describe HEAD` → **v7.3-rc4-27-gf0100363d8c37**;
  `make kernelversion` → **7.3.0-rc4**
- `sf_state`, skip-if-same-state, and `iwl_mvm_up()` SF init all exist
- Bug introduced with Smart FIFO in 2013 (`1f3b0ff8eccef`); ancestor of
  this HEAD

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: Clean apply. Pre-fix `iwl_mvm_stop_device()` already has the
insertion point next to `clear_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING,
...)`. Expected difficulty: clean apply.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: No earlier equivalent reset of `sf_state` on stop. Only the
start-time `mvm->sf_state = SF_UNINIT` in `iwl_op_mode_mvm_start()`
(probe), which does not cover later stop/start cycles.

---

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: SUBSYSTEM AND CRITICALITY**
Record: **wifi / iwlwifi mvm**. **IMPORTANT** — Intel WiFi is one of the
most common laptop NICs. Not core mm/VFS, but far from
peripheral/staging.

**Step 7.2: SUBSYSTEM ACTIVITY**
Record: Very active. This patch came in an iwlwifi-next 15-patch update
dump, then was taken by the maintainer.

---

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: WHO IS AFFECTED**
Record: Intel iwlwifi **mvm** users whose firmware does **not**
advertise `IWL_UCODE_TLV_API_SMART_FIFO_OFFLOAD`. Driver-specific /
firmware-version-specific. Still a large installed base of 22000-and-
older-class chips plus any newer FW without that TLV.

**Step 8.2: TRIGGER CONDITIONS**
Record: Firmware stop then start while cached state is `SF_INIT_OFF` or
`SF_UNINIT`. Common: wifi radio toggle, interface down/up, some suspend
paths. Not a race. Unprivileged users can toggle wifi and hit it.

**Step 8.3: FAILURE MODE SEVERITY**
Record: Firmware left without host `REPLY_SF_CFG_CMD` after reload
(wrong RX FIFO watermarks/timers in unassociated/init). Not an oops,
deadlock, or filesystem corruption.
**Severity: MEDIUM** (wrong firmware config / power and RX-FIFO
behavior; associated `SF_FULL_ON` still sent).

**Step 8.4: RISK-BENEFIT RATIO**
Record:
- **Benefit:** Restores a required init-time firmware command after
  every firmware stop on a very common driver. Low-to-medium user-
  visible benefit (no crash report), but the broken path is not rare.
- **Risk:** Very low (one store under existing mutex).
- **Ratio:** Favorable for a 1-line obviously-correct fix.

---

## PHASE 9: FINAL SYNTHESIS

**Step 9.1: COMPILE THE EVIDENCE**

FOR:
- Real, verified stale-cache bug; init explicitly tries to send SF
  config and can skip it
- One line, obviously correct, mutex-protected
- Bug present since 2013; code exists in this tree
- No prerequisites; applies cleanly
- Intel iwlwifi mvm is widely deployed
- Author/maintainer-originated; no NAKs found

AGAINST:
- Not a crash, UAF, deadlock, corruption, or security issue
- No user/syzbot report; impact is firmware defaults vs host SF_INIT_OFF
- `SF_FULL_ON` still always sent, so associated operation is less
  affected
- Newer firmware with SMART_FIFO_OFFLOAD never needed the command
- Submitted as iwlwifi-next “updates” 13/15, not a -fixes/stable
  nomination

UNRESOLVED:
- lore.kernel.org WebFetch/stable search blocked (403 / anti-bot)
- Exact user-visible symptom (power vs missed RX vs none) not documented

**Step 9.2: STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — one assignment; merged by
   iwlwifi maintainer
2. Fixes a real bug that affects users? **PASS** — stale cache skips a
   real firmware command on wifi stop/start
3. Important issue (crash/security/corruption/deadlock)? **PASS** with
   MEDIUM severity — wrong device firmware configuration after stop is a
   functional bug on a common driver, not a panic. Conservative reading
   could FAIL this bar; the 1-line nature and common trigger keep it a
   PASS.
4. Small and contained? **PASS** — +1 line, one function
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — `iwl_mvm_stop_device()`,
   `sf_state`, and `SF_UNINIT` are all here

**Step 9.3: EXCEPTION CATEGORIES**
Record: None (not a device ID, quirk table, DT, build, or docs fix).

**Step 9.4: DECISION**
This is a real, long-standing iwlwifi correctness bug: after firmware
stop the driver keeps believing smart-fifo is already programmed, so
`iwl_mvm_up()` skips `REPLY_SF_CFG_CMD`. The local 7.3-rc4 tree has the
buggy cache and skip logic. The fix is a single `sf_state = SF_UNINIT`
in the existing stop path, with no API change and negligible regression
risk. That meets stable rules for a small, obviously correct driver
bugfix even without a crash report.

---

### What the commit solves for this tree
On this checkout, `iwl_mvm_sf_config()` refuses to send smart-fifo
config when `new_state` matches `mvm->sf_state` (except `SF_FULL_ON`).
`sf_state` was only initialized at op-mode start, not when firmware
actually stopped. After a normal mac stop / restart / D3 firmware swap,
the next `iwl_mvm_up()` therefore omits `REPLY_SF_CFG_CMD`. Stable users
hitting wifi toggle, rfkill, or non-fast suspend on Intel mvm hardware
then run reloaded firmware without the host SF init the driver intends.

### Risk vs benefit
Benefit is restoring firmware RX-FIFO configuration after a common
stop/start cycle. Risk is essentially nil: one field write under
`mvm->mutex`, harmless on offload firmware. Backport needs no extra
commits.

---

Verification:
- [Phase 1] Parsed tags: SOB Emmanuel Grumbach + Miri Korenblit; Link to
  msgid; no Fixes/Reported-by/stable Cc
- [Phase 2] Diff: +1 line `mvm->sf_state = SF_UNINIT` in
  `iwl_mvm_stop_device()`
- [Phase 2] Confirmed skip in `iwl_mvm_sf_config()` and init call in
  `iwl_mvm_up()`
- [Phase 3] `git show a51cc81312148`: 1 file, +1; parent `974cbad4c86d6`
- [Phase 3] Original SF: `1f3b0ff8eccef` (2013-12-17), ancestor of HEAD;
  `git merge-base --is-ancestor` succeeded
- [Phase 3] Blame: new line is this commit; rest of stop_device from
  `cf5b462768474` (2020)
- [Phase 3] Follow-up `0a00c3ec2db76` is independent, not required
- [Phase 4] `b4 dig -c a51cc81312148`: lore match; patch 13/15 of
  iwlwifi-next updates
- [Phase 4] `b4 dig -a`: v1 and v2; committed Link is v2; hunk unchanged
- [Phase 4] `b4 dig -w`: Johannes Berg + linux-wireless; no NAK in saved
  mbox
- [Phase 4] UNVERIFIED: stable list discussion (lore 403/anti-bot);
  WebFetch of lore URLs also 403
- [Phase 5] Callers of `iwl_mvm_stop_device()`: mac80211 stop/restart,
  d3, fw error, NVM init
- [Phase 5] `IWL_UCODE_TLV_API_SMART_FIFO_OFFLOAD` added in
  `ff04f78ce38d7` (2024); offload path ignores SF commands
- [Phase 6] `git describe HEAD` = v7.3-rc4-27-gf0100363d8c37;
  kernelversion 7.3.0-rc4
- [Phase 6] Pre-fix `iwl_mvm_stop_device()` at parent matches insertion
  context; clean apply
- [Phase 7] MAINTAINERS: INTEL WIRELESS WIFI LINK, Miri Korenblit
- [Phase 8] Failure mode: skipped firmware SF init after stop; severity
  MEDIUM, not oops/deadlock
- UNVERIFIED: concrete user-visible packet-loss vs power-only impact
  (not stated in commit or mail)

**YES**

 drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index d6a13174b5617..3e7c620821069 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -1535,6 +1535,7 @@ void iwl_mvm_stop_device(struct iwl_mvm *mvm)
 	iwl_fw_cancel_timestamp(&mvm->fwrt);
 
 	clear_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, &mvm->status);
+	mvm->sf_state = SF_UNINIT;
 
 	iwl_mvm_pause_tcm(mvm, false);
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] wifi: mac80211: ibss: read deauth reason_code after frame length check
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (38 preceding siblings ...)
  2026-10-19 13:53 ` [PATCH AUTOSEL 6.18-5.15] wifi: iwlwifi: mvm: reset the smart fifo state upon FW stop Sasha Levin
@ 2026-10-19 13:53 ` Sasha Levin
  2026-10-19 13:53 ` [PATCH AUTOSEL 6.18-5.10] wifi: brcmfmac: validate msgbuf flowring IDs before use Sasha Levin
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:53 UTC (permalink / raw)
  To: patches, stable
  Cc: Shahar Tzarfati, Miri Korenblit, Johannes Berg, Sasha Levin,
	johannes, linux-wireless, linux-kernel

From: Shahar Tzarfati <shahar.tzarfati@intel.com>

[ Upstream commit aa4c0a649903567762edf2bbc7fff608953b3ca4 ]

The function was reading reason_code from the frame before validating
that the frame is at least IEEE80211_DEAUTH_FRAME_LEN bytes long.

Move the reason_code read to after the length check so the field is
guaranteed to be present before it is accessed.

Signed-off-by: Shahar Tzarfati <shahar.tzarfati@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260715212706.db26604650bd.I2caa73c396b8c9d357224b9334d5df3cafac498e@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## PHASE 1: COMMIT MESSAGE FORENSICS

**Step 1.1: PARSE THE SUBJECT LINE**
Record: `[mac80211/ibss] [read / reorder] Move IBSS deauth `reason_code`
access to after the existing frame-length check.`

**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
Record:
- `Fixes:` — none (expected)
- `Reported-by:` — none
- `Tested-by:` — none
- `Reviewed-by:` — none on the commit
- `Acked-by:` — none
- `Link:` `https://patch.msgid.link/20260715212706.db26604650bd.I2caa73c
  396b8c9d357224b9334d5df3cafac498e@changeid`
- `Cc: stable@vger.kernel.org` — none (expected)
- `Signed-off-by: Shahar Tzarfati <shahar.tzarfati@intel.com>` (author)
- `Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>`
  (Intel wireless)
- `Signed-off-by: Johannes Berg <johannes.berg@intel.com>` (mac80211
  maintainer)

No syzbot, no CVE, no multi-user reports. Maintainer SOB is the main
trust signal.

**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
Record:
- **Bug:** `ieee80211_rx_mgmt_deauth_ibss()` read
  `mgmt->u.deauth.reason_code` before checking `len >=
  IEEE80211_DEAUTH_FRAME_LEN`.
- **Symptom/failure mode:** 2-byte read past the validated frame on a
  truncated deauth. Value is then discarded if the length check fails.
- **Version info:** none in the message.
- **Root cause (author):** field access before the length check; move
  the read after the check.

**Step 1.4: DETECT HIDDEN BUG FIXES**
Record: Not a disguised cleanup. It is an explicit bounds-check-before-
access fix. The length check already existed; only the premature read
was wrong.

---

## PHASE 2: DIFF ANALYSIS - LINE BY LINE

**Step 2.1: INVENTORY THE CHANGES**
Record:
- File: `net/mac80211/ibss.c` (+3 / −1)
- Function: `ieee80211_rx_mgmt_deauth_ibss()`
- Scope: single-file surgical fix

**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
Record: Before: initialize `reason` from `mgmt->u.deauth.reason_code`,
then return if `len < 26`. After: declare `reason`, length-check first,
then read the field. `ibss_dbg()` and `sta_info_destroy_addr()` are
unchanged and remain after the check.

**Step 2.3: IDENTIFY THE BUG MECHANISM**
Record: **Memory safety / out-of-bounds read.**
`IEEE80211_DEAUTH_FRAME_LEN` is `(24 /* hdr */ + 2 /* reason */)`.
`reason_code` sits at offset 24 in `struct ieee80211_mgmt`. RX already
drops mgmt frames shorter than the 802.11 header (`skb->len <
ieee80211_hdrlen(fc)` in `ieee80211_rx()`), so 24- and 25-byte deauths
can still reach this handler. Those frames do not contain the reason
field; the old code always read it anyway. On the short-frame path the
value is unused (immediate `return`).

**Step 2.4: ASSESS THE FIX QUALITY**
Record: Obviously correct: same pattern as
`ieee80211_rx_mgmt_auth_ibss()` in the same file and as
`ieee80211_rx_mgmt_deauth()` in `mlme.c` (`4a360c6e18dfa`). Minimal, no
API/locking/structure changes. Regression risk is negligible (debug
print still sees a valid reason on well-formed frames).

---

## PHASE 3: GIT HISTORY INVESTIGATION

**Step 3.1: BLAME THE CHANGED LINES**
Record: Function introduced in `2cc59e784b54` (Antonio Quartulli,
2012-09-07, “mac80211: reply to AUTH with DEAUTH if sta allocation fails
in IBSS”). The premature `reason_code` read was in the original
function. Present for ~14 years, including this 7.3 tree’s lineage.

**Step 3.2: FOLLOW THE FIXES: TAG**
Record: No `Fixes:` tag. Buggy commit is `2cc59e784b54`, which `git
merge-base --is-ancestor` confirms is in this tree.

**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Record: Recent `ibss.c` work is unrelated (TX-on-disconnect, rx_nss).
Same-day series patch 2/2 was mlme deauth length checking; that path was
already fixed by `4a360c6e18dfa` (“wifi: mac80211: validate deauth frame
length before reason access”, Zhao Li, 2026-06-13). This IBSS patch is
standalone.

**Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS**
Record: Shahar Tzarfati is an Intel wireless contributor (iwlwifi
bounds-check fixes plus this IBSS change). Not the mac80211 maintainer;
Johannes Berg applied it.

**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
Record: None. Uses existing `IEEE80211_DEAUTH_FRAME_LEN` (defined 2012
in `net/mac80211/ieee80211_i.h`). Applies standalone.

---

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

**Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION**
Record:
- `b4 dig -c aa4c0a649903`: https://patch.msgid.link/20260715212706.db26
  604650bd.I2caa73c396b8c9d357224b9334d5df3cafac498e@changeid
- `b4 dig -a`: single revision, `[PATCH wireless-next 1/2]`
- Thread (mbox): no replies, no NAK, no `Cc: stable` request. Johannes
  applied v1.

**Step 4.2: CHECK WHO REVIEWED THE PATCH**
Record (`b4 dig -w`): To Johannes Berg; Cc `linux-wireless@`, Shahar
Tzarfati, sent by Miri Korenblit. No extra reviewer tags; maintainer
merge is the review signal.

**Step 4.3: SEARCH FOR THE BUG REPORT**
Record: No Reported-by, syzbot, or bugzilla. Sibling `4a360c6e18dfa` on
the STA deauth path is the same class of bug (LLM-assisted). No user
crash report found.

**Step 4.4: CHECK FOR RELATED PATCHES AND SERIES**
Record: 2/2 was `wifi: mac80211: mlme: read deauth reason_code after
frame length check`. It was not committed (mlme already had
`4a360c6e18dfa`). 1/2 does not depend on 2/2.

**Step 4.5: CHECK STABLE MAILING LIST HISTORY**
Record: lore.kernel.org search was blocked (Anubis 403). UNVERIFIED
whether linux-stable discussed this. No local `ibss.c` history indicates
a prior stable rejection.

---

## PHASE 5: CODE SEMANTIC ANALYSIS

**Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF**
Record: `ieee80211_rx_mgmt_deauth_ibss()`

**Step 5.2: TRACE CALLERS**
Record:
- `ieee80211_ibss_rx_queued_mgmt()` → `IEEE80211_STYPE_DEAUTH` case,
  `mgmt = skb->data`, `len = skb->len`
- `ieee80211_iface_work()` in `iface.c` for `NL80211_IFTYPE_ADHOC`
- Frames queued from `ieee80211_rx_h_mgmt()` in `rx.c` (IBSS deauth
  allowed)

Workqueue / wiphy context, not hardirq. Reachable from over-the-air RX.

**Step 5.3: TRACE CALLEES**
Record: `le16_to_cpu()`, `ibss_dbg()` (`MAC80211_IBSS_DEBUG` only),
`sta_info_destroy_addr()`. Functional work was already after the length
check.

**Step 5.4: FOLLOW THE CALL CHAIN**
Record: Wireless NIC RX → `ieee80211_rx()` (drops `skb->len < hdrlen`) →
`ieee80211_rx_h_mgmt()` → iface work → `ieee80211_ibss_rx_queued_mgmt()`
→ deauth handler. A peer on the IBSS can send a 24-byte deauth.
Unprivileged local userspace cannot inject this without packet
injection; a radio neighbor can. `ibss_dbg` does not gate the old read:
`reason` was initialized before the debug macro.

**Step 5.5: SEARCH FOR SIMILAR PATTERNS**
Record: Same bug on STA deauth (`mlme.c`, fixed in `4a360c6e18dfa`).
IBSS auth already checks `len < 24 + 6` before reading auth fields.
Probe-req path checks `len < 24 + 2`. This was the remaining IBSS deauth
hole.

---

## PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE

**Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?**
Record: Local tree is **v7.3-rc4-27-gf0100363d8c37** (`VERSION=7
PATCHLEVEL=3 SUBLEVEL=0 EXTRAVERSION=-rc4`).
`ieee80211_rx_mgmt_deauth_ibss()` exists in `net/mac80211/ibss.c`. Bug
introduced 2012 (`2cc59e784b54`), long before this branch. Current file
already has the fixed order (commit is an ancestor of HEAD). Evaluation
is of the pre-fix bug in this lineage, not “already selected.”

**Step 6.2: CHECK FOR BACKPORT COMPLICATIONS**
Record: Clean apply. Surrounding function matches the pre-image; no
conflicting refactor of this handler.

**Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE**
Record: No earlier IBSS-specific version of this fix. `4a360c6e18dfa`
only covers `mlme.c`. No duplicate IBSS patch.

---

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

**Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY**
Record: `net/mac80211` IBSS/ad-hoc RX. **IMPORTANT** for IBSS users,
**PERIPHERAL** vs core mm/VFS. IBSS is built with mac80211 (only
`MAC80211_IBSS_DEBUG` is extra). Less common than infrastructure STA,
but real (ad-hoc, some embedded/industrial).

**Step 7.2: ASSESS SUBSYSTEM ACTIVITY**
Record: mac80211 is actively developed; this IBSS handler has been
stable since 2012. Long-lived bug, not churn from new code.

---

## PHASE 8: IMPACT AND RISK ASSESSMENT

**Step 8.1: DETERMINE WHO IS AFFECTED**
Record: Driver-specific / config-specific: mac80211 IBSS
(`NL80211_IFTYPE_ADHOC`). Not all wifi users; IBSS is a minority of
deployments.

**Step 8.2: DETERMINE THE TRIGGER CONDITIONS**
Record: Truncated deauth (len 24 or 25) on an IBSS interface. Not every
boot; needs IBSS up plus a short frame (malformed or hostile). Remote
on-air trigger. Local unprivileged trigger only with injection.

**Step 8.3: DETERMINE THE FAILURE MODE SEVERITY**
Record: 2-byte read past `skb->len` into a local that is discarded on
the short-frame path. No leak through `ibss_dbg` (return happens first).
Crash only if the skb has no tailroom past 24 bytes (often it does).
KASAN may or may not fire depending on allocator vs `skb->len`.
Severity: **MEDIUM** (CWE-125 / packet-parser OOB), not a demonstrated
oops or UAF.

**Step 8.4: CALCULATE RISK-BENEFIT RATIO**
Record:
- **Benefit:** Closes a real, remotely reachable OOB in frame parsing.
  Modest user-visible impact (IBSS, discarded 2 bytes).
- **Risk:** Very low (3 lines, no locking/API, same pattern as mlme).
- **Ratio:** Favorable. Cheap to take; cost of skipping is leaving a
  parser OOB in long-lived code.

---

## PHASE 9: FINAL SYNTHESIS

**Step 9.1: COMPILE THE EVIDENCE**

FOR:
- Real OOB: `reason_code` at offset 24 read when `len` can be 24–25
- Read is not debug-gated; it always ran
- Over-the-air reachable on IBSS
- 4-line, obviously correct, tested by landing in wireless-next via
  Johannes Berg
- Same class already fixed in STA mlme (`4a360c6e18dfa`)
- No new features/APIs; no prerequisites
- Applies cleanly; bug present since 2012 in this tree’s code
- Buffer OOB is a documented stable category

AGAINST:
- No crash/syzbot/CVE/user report
- `reason` unused on the short path; `sta_info_destroy_addr()` was
  already guarded
- IBSS is uncommon vs infrastructure
- Practical crash likely rare (skb tailroom)
- No explicit stable nomination

UNRESOLVED:
- lore.kernel.org HTML search blocked; no independent stable-list
  confirmation
- Exact KASAN behavior on `skb->len` vs kmalloc size not demonstrated

**Step 9.2: APPLY THE STABLE RULES CHECKLIST**
1. Obviously correct and tested? **PASS** — reorder after an existing
   check; maintainer merged v1
2. Fixes a real bug that affects users? **PASS** — OOB on truncated IBSS
   deauth
3. Important issue (crash, security, corruption, deadlock)? **PASS**
   (low–medium) — remote 2-byte overread in a parser; not a known oops,
   but memory-safety
4. Small and contained? **PASS** — +3/−1, one function
5. No new features or APIs? **PASS**
6. Can apply to the local tree? **PASS** — matching pre-image in
   `ibss.c`

**Step 9.3: CHECK FOR EXCEPTION CATEGORIES**
Record: None (not a device ID, quirk, DT, build, or docs patch).
Qualifies as a normal small bugfix.

**Step 9.4: MAKE YOUR DECISION**
This is a surgical bounds-check fix for a long-standing, remotely
reachable out-of-bounds read in mac80211 IBSS deauth parsing. The
functional destroy path was already safe; the bug is the unconditional
2-byte overread. That is still a real memory-safety defect, the same one
already corrected on the STA deauth path. Risk of the change is
essentially zero. For this 7.3 tree, the code exists and the patch
applies cleanly, so it should be taken.

**What it solves for stable users:** A truncated IBSS deauth no longer
reads past the frame before the length check. That avoids undefined/OOB
behavior on a path a radio neighbor can hit.

**Risk vs benefit:** Benefit is modest but real; risk is negligible.
Take it.

---

### Verification
- [Phase 1] Parsed commit `aa4c0a649903`; tags: Link + three SOBs
  (Tzarfati, Korenblit, Berg); no Fixes/Reported-by/Cc:stable
- [Phase 2] Diff: `ieee80211_rx_mgmt_deauth_ibss()` +3/−1; read moved
  after `IEEE80211_DEAUTH_FRAME_LEN` (26 = 24+2)
- [Phase 2] Confirmed `reason` only used in `ibss_dbg`;
  `sta_info_destroy_addr()` already after the check
- [Phase 3] `git blame`: function from `2cc59e784b54` (2012); `git
  merge-base --is-ancestor 2cc59e784b54 HEAD` succeeded
- [Phase 3] Pre-image shown via `git show
  aa4c0a649903^:net/mac80211/ibss.c`
- [Phase 3] Author log: Intel wifi bounds-check work; series 2/2 did not
  land
- [Phase 4] `b4 dig -c/-a/-w/-m`: wireless-next 1/2, v1 only, no review
  replies; 2/2 was mlme duplicate of `4a360c6e18dfa`
- [Phase 4] `git show 4a360c6e18dfa`: same bug on STA deauth, already in
  this tree
- [Phase 4] lore HTML/WebFetch: 403/Anubis — UNVERIFIED for linux-stable
  archive
- [Phase 5] Callers: `ieee80211_ibss_rx_queued_mgmt` ← `iface.c` ADHOC ←
  `ieee80211_rx_h_mgmt`
- [Phase 5] `ieee80211_rx()` drops mgmt if `skb->len <
  ieee80211_hdrlen(fc)` (~24), so 24–25 byte frames still reach the
  handler
- [Phase 6] `git describe HEAD` = `v7.3-rc4-27-gf0100363d8c37`; `make
  kernelversion` = 7.3.0-rc4; buggy function present; apply would be
  clean
- [Phase 8] Failure mode: discarded 2-byte overread; severity MEDIUM;
  IBSS-specific
- UNVERIFIED: whether KASAN fires on this skb overread; whether linux-
  stable already discussed it

The patch is small, correct, and fixes a real parser OOB in code this
tree has had since 2012.

**YES**

 net/mac80211/ibss.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 6ca2ff354e768..4dc748a667a72 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -910,11 +910,13 @@ static void ieee80211_rx_mgmt_deauth_ibss(struct ieee80211_sub_if_data *sdata,
 					  struct ieee80211_mgmt *mgmt,
 					  size_t len)
 {
-	u16 reason = le16_to_cpu(mgmt->u.deauth.reason_code);
+	u16 reason;
 
 	if (len < IEEE80211_DEAUTH_FRAME_LEN)
 		return;
 
+	reason = le16_to_cpu(mgmt->u.deauth.reason_code);
+
 	ibss_dbg(sdata, "RX DeAuth SA=%pM DA=%pM\n", mgmt->sa, mgmt->da);
 	ibss_dbg(sdata, "\tBSSID=%pM (reason: %d)\n", mgmt->bssid, reason);
 	sta_info_destroy_addr(sdata, mgmt->sa);
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH AUTOSEL 6.18-5.10] wifi: brcmfmac: validate msgbuf flowring IDs before use
       [not found] <20261019135441.1420968-1-sashal@kernel.org>
                   ` (39 preceding siblings ...)
  2026-10-19 13:53 ` [PATCH AUTOSEL 6.18-5.10] wifi: mac80211: ibss: read deauth reason_code after frame length check Sasha Levin
@ 2026-10-19 13:53 ` Sasha Levin
  40 siblings, 0 replies; 41+ messages in thread
From: Sasha Levin @ 2026-10-19 13:53 UTC (permalink / raw)
  To: patches, stable
  Cc: Can Peng, Arend van Spriel, Johannes Berg, Sasha Levin,
	linux-wireless, brcm80211, brcm80211-dev-list.pdl, linux-kernel

From: Can Peng <pengcan@kylinos.cn>

[ Upstream commit 32856f39fefdc75bd253cab999f996750628648e ]

Firmware messages carry flow_ring_id values which brcmfmac converts
to an internal flowid by subtracting
BRCMF_H2D_MSGRING_FLOWRING_IDSTART. The resulting value is used as
a bit index in txstatus_done_map and as an array index into
msgbuf->flowrings and the flowring state.

Validate the firmware supplied flow_ring_id before using it. This
prevents flow_ring_id values below BRCMF_H2D_MSGRING_FLOWRING_IDSTART
from underflowing and rejects values outside msgbuf->max_flowrings.

In the tx status path, complete the packet with an error after
removing a valid packet id so the skb is not leaked when the flow
ring id is invalid.

Signed-off-by: Can Peng <pengcan@kylinos.cn>
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Link: https://patch.msgid.link/20260723055618.550834-1-pengcan@kylinos.cn
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

This is a 5.15.221 tree (`pending-5.15`). The buggy firmware-ID indexing
is present here, and the patch is a small bounds check that prevents
out-of-bounds writes/crashes and an skb leak.

===============================================================
PHASE 1: COMMIT MESSAGE FORENSICS
===============================================================

Step 1.1: PARSE THE SUBJECT LINE
Record: [subsystem: wifi: brcmfmac] [action verb: validate] [intent:
reject firmware-supplied msgbuf flowring IDs before they are used as
bitmap/array indexes]

Step 1.2: PARSE ALL COMMIT MESSAGE TAGS
Record: Tags in the candidate message:
- Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> (brcmfmac
  maintainer)
- Link:
  https://patch.msgid.link/20260723055618.550834-1-pengcan@kylinos.cn
- Signed-off-by: Can Peng <pengcan@kylinos.cn> (author)
- Signed-off-by: Johannes Berg <johannes.berg@intel.com> (wireless
  maintainer who applied it)

No Reported-by, Tested-by, Fixes, or Cc: stable in the candidate text
(absence expected). The original mailing-list submission (v1, same
msgid) did include `Fixes: 9a1bb60250d2 ("brcmfmac: Adding msgbuf
protocol.")` and `Cc: stable@vger.kernel.org`; those are author-
submitted tags, not pipeline markers.

Step 1.3: ANALYZE THE COMMIT BODY TEXT
Record:
- Bug: firmware `flow_ring_id` is converted with `id -
  BRCMF_H2D_MSGRING_FLOWRING_IDSTART` and then used as a bit index in
  `txstatus_done_map` and an array index into `msgbuf->flowrings` /
  flowring state, with no range check.
- Failure mode: IDs below `BRCMF_H2D_MSGRING_FLOWRING_IDSTART` (2)
  underflow a `u16`; IDs above `max_flowrings` index past allocated
  arrays. On the TX-status path, a valid pktid can already have been
  taken, so an early return would leak the skb.
- Version info in the body: none. Original Fixes target is from 2014.
- Root cause (author): missing validation of firmware-supplied ring IDs.

Step 1.4: DETECT HIDDEN BUG FIXES
Record: Not a hidden fix. The subject/body describe a bounds check and
an skb-leak close on the invalid-ID TX-status path.

===============================================================
PHASE 2: DIFF ANALYSIS - LINE BY LINE
===============================================================

Step 2.1: INVENTORY THE CHANGES
Record:
- File: `drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c`
  (single file)
- Scope: ~40 insertions / 6 deletions (mailing-list v1: 46 lines net in
  that file)
- Functions: adds `brcmf_msgbuf_get_flowid()`; changes
  `brcmf_msgbuf_process_txstatus()`,
  `brcmf_msgbuf_process_flow_ring_create_response()`,
  `brcmf_msgbuf_process_flow_ring_delete_response()`
- Classification: single-file surgical fix

Step 2.2: UNDERSTAND THE CODE FLOW CHANGE
Record:
- Helper (new): convert firmware `flow_ring_id` to internal `flowid`
  only if `id >= BRCMF_H2D_MSGRING_FLOWRING_IDSTART` and `(id - START) <
  msgbuf->max_flowrings`. Uses `u32` so the subtract cannot wrap.
- TX status (normal/error path): previously always subtracted then
  `set_bit(flowid, txstatus_done_map)`, `msgbuf->flowrings[flowid]`,
  `atomic_dec`, `brcmf_txfinalize(..., true)`. After: if ID invalid,
  `brcmf_txfinalize(..., false)` and return (skb already taken from
  pktid table).
- Create/delete response: previously subtracted and used the index
  unconditionally (`brcmf_msgbuf_remove_flowring`,
  `brcmf_flowring_open`, `brcmf_flowring_delete`). After: invalid ID
  returns without touching rings.

Step 2.3: IDENTIFY THE BUG MECHANISM
Record:
- Category: memory safety (out-of-bounds index / underflow) plus
  resource leak on the TX-status error path.
- Mechanism: firmware DMA completion messages supply
  `compl_hdr.flow_ring_id`. `BRCMF_H2D_MSGRING_FLOWRING_IDSTART` is 2.
  For ID 0 or 1, `u16 flowid -= 2` wraps to 65534/65535. `set_bit()`
  then writes far past `txstatus_done_map` (sized to `max_flowrings`
  bits). `msgbuf->flowrings[flowid]` is an OOB load and typically a
  crash. Oversized IDs do the same without wrapping. The helper rejects
  both. TX-status also finalizes the skb so `brcmf_msgbuf_get_pktid()`’s
  take is not leaked.

Step 2.4: ASSESS THE FIX QUALITY
Record:
- Obviously correct: range check matches how the host builds IDs
  (`flowid + BRCMF_H2D_MSGRING_FLOWRING_IDSTART` in create/delete
  requests). Happy path is unchanged.
- Minimal: one helper, three call sites, no API change.
- Regression risk: low. Invalid create/delete IDs now skip ring
  teardown; that is safer than OOB. A stuck ring on bogus firmware is
  preferable to memory corruption. `brcmf_txfinalize()` already handles
  a NULL `ifp` from a bad `ifidx` by freeing the skb.
- Red flags: none. Double blank line after the helper is style-only (v2
  tried to clean it; Johannes applied v1).

===============================================================
PHASE 3: GIT HISTORY INVESTIGATION
===============================================================

Step 3.1: BLAME THE CHANGED LINES
Record:
- Unvalidated `flowid = le16_to_cpu(...flow_ring_id)` dates to
  9a1bb60250d2 (Hante Meuleman, 2014-07-30), “brcmfmac: Adding msgbuf
  protocol.”
- The subtract of `BRCMF_H2D_MSGRING_FLOWRING_IDSTART` was added in
  be4b092cab84b (Franky Lin, 2016-11-23), “brcmfmac: add pcie host
  dongle interface rev6 support” (replaced
  `BRCMF_NROF_H2D_COMMON_MSGRINGS`, also 2).
- Code has been in-tree for many years, including this 5.15 branch.

Step 3.2: FOLLOW THE FIXES: TAG
Record:
- Original mailing-list Fixes: 9a1bb60250d2. `git merge-base --is-
  ancestor 9a1bb60250d2 HEAD` succeeds.
- Slightly imprecise: large-ID OOB is from 2014; underflow of IDs 0/1 is
  from the 2016 subtract. Both commits are in this tree.
- No later in-tree fix of the same hole (`brcmf_msgbuf_get_flowid` is
  absent; `git log --grep="invalid flowring"` / `--grep="flow_ring_id"`
  on this path found nothing equivalent).

Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES
Record: Recent `msgbuf.c` commits here are unrelated (pktid DMA unmap,
allocation-mode plumbing, memleak in attach). Not part of a functional
series that must land first. v2 was whitespace-only prep + the same
validation; Johannes applied v1 and declined the cleanup.

Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS
Record: `git log --author="Can Peng"` on
`drivers/net/wireless/broadcom/brcm80211/` in this tree is empty
(outside contributor). Weight comes from Arend van Spriel’s Acked-by and
Johannes applying the patch.

Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS
Record: No new helpers, structs, or APIs. Uses existing `bphy_err`,
`brcmf_txfinalize`, `brcmf_get_ifp`, `msgbuf->max_flowrings`.
Standalone. v2 patch 1/2 (blank-line cleanup) is not required.

===============================================================
PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
===============================================================

Step 4.1: FIND THE ORIGINAL PATCH DISCUSSION
Record:
- `b4 mbox` on msgid `20260723055618.550834-1-pengcan@kylinos.cn`
  retrieved the thread (lore WebFetch returned 403).
- v1: standalone `[PATCH wireless]` with Fixes + Cc: stable.
- Arend: one nit (double blank line), “To be applied to wireless tree,”
  Acked-by. No NAK.
- v2: 0/2 cover + whitespace cleanup + same validation rebase. Johannes:
  too late, he already applied v1; not rebasing for whitespace.
- Applied version matches the candidate (v1, double blank line kept). No
  later functional revision.

Step 4.2: CHECK WHO REVIEWED THE PATCH
Record: To: Arend van Spriel. Cc: linux-wireless, brcm80211 lists,
linux-kernel, stable@vger.kernel.org. Ack from the brcm80211 maintainer;
applied by Johannes Berg.

Step 4.3: SEARCH FOR THE BUG REPORT
Record: No syzbot, bugzilla, or user crash in the message. Justification
is code analysis of firmware-supplied indexes. Trigger is a bad
`flow_ring_id` on D2H completion rings (firmware bug, DMA corruption, or
hostile firmware), not a documented userspace repro.

Step 4.4: CHECK FOR RELATED PATCHES AND SERIES
Record: v2 series is cleanup + this fix. Functional patch is self-
contained. No other msgbuf ID-validation patches in the thread.

Step 4.5: CHECK STABLE MAILING LIST HISTORY
Record: Author Cc’d stable@vger.kernel.org on v1/v2. No separate stable-
list rejection found. lore.kernel.org HTTP from WebFetch was 403;
evidence is the b4-retrieved mbox.

===============================================================
PHASE 5: CODE SEMANTIC ANALYSIS
===============================================================

Step 5.1: IDENTIFY KEY FUNCTIONS IN THE DIFF
Record: `brcmf_msgbuf_get_flowid` (new);
`brcmf_msgbuf_process_txstatus`;
`brcmf_msgbuf_process_flow_ring_create_response`;
`brcmf_msgbuf_process_flow_ring_delete_response`.

Step 5.2: TRACE CALLERS
Record:
- All three process_* functions are called only from
  `brcmf_msgbuf_process_msgtype()` (`MSGBUF_TYPE_TX_STATUS`,
  `MSGBUF_TYPE_FLOW_RING_CREATE_CMPLT`,
  `MSGBUF_TYPE_FLOW_RING_DELETE_CMPLT`).
- That is called from `brcmf_msgbuf_process_rx()` while draining D2H
  rings.
- `brcmf_proto_msgbuf_rx_trigger()` calls process_rx for RX/TX/control
  complete rings.
- Call site: `brcmf_pcie_isr_thread()` in `pcie.c` on
  `BRCMF_PCIE_MB_INT_D2H_DB` (IRQ thread). Hot path for PCIe FullMAC
  traffic.

Step 5.3: TRACE CALLEES
Record: `brcmf_msgbuf_get_pktid` (takes skb out of the TX pktid table;
already bounds-checks pktid); `set_bit`; `msgbuf->flowrings[flowid]`;
`atomic_dec(&commonring->outstanding_tx)`; `brcmf_txfinalize`;
`brcmf_get_ifp`; `brcmf_msgbuf_remove_flowring` /
`brcmf_flowring_delete` / `brcmf_flowring_open` (those use `flowid` as
`flow->rings[flowid]` with no extra range check).

Step 5.4: FOLLOW THE CALL CHAIN
Record: Userspace TX → flowring → firmware; firmware posts TX-status /
create / delete completions into DMA rings; host IRQ processes them. Any
PCIe brcmfmac user hits this path. Not a syscall fuzz target by itself;
firmware-supplied fields in DMA completions are still a real input.

Step 5.5: SEARCH FOR SIMILAR PATTERNS
Record: Other `flow_ring_id` uses: host-generated create/delete
requests, and ring-status which only logs the ID. No sibling driver copy
of this helper. `brcmf_flowring_delete`/`open` do not bounds-check
`flowid`; they assume the caller already has a valid index.

===============================================================
PHASE 6: CROSS-REFERENCING AGAINST THE LOCAL TREE
===============================================================

Step 6.1: DOES THE BUGGY CODE EXIST IN THIS TREE?
Record: Yes. This checkout is 5.15.221 (`p-5.15-2-g6703e5d2f3a29`).
Unvalidated subtract is in `msgbuf.c` at process_txstatus (~883–891),
create_response (~1239–1245), delete_response (~1268–1274). Introduced
2014/2016; present here. `brcmf_msgbuf_get_flowid` is not present.

Step 6.2: CHECK FOR BACKPORT COMPLICATIONS
Record: Minor context conflict. 5.15 `brcmf_msgbuf_rxreorder` still has
a `bool inirq` argument (687006e20c445); the candidate hunk context uses
the later two-argument form. Insertion point after
`brcmf_msgbuf_remove_flowring` and the three process_* hunks match.
Expected: trivial context adjust, not a rework. `bphy_err`,
`max_flowrings`, `brcmf_txfinalize` all exist.

Step 6.3: CHECK IF RELATED FIXES ARE ALREADY HERE
Record: No equivalent validation. Unrelated msgbuf fixes (pktid unmap,
attach memleak) do not close this hole.

===============================================================
PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
===============================================================

Step 7.1: IDENTIFY THE SUBSYSTEM AND ITS CRITICALITY
Record: [brcmfmac msgbuf / PCIe FullMAC Wi-Fi] [IMPORTANT]. Not core
mm/vfs, but used on Raspberry Pi-class boards and many Broadcom PCIe
WLAN cards. `CONFIG_BRCMFMAC_PCIE` selects `BRCMFMAC_PROTO_MSGBUF`.
SDIO/USB FullMAC uses BCDC, not this path.

Step 7.2: ASSESS SUBSYSTEM ACTIVITY
Record: Mature. msgbuf protocol from 2014; this file is not under heavy
5.15 churn. Long-standing hole, not a brand-new subsystem.

===============================================================
PHASE 8: IMPACT AND RISK ASSESSMENT
===============================================================

Step 8.1: DETERMINE WHO IS AFFECTED
Record: Driver-specific / config-specific: `CONFIG_BRCMFMAC_PCIE`
(msgbuf). Does not affect SDIO/USB brcmfmac. Population is still large
for an LTS kernel.

Step 8.2: DETERMINE THE TRIGGER CONDITIONS
Record: Trigger is a firmware completion with `flow_ring_id` < 2 or `>=
max_flowrings + 2`. Normal firmware should echo host IDs, so the common
path is fine. Realistic triggers: buggy/mismatched firmware, DMA
corruption, compromised firmware. Unprivileged userspace cannot poke the
ID directly; it can generate TX completions by sending traffic.

Step 8.3: DETERMINE THE FAILURE MODE SEVERITY
Record:
- `set_bit(underflowed_id, txstatus_done_map)`: out-of-bounds write
  (memory corruption).
- `msgbuf->flowrings[flowid]` / `flow->rings[flowid]`: OOB / NULL deref
  → oops.
- TX-status without finalize: skb leak (the patch closes this).
- Severity: HIGH (crash / memory corruption on a common Wi-Fi driver).
  Not a documented privilege-escalation writeup, but OOB write from
  device DMA is security-relevant.

Step 8.4: CALCULATE RISK-BENEFIT RATIO
Record:
- Benefit: high for PCIe brcmfmac — prevents OOB write/crash and a leak.
- Risk: low — ~40-line helper, no locking/API/data-structure change, no
  happy-path behavior change.
- Ratio: strongly favors backport.

===============================================================
PHASE 9: FINAL SYNTHESIS
===============================================================

Step 9.1: COMPILE THE EVIDENCE
FOR:
- Real OOB index from firmware-supplied IDs (underflow and upper bound),
  present in this 5.15 tree since 2014/2016.
- TX-status path can leak an skb after `brcmf_msgbuf_get_pktid()` if the
  ring ID is bad.
- Small, obviously correct helper; happy path unchanged.
- Maintainer Acked-by; wireless maintainer applied v1.
- Applies with only a trivial rxreorder-context tweak.

AGAINST:
- No public crash/syzbot report; trigger depends on bad firmware IDs.
- Affects only PCIe msgbuf, not all brcmfmac buses.

UNRESOLVED:
- Could not HTTP-fetch lore.kernel.org (403); thread was recovered via
  `b4 mbox`.
- No mainline SHA in this checkout to `merge-base --is-ancestor` the fix
  itself (expected: it is not in 5.15 yet).

Step 9.2: APPLY THE STABLE RULES CHECKLIST
1. Obviously correct and tested? PASS — range check matches host ID
   encoding; Acked by subsystem maintainer.
2. Fixes a real bug that affects users? PASS — unvalidated device-
   supplied index used as bit/array index; skb leak on that path.
3. Important issue? PASS — OOB write / crash / leak; HIGH.
4. Small and contained? PASS — one file, ~40 lines, three call sites.
5. No new features or APIs? PASS — internal helper only.
6. Can apply to the local tree? PASS — buggy code is here; minor context
   conflict only.

Step 9.3: CHECK FOR EXCEPTION CATEGORIES
Record: Not a device-ID/quirk/DT/build/docs exception. It is a
straightforward memory-safety fix.

Step 9.4: MAKE YOUR DECISION
This should be backported to this 5.15 tree. The hole exists here, the
fix is surgical, and the downside of skipping it is memory corruption or
an oops if firmware supplies a bad flowring ID.

Verification:
- [Phase 1] Parsed candidate tags: Acked-by Arend van Spriel, Link
  msgid, SOBs Can Peng / Johannes Berg; no Fixes/Cc in candidate text.
- [Phase 1] `b4 mbox` v1 body: `Fixes: 9a1bb60250d2` and `Cc:
  stable@vger.kernel.org`.
- [Phase 2] Diff: helper `brcmf_msgbuf_get_flowid`; TX-status finalizes
  skb on invalid ID; create/delete return early.
- [Phase 2] Confirmed `BRCMF_H2D_MSGRING_FLOWRING_IDSTART` is 2 in
  `bus.h`; `flowid` is `u16` so subtract underflows.
- [Phase 2] `txstatus_done_map` allocated as
  `BITS_TO_LONGS(max_flowrings) * sizeof(unsigned long)` — overflowed
  bit index is OOB.
- [Phase 2] `brcmf_txfinalize()` NULL-`ifp` path frees the skb
  (`core.c`).
- [Phase 3] `git blame`: unvalidated use 9a1bb60250d2 (2014); subtract
  be4b092cab84b (2016).
- [Phase 3] `git merge-base --is-ancestor 9a1bb60250d2 HEAD`: yes.
- [Phase 3] No `brcmf_msgbuf_get_flowid` in this tree; no prior “invalid
  flowring” fix on this path.
- [Phase 4] `b4 mbox -c`: 7 messages; v1 applied; v2 whitespace declined
  by Johannes; Arend Acked-by, no NAK.
- [Phase 4] WebFetch lore/msgid.link: 403; used b4 instead.
- [Phase 5] Call chain: `brcmf_pcie_isr_thread` →
  `brcmf_proto_msgbuf_rx_trigger` → `brcmf_msgbuf_process_rx` →
  `process_msgtype` → the three functions.
- [Phase 5] Host encodes IDs as `flowid +
  BRCMF_H2D_MSGRING_FLOWRING_IDSTART` at msgbuf.c create/delete request
  sites.
- [Phase 6] `git describe HEAD`: p-5.15-2-g6703e5d2f3a29; `make
  kernelversion`: 5.15.221.
- [Phase 6] Local `process_txstatus` still does unvalidated `flowid -=
  BRCMF_H2D_MSGRING_FLOWRING_IDSTART`.
- [Phase 6] Nearby `brcmf_msgbuf_rxreorder(..., bool inirq)` differs
  from candidate context → minor apply tweak.
- [Phase 7] `Kconfig`: `BRCMFMAC_PCIE` selects `BRCMFMAC_PROTO_MSGBUF`.
- [Phase 8] Failure mode: OOB `set_bit` / OOB `flowrings[]` dereference;
  severity HIGH.
- UNVERIFIED: live firmware that currently emits IDs < 2 (no user report
  in the thread).

**YES**

 .../broadcom/brcm80211/brcmfmac/msgbuf.c      | 46 ++++++++++++++++---
 1 file changed, 40 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
index de47d6b7e02b2..f850e64108c41 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
@@ -561,6 +561,28 @@ brcmf_msgbuf_remove_flowring(struct brcmf_msgbuf *msgbuf, u16 flowid)
 	brcmf_flowring_delete(msgbuf->flow, flowid);
 }
 
+static bool brcmf_msgbuf_get_flowid(struct brcmf_msgbuf *msgbuf,
+				    u16 flow_ring_id, u16 *flowid)
+{
+	u32 id = flow_ring_id;
+
+	if (id < BRCMF_H2D_MSGRING_FLOWRING_IDSTART) {
+		bphy_err(msgbuf->drvr, "invalid flowring id %u\n",
+			 flow_ring_id);
+		return false;
+	}
+
+	id -= BRCMF_H2D_MSGRING_FLOWRING_IDSTART;
+	if (id >= msgbuf->max_flowrings) {
+		bphy_err(msgbuf->drvr, "invalid flowring id %u\n",
+			 flow_ring_id);
+		return false;
+	}
+
+	*flowid = id;
+	return true;
+}
+
 
 static struct brcmf_msgbuf_work_item *
 brcmf_msgbuf_dequeue_work(struct brcmf_msgbuf *msgbuf)
@@ -881,17 +903,23 @@ brcmf_msgbuf_process_txstatus(struct brcmf_msgbuf *msgbuf, void *buf)
 	struct msgbuf_tx_status *tx_status;
 	u32 idx;
 	struct sk_buff *skb;
+	u16 flow_ring_id;
 	u16 flowid;
 
 	tx_status = (struct msgbuf_tx_status *)buf;
 	idx = le32_to_cpu(tx_status->msg.request_id) - 1;
-	flowid = le16_to_cpu(tx_status->compl_hdr.flow_ring_id);
-	flowid -= BRCMF_H2D_MSGRING_FLOWRING_IDSTART;
+	flow_ring_id = le16_to_cpu(tx_status->compl_hdr.flow_ring_id);
 	skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev,
 				     msgbuf->tx_pktids, idx);
 	if (!skb)
 		return;
 
+	if (!brcmf_msgbuf_get_flowid(msgbuf, flow_ring_id, &flowid)) {
+		brcmf_txfinalize(brcmf_get_ifp(msgbuf->drvr, tx_status->msg.ifidx),
+				 skb, false);
+		return;
+	}
+
 	set_bit(flowid, msgbuf->txstatus_done_map);
 	commonring = msgbuf->flowrings[flowid];
 	atomic_dec(&commonring->outstanding_tx);
@@ -1238,13 +1266,16 @@ brcmf_msgbuf_process_flow_ring_create_response(struct brcmf_msgbuf *msgbuf,
 	struct msgbuf_flowring_create_resp *flowring_create_resp;
 	u16 status;
 	u16 flowid;
+	u16 flow_ring_id;
 
 	flowring_create_resp = (struct msgbuf_flowring_create_resp *)buf;
 
-	flowid = le16_to_cpu(flowring_create_resp->compl_hdr.flow_ring_id);
-	flowid -= BRCMF_H2D_MSGRING_FLOWRING_IDSTART;
+	flow_ring_id = le16_to_cpu(flowring_create_resp->compl_hdr.flow_ring_id);
 	status =  le16_to_cpu(flowring_create_resp->compl_hdr.status);
 
+	if (!brcmf_msgbuf_get_flowid(msgbuf, flow_ring_id, &flowid))
+		return;
+
 	if (status) {
 		bphy_err(drvr, "Flowring creation failed, code %d\n", status);
 		brcmf_msgbuf_remove_flowring(msgbuf, flowid);
@@ -1267,13 +1298,16 @@ brcmf_msgbuf_process_flow_ring_delete_response(struct brcmf_msgbuf *msgbuf,
 	struct msgbuf_flowring_delete_resp *flowring_delete_resp;
 	u16 status;
 	u16 flowid;
+	u16 flow_ring_id;
 
 	flowring_delete_resp = (struct msgbuf_flowring_delete_resp *)buf;
 
-	flowid = le16_to_cpu(flowring_delete_resp->compl_hdr.flow_ring_id);
-	flowid -= BRCMF_H2D_MSGRING_FLOWRING_IDSTART;
+	flow_ring_id = le16_to_cpu(flowring_delete_resp->compl_hdr.flow_ring_id);
 	status =  le16_to_cpu(flowring_delete_resp->compl_hdr.status);
 
+	if (!brcmf_msgbuf_get_flowid(msgbuf, flow_ring_id, &flowid))
+		return;
+
 	if (status) {
 		bphy_err(drvr, "Flowring deletion failed, code %d\n", status);
 		brcmf_flowring_delete(msgbuf->flow, flowid);
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 41+ messages in thread

end of thread, other threads:[~2026-10-19 14:06 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20261019135441.1420968-1-sashal@kernel.org>
2026-10-19 13:45 ` [PATCH AUTOSEL 6.18-5.10] wifi: brcmfmac: Set DMA direction for msgbuf packet IDs Sasha Levin
2026-10-19 13:45 ` [PATCH AUTOSEL 6.18-6.6] wifi: iwlwifi: mvm: ignore sync frames when sync is disabled Sasha Levin
2026-10-19 13:45 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: support TTL platform device ID Sasha Levin
2026-10-19 13:45 ` [PATCH AUTOSEL 6.18-5.10] wifi: rtlwifi: fix disabling of ASPM for RTL8723BE with AER flooding Sasha Levin
2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7921: fix memory leak when skb_linearize fails in mcu rx event Sasha Levin
2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-6.6] wifi: mac80211_hwsim: clear PMSR request state on abort Sasha Levin
2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.15] wifi: mt76: set the EOSP bit in the QoS header of the last released frame Sasha Levin
2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.10] wifi: rtlwifi: rtl8723be: Remove unnecessary irq save/restore in hw_init() Sasha Levin
2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.10] wifi: ath10k: trigger hardware recovery upon rx failures Sasha Levin
2026-10-19 13:46 ` [PATCH AUTOSEL 6.18] wifi: mt76: wed: fix kernel panic on non-DBDC MT7986 Sasha Levin
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-6.12] wifi: rtw89: wow: add QoS control field to WoWLAN ARP response for MLO Sasha Levin
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: mld: validate D3_END notif size Sasha Levin
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-5.15] wifi: mt76: mt7603: free beacon SKB on error Sasha Levin
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7915: configure noise floor reporting on reset Sasha Levin
2026-10-19 13:48 ` [PATCH AUTOSEL 6.18-6.6] wifi: mt76: mt7603: file buffered frames under the TID reported to mac80211 Sasha Levin
2026-10-19 13:48 ` [PATCH AUTOSEL 6.18-5.10] wifi: mt76: mt7603: fix U-APSD service period termination Sasha Levin
2026-10-19 13:48 ` [PATCH AUTOSEL 6.18-6.6] wifi: ath12k: fix scan command endianness on big endian Sasha Levin
2026-10-19 13:48 ` [PATCH AUTOSEL 6.18-6.12] wifi: rtw89: wow: only WiFi 6 chips initialize RF registers in WoWLAN mode Sasha Levin
2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-5.15] wifi: mt76: mt7603: add 0x7592 EEPROM chip ID Sasha Levin
2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-6.1] wifi: mt76: mt7615: fix NULL deref in mt7615_mac_set_rates Sasha Levin
2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-5.10] wifi: ath11k: validate regulatory capability phy_id Sasha Levin
2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-5.10] wifi: cfg80211: include cf1 offset when sending chandef Sasha Levin
2026-10-19 13:50 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: mld: cancel wiphy work before freeing wiphy Sasha Levin
2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-6.12] wifi: ath12k: avoid setting 320MHz support on non 6GHz band Sasha Levin
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: mld: reset the driver state upon firmware recovery Sasha Levin
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: mld: support aborting an ongoing ftm request Sasha Levin
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-5.10] wifi: mt76: mt76x02: report rx FCS errors to mac80211 Sasha Levin
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-6.12] wifi: ath11k: fix resource leak on error in ext IRQ setup Sasha Levin
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: validate UEFI reduced-power SKU TLV length Sasha Levin
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: mld: validate wake packet crypto overhead Sasha Levin
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: mld: Do not cleanup FW state when the device is dead Sasha Levin
2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-5.10] wifi: p54: validate firmware record lengths Sasha Levin
2026-10-19 13:52 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: mld: drop connection on D3 resume failure Sasha Levin
2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-6.6] wifi: wilc1000: validate monitor transmit frame headers Sasha Levin
2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-5.10] iwlwifi: dvm: add missing cleaup for on error path Sasha Levin
2026-10-19 13:52 ` [PATCH AUTOSEL 6.18] wifi: iwlwifi: validate PNVM SKU TLV length Sasha Levin
2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-6.6] wifi: rsi: Fix types to appease CFI Sasha Levin
2026-10-19 13:52 ` [PATCH AUTOSEL 6.18] wifi: mt76: mt7603: restore hardware PS buffering after a service period Sasha Levin
2026-10-19 13:53 ` [PATCH AUTOSEL 6.18-5.15] wifi: iwlwifi: mvm: reset the smart fifo state upon FW stop Sasha Levin
2026-10-19 13:53 ` [PATCH AUTOSEL 6.18-5.10] wifi: mac80211: ibss: read deauth reason_code after frame length check Sasha Levin
2026-10-19 13:53 ` [PATCH AUTOSEL 6.18-5.10] wifi: brcmfmac: validate msgbuf flowring IDs before use Sasha Levin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox