openwrt / openwrt/mt76

wifi: mt76/mt7925: use-after-free in mt76_wcid_add_poll() from RX-poll (sta_poll_list corruption → panic)

Open
#1,096 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C
Stars
888
Forks
436
PR merge metrics
No merged PRs in 30d

Description

(Issue written by Claude after a many-hour back-and-forth debugging session involving six separate crashes...)

wifi: mt76/mt7925: use-after-free in mt76_wcid_add_poll() from RX-poll (sta_poll_list corruption → panic)

Summary

On a MediaTek MT7925 (RZ717), the RX-NAPI thread corrupts dev->sta_poll_list in
mt76_wcid_add_poll() while handling TX-status / TX-free completions on the unified RX queue.
With list debugging enabled this is caught as kernel BUG at lib/list_debug.c:32 and panics the
machine ("Fatal exception in interrupt") within minutes-to-hours of normal use. It reproduces
independently of firmware version, kernel point-release, 6 GHz/MLO, and roaming, which points to
a station/wcid lifetime use-after-free on the RX-completion path (a bare mt76_wcid * retained in
mt76_rx_status while the station can be freed concurrently).

Hardware / software

  • Device: MediaTek MT7925 (RZ717) Wi-Fi 7 160MHz, PCI 14c3:0717, mt7925e
  • Platform: Framework Laptop 16 (AMD Ryzen AI 9 HX 370 / Strix Point), BIOS 03.06
  • Kernel: reproduced on 7.1.1 and 7.1.2 (in-tree mt76); reproduces with list hardening on
  • Firmware: reproduced on mt7925 fw builds 20260605 and 20260414 (both)

Backtrace (verbatim; representative of ~5 captures)

slab kmalloc-rnd-03-8k start ffff8e7e29990000 pointer offset 4176 size 8192
list_add corruption. prev->next should be next (ffff8e79c1ad8908), but was ffff8e7e29991050. (prev=ffff8e7e29991050).
kernel BUG at lib/list_debug.c:32!
Oops: invalid opcode: 0000 [#1] SMP NOPTI
CPU: 19 PID: 1185 Comm: napi/phy0-0 Tainted: G U O 7.1.2 #1
Hardware name: Framework Laptop 16 (AMD Ryzen AI 300 Series)/FRANMHCP09, BIOS 03.06 04/23/2026
RIP: 0010:__list_add_valid_or_report+0xa8/0xb0
Call Trace:
 mt76_wcid_add_poll+0x95/0xd0      [mt76]
 mt7925_mac_tx_free+0x175/0x310    [mt7925_common]
 mt7925_rx_check+0x5c/0xc0         [mt7925_common]
 mt76_dma_rx_poll+0x4a2/0x6d0      [mt76]
 mt792x_poll_rx+0x52/0xe0          [mt792x_lib]
 __napi_poll+0x30/0x1f0
 napi_threaded_poll_loop+0x214/0x260
 napi_threaded_poll+0xdf/0x120
 kthread+0xe2/0x110
 ret_from_fork+0x251/0x330 / ret_from_fork_asm+0x1a/0x30
Kernel panic - not syncing: Fatal exception in interrupt

The middle frame is mt7925_mac_tx_free or mt7925_mac_add_txs.part.0 (both via
mt7925_rx_check); the fault is always mt76_wcid_add_poll → __list_add_valid_or_report.

Reproduction

Use the NIC normally (any sustained associated RX traffic). Panic occurs within minutes to a few
hours, in the napi/phy0-0 thread. No special action required; it has fired during a video call,
immediately after resume-from-hibernate at the lock screen, and while idle on a single BSSID.

Ruled out (so please don't be misled by these — all tested)

  • 6 GHz / MLO / roaming: reproduced with 6 GHz hard-disabled (iwd BandModifier6GHz=0.0),
    single BSSID, no roam.
  • Firmware: reproduced on mt7925 fw 20260605 and pinned 20260414.
  • Kernel point-release: reproduced on 7.1.1 and 7.1.2 (7.1.2 has no mt76 changes).
  • Not a GPU/display issue (on-screen corruption is the post-panic frozen scanout); kernel taint is
    unrelated out-of-tree modules (netatop, framework_laptop), neither in the backtrace.

Likely root cause

mt76_rx_status carries a raw struct mt76_wcid * (resolved via mt792x_rx_get_wcid()); the
TX-status/TX-free completion handlers reached from mt7925_rx_check() call mt76_wcid_add_poll()
on it. A station/link removed concurrently frees the embedded mt76_wcid (8 KiB slab object,
offset 4176), and the stale pointer's poll_list then corrupts dev->sta_poll_list.

Likely fix (already written, not yet merged)

The pending patch "wifi: mt76: mt792x: fix use-after-free in mt76_rx_poll_complete" — which
replaces the bare mt76_wcid * in mt76_rx_status with a u16 wcid_idx resolved via
__mt76_wcid_ptr() under RCU (adds MT76_WCID_IDX_INVALID) — appears to address exactly this. As
of 2026-06-30 it is not in 7.1.1, 7.1.2, or 7.2-rc1, and a reviewer note indicates it still
needs the mt76x02 RX path converted to build everywhere. Requesting it be completed and merged
(with a Fixes: tag + Cc: stable). Full crash dumps for all occurrences available on request.

Related issues (checked — none is a duplicate of this exact STA-mode RX-poll signature)

  • openwrt/mt76 #763 — same class (sta_poll_list list corruption during roaming) but mt7915, older. Closest conceptual relative.
  • openwrt/mt76 #909 / openwrt #16273 — mt7925 panic in mt7925_mac_sta_add (paging fault), AP/hostapd mode. Same subsystem (sta/wcid lifecycle), different signature.
  • openwrt/mt76 #1014 — mt7925 WARNING in mt7925_mcu_set_mlo_roc during AP-mode MLO setup. Different function.
  • openwrt/mt76 #1023 — mt7925 panic in mt76_connac2_load_patch (firmware load buffer overflow). Unrelated.
    This report is STA/client mode, mt76_wcid_add_poll from the RX-poll/TX-completion path — distinct from all of the above.

crash-oops-7.1.2-20260630-0337.txt

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading mt76_rx_status, mt76_wcid_add_poll(), mt7925_rx_check(), and the pending “fix use-after-free in mt76_rx_poll_complete” patch. Check the mt76x02 RX path noted by the reviewer and reproduce or validate the failure with the provided crash trace; done means the lifetime fix builds across the affected RX paths and prevents the stale wcid poll-list corruption.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, linux
Domain
networking, operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.