Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH rtw-next] wifi: rtw88: 8822c: fix out-of-bounds access in cck_pd_set
@ 2026-11-05 11:34 Zeshan Ahmed Nobin
  2026-11-06 15:07 ` Luka Gejak
  0 siblings, 1 reply; 4+ messages in thread
From: Zeshan Ahmed Nobin @ 2026-11-05 11:34 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ping-Ke Shih

rtw8822c_phy_cck_pd_set() reads the current bandwidth from a 2-bit
register field (0x9b0[3:2]) and uses it as the first index into
dm_info->cck_pd_lv[2][RTW_RF_PATH_MAX]. CCK PD only runs on 2.4 GHz,
where the bandwidth is 20 or 40 MHz, so the array has two entries.

When the chip stops responding on the PCIe bus, register reads return
all ones and bw becomes 3. The function then reads cck_pd_lv[3][nrx]
three times. rtw8822c_phy_cck_pd_set_reg() rejects bw with WARN_ON()
and returns, but the caller still writes new_lvl to cck_pd_lv[3][nrx],
past the end of the array, into the fields that follow it in struct
rtw_dm_info. Depending on the byte read back, pd_lvl[cur_lvl] and
cs_lvl[cur_lvl] can also read past the end of the on-stack arrays.

On Ubuntu's 7.0.0-42 kernel, whose line numbers here are three lower
than in mainline, each chip failure seen so far logged one report for
each of the three reads, then the WARN_ON(), then one for the write:

  UBSAN: array-index-out-of-bounds in .../rtw88/rtw8822c.c:4407:21
  index 3 is out of range for type 'u8 [2][4]'
  Workqueue: phy0 rtw_watch_dog_work [rtw88_core]
  Call Trace:
   <TASK>
   __ubsan_handle_out_of_bounds+0xdd/0x120
   rtw8822c_phy_cck_pd_set+0x33c/0x510 [rtw88_8822c]
   rtw_phy_dynamic_mechanism+0x310/0x330 [rtw88_core]
   rtw_watch_dog_work+0x217/0x330 [rtw88_core]
  UBSAN: array-index-out-of-bounds in .../rtw88/rtw8822c.c:4410:24
  UBSAN: array-index-out-of-bounds in .../rtw88/rtw8822c.c:4413:30
  WARNING: .../rtw88/rtw8822c.c:4364 at rtw8822c_phy_cck_pd_set+0x322
  UBSAN: array-index-out-of-bounds in .../rtw88/rtw8822c.c:4422:20

Return early when bw is out of range. nrx comes from a 2-bit field and
always fits the second dimension; it is checked as well so that both
indices are validated before use. The chip is already unusable at that
point; this only stops the driver from corrupting its own state.

On the machine below, every boot with a chip failure logged these
reports together with the WARN_ON(): 17 boots between 2026-10-18 and
2026-11-02 on Ubuntu's 6.8.0-147 kernel, and 3 boots on 2026-11-04/05
on 7.0.0-42. Boots without a chip failure logged neither. With this
patch applied to 6.8.0-147, 5 boots with chip failures logged no UBSAN
report and no WARN_ON().

Seen on an RTL8822CE in an ASUS TUF Gaming A15 FA506IU whose chip
intermittently drops off the PCIe bus.

The problem was found from the UBSAN reports above. The analysis, the
fix and this message were written with the help of an AI coding
assistant (Claude Opus 5.5 by Anthropic), then reviewed and tested by
the submitter as described above.

Fixes: 479c4ee931a6 ("rtw88: add dynamic cck pd mechanism")
Cc: stable@vger.kernel.org
Signed-off-by: Zeshan Ahmed Nobin <zeshanahmednobin@gmail.com>
---

Notes:
    Tested only on Ubuntu's 6.8.0-147 kernel with this change applied. On
    rtw-next (dc16902cad9c) it is build-tested only: rtw8822c.o compiles
    with W=1 and no warnings, before and after the patch.
    
    On the AI assistance: I asked an AI coding assistant to help find out
    why the RTL8822CE in this laptop keeps failing. Over several sessions it
    analyzed the kernel logs, found this out-of-bounds access in the UBSAN
    reports, wrote the fix and drafted the commit message. It also checked
    the code against rtw-next and recounted the numbers above from the saved
    logs. I reviewed the patch and the message before sending.

 drivers/net/wireless/realtek/rtw88/rtw8822c.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
index 09315d23e2c4..a29611ff248d 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
@@ -4406,6 +4406,13 @@ static void rtw8822c_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl)
 	nrx = (u8)rtw_read32_mask(rtwdev, 0x1a2c, 0x60000);
 	bw = (u8)rtw_read32_mask(rtwdev, 0x9b0, 0xc);
 
+	/* cck_pd_lv[] only has entries for 20 and 40 MHz. A chip that stops
+	 * responding on the bus reads back as all ones, giving bw = 3.
+	 */
+	if (bw >= ARRAY_SIZE(dm_info->cck_pd_lv) ||
+	    nrx >= ARRAY_SIZE(dm_info->cck_pd_lv[0]))
+		return;
+
 	rtw_dbg(rtwdev, RTW_DBG_PHY, "lv: (%d) -> (%d) bw=%d nr=%d cck_fa_avg=%d\n",
 		dm_info->cck_pd_lv[bw][nrx], new_lvl, bw, nrx,
 		dm_info->cck_fa_avg);

base-commit: dc16902cad9c6b08df9395a510c7be44fbab545d
-- 
2.43.0


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

end of thread, other threads:[~2026-11-07 14:39 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-05 11:34 [PATCH rtw-next] wifi: rtw88: 8822c: fix out-of-bounds access in cck_pd_set Zeshan Ahmed Nobin
2026-11-06 15:07 ` Luka Gejak
2026-11-07 12:42   ` Zeshan Ahmed Nobin
2026-11-07 14:39     ` Luka Gejak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox