* [PATCH RESEND rtw-next v2 0/2] wifi: rtw88: 8822c: check register values in cck_pd_set @ 2026-11-08 18:28 Zeshan Ahmed Nobin 2026-11-08 18:28 ` [PATCH RESEND rtw-next v2 1/2] wifi: rtw88: 8822c: fix out-of-bounds access " Zeshan Ahmed Nobin 2026-11-08 18:28 ` [PATCH RESEND rtw-next v2 2/2] wifi: rtw88: 8822c: ignore nrx values without CCK PD registers Zeshan Ahmed Nobin 0 siblings, 2 replies; 7+ messages in thread From: Zeshan Ahmed Nobin @ 2026-11-08 18:28 UTC (permalink / raw) To: linux-wireless; +Cc: linux-kernel, Ping-Ke Shih, Luka Gejak, Kalle Valo rtw8822c_phy_cck_pd_set() indexes its tables with two values read from the chip, bw and nrx, without checking them first. When the chip stops responding, both can be out of range. Patch 1 handles bw, which goes out of range when an RTL8822CE drops off the PCIe bus. Patch 2 handles nrx, which Luka Gejak found while reviewing v1. v2: - Patch 1: move the test data below the --- line (Luka) - Patch 1: use the preferred multi-line comment style (Luka) - Patch 1: drop the nrx check, which can never be true (Luka) - Patch 2: new v1: https://lore.kernel.org/linux-wireless/20261105113415.73184-1-zeshanahmednobin@gmail.com/ AI assistance: I asked an AI coding assistant to help find out why the RTL8822CE in my laptop keeps failing. It analyzed the kernel logs and found the bw bug (Luka found the nrx one), wrote both fixes, the debug-only changes used for testing, and the messages. I reviewed everything and ran the tests described in each patch before sending. Zeshan Ahmed Nobin (2): wifi: rtw88: 8822c: fix out-of-bounds access in cck_pd_set wifi: rtw88: 8822c: ignore nrx values without CCK PD registers drivers/net/wireless/realtek/rtw88/rtw8822c.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) base-commit: dc16902cad9c6b08df9395a510c7be44fbab545d -- 2.43.0 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH RESEND rtw-next v2 1/2] wifi: rtw88: 8822c: fix out-of-bounds access in cck_pd_set 2026-11-08 18:28 [PATCH RESEND rtw-next v2 0/2] wifi: rtw88: 8822c: check register values in cck_pd_set Zeshan Ahmed Nobin @ 2026-11-08 18:28 ` Zeshan Ahmed Nobin 2026-11-09 6:41 ` Luka Gejak 2026-11-08 18:28 ` [PATCH RESEND rtw-next v2 2/2] wifi: rtw88: 8822c: ignore nrx values without CCK PD registers Zeshan Ahmed Nobin 1 sibling, 1 reply; 7+ messages in thread From: Zeshan Ahmed Nobin @ 2026-11-08 18:28 UTC (permalink / raw) To: linux-wireless; +Cc: linux-kernel, Ping-Ke Shih, Luka Gejak, Kalle Valo rtw8822c_phy_cck_pd_set() reads the bandwidth from a 2-bit register field and uses it as the first index into dm_info->cck_pd_lv[], which only has entries for 20 and 40 MHz. 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], past the end of the array. If that byte differs from new_lvl, it calls rtw8822c_phy_cck_pd_set_reg(), which rejects bw with WARN_ON(), and then writes new_lvl to cck_pd_lv[3][nrx] anyway. UBSAN reports the first of these accesses as: 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] Return early when bw is out of range. The chip is already unusable at that point; this only stops the driver from corrupting its own state. The fix and this message were drafted with an AI coding assistant (Claude Opus 5.5 by Anthropic), then reviewed and tested by the submitter. Fixes: 479c4ee931a6 ("rtw88: add dynamic cck pd mechanism") Cc: stable@vger.kernel.org Signed-off-by: Zeshan Ahmed Nobin <zeshanahmednobin@gmail.com> --- Notes: Testing, on an RTL8822CE in an ASUS TUF Gaming A15 (FA506IU) whose chip intermittently drops off the PCIe bus: - Without this patch, on Ubuntu's 6.8.0-147 and 7.0.0-42 kernels, 22 of the 23 boots with a chip failure logged three UBSAN reports for the reads, the WARN_ON() and one report for the write; the other logged neither. Boots without a failure logged neither. The trace above is from 7.0.0-42, whose line numbers are three lower than mainline here. - With v1 applied to 6.8.0-147, 5 boots with chip failures logged no UBSAN report and no WARN_ON(). - v2 on 6.8.0-147, with a debug-only change that forces bw to 3 on a working chip: in 12 s the function ran 6 times and returned early each time, with no UBSAN report and no WARN_ON(). With the new check also skipped, the same input brought back the UBSAN reports for the three reads and the write and the WARN_ON(), plus two more for pd_lvl[cur_lvl] and cs_lvl[cur_lvl] ("index 36 is out of range for type 's8 [5]'"). - Build-tested on rtw-next (dc16902cad9c) with W=1: no warnings. 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..6343568285bc 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 PCIe bus reads back as all ones, giving bw = 3. + */ + if (bw >= ARRAY_SIZE(dm_info->cck_pd_lv)) + 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); -- 2.43.0 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH RESEND rtw-next v2 1/2] wifi: rtw88: 8822c: fix out-of-bounds access in cck_pd_set 2026-11-08 18:28 ` [PATCH RESEND rtw-next v2 1/2] wifi: rtw88: 8822c: fix out-of-bounds access " Zeshan Ahmed Nobin @ 2026-11-09 6:41 ` Luka Gejak 2026-11-09 18:20 ` Zeshan Ahmed Nobin 0 siblings, 1 reply; 7+ messages in thread From: Luka Gejak @ 2026-11-09 6:41 UTC (permalink / raw) To: Zeshan Ahmed Nobin, linux-wireless; +Cc: linux-kernel, Ping-Ke Shih, Kalle Valo Hi Zeshan, Thanks for the v2. One minor thing. On November 8, 2026 7:28:36 PM GMT+01:00, Zeshan Ahmed Nobin <zeshanahmednobin@gmail.com> wrote: > diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c > index 09315d23e2c4..6343568285bc 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 PCIe bus reads back as all ones, giving bw = 3. > + */ > + if (bw >= ARRAY_SIZE(dm_info->cck_pd_lv)) > + return; As far as I can see bw doesn't have to come from the chip here, since rtw_set_channel() programs the same value it stores in hal. So maybe this could just be bw = rtwdev->hal.current_band_width; CCK PD only runs on 2.4 GHz, so that seems to always be 20 or 40 MHz and the check could go. Or is there a reason to read it from the chip that I missed? Best regards, Luka Gejak ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH RESEND rtw-next v2 1/2] wifi: rtw88: 8822c: fix out-of-bounds access in cck_pd_set 2026-11-09 6:41 ` Luka Gejak @ 2026-11-09 18:20 ` Zeshan Ahmed Nobin 2026-11-09 19:24 ` Luka Gejak 0 siblings, 1 reply; 7+ messages in thread From: Zeshan Ahmed Nobin @ 2026-11-09 18:20 UTC (permalink / raw) To: Luka Gejak; +Cc: linux-wireless, linux-kernel, Ping-Ke Shih, Kalle Valo Hi Luka, On Mon, Nov 09, 2026 at 07:41:46 +0100, Luka Gejak wrote: > As far as I can see bw doesn't have to come from the chip here, since > rtw_set_channel() programs the same value it stores in hal. So maybe > this could just be > > bw = rtwdev->hal.current_band_width; > > CCK PD only runs on 2.4 GHz, so that seems to always be 20 or 40 MHz and > the check could go. Or is there a reason to read it from the chip that I > missed? I couldn't find one. Apart from the BB init table, bits 3:2 of 0x9b0 are only written by rtw8822c_set_channel_bb(), with the bandwidth that rtw_set_channel() also stores in hal. I also checked it on my RTL8822CE with Ubuntu's 6.8 kernel. Its firmware does hardware scans, and at 40 MHz on 2.4 GHz, hal and the register matched at every cck_pd_set call, across 10 scans and a reconnect. So v3 will take bw from hal and drop the check. One consequence: a chip that drops off the PCIe bus still reads nrx back as 3. When the level then changes, rtw8822c_phy_cck_pd_set_reg() gets past its WARN_ON(), since bw is now valid, and does the zero-mask access to register 0x0; forcing nrx to 3 confirmed it. So on PCIe, patch 2 is then what handles a dead chip. In v3 I'll update its message for that and add Cc: stable to it as well. Its code doesn't change; is it fine to keep your Reviewed-by on it? Thanks, Zeshan Ahmed Nobin ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH RESEND rtw-next v2 1/2] wifi: rtw88: 8822c: fix out-of-bounds access in cck_pd_set 2026-11-09 18:20 ` Zeshan Ahmed Nobin @ 2026-11-09 19:24 ` Luka Gejak 0 siblings, 0 replies; 7+ messages in thread From: Luka Gejak @ 2026-11-09 19:24 UTC (permalink / raw) To: Zeshan Ahmed Nobin; +Cc: linux-wireless, linux-kernel, Ping-Ke Shih, Kalle Valo Hi Zeshan, On November 9, 2026 7:20:01 PM GMT+01:00, Zeshan Ahmed Nobin <zeshanahmednobin@gmail.com> wrote: > > patch 2 is then what handles a dead chip. In v3 I'll update its > message for that and add Cc: stable to it as well. Its code doesn't > change; is it fine to keep your Reviewed-by on it? Yes, that matches what I see, so please keep it. "bw has already been checked at that point" in the message and "patch 1 returns first" in the notes won't be true any more, so those need updating too. The forced bw test won't apply either, so maybe run the real chip failure case again with both patches. As far as I can see patch 1 alone would then reach that zero mask access on PCIe, so maybe keep this order and say in the cover letter that the two belong together. Best regards, Luka Gejak ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH RESEND rtw-next v2 2/2] wifi: rtw88: 8822c: ignore nrx values without CCK PD registers 2026-11-08 18:28 [PATCH RESEND rtw-next v2 0/2] wifi: rtw88: 8822c: check register values in cck_pd_set Zeshan Ahmed Nobin 2026-11-08 18:28 ` [PATCH RESEND rtw-next v2 1/2] wifi: rtw88: 8822c: fix out-of-bounds access " Zeshan Ahmed Nobin @ 2026-11-08 18:28 ` Zeshan Ahmed Nobin 2026-11-09 6:43 ` Luka Gejak 1 sibling, 1 reply; 7+ messages in thread From: Zeshan Ahmed Nobin @ 2026-11-08 18:28 UTC (permalink / raw) To: linux-wireless; +Cc: linux-kernel, Ping-Ke Shih, Luka Gejak, Kalle Valo rtw8822c_phy_cck_pd_set() reads nrx, the number of CCK RX paths minus one, from a 2-bit register field. The driver only ever sets it to 0 or 1, for one or two RX paths (see rtw8822c_config_cck_rx_path()), and rtw8822c_cck_pd_reg[] only has registers for those two values; its entries for nrx 2 and 3 are all zero. A device that stops responding can return any value. On USB, a failed read returns whatever an earlier read left in the buffer, so bw can be 0 or 1 while nrx is 2 or 3. When the level then changes, rtw8822c_phy_cck_pd_set_reg() gets past its WARN_ON(), which only checks nrx against RTW_RF_PATH_MAX, and calls rtw_read32_mask() and rtw_write32_mask() on register 0x0 with a zero mask. Both compute __ffs(0), which is undefined, and the write puts back whatever was read from register 0x0. Return early when rtw8822c_cck_pd_reg[] has no registers for nrx; bw has already been checked at that point. The fix and this message were drafted with an AI coding assistant (Claude Opus 5.5 by Anthropic), then reviewed and tested by the submitter. Reported-by: Luka Gejak <luka.gejak@linux.dev> Closes: https://lore.kernel.org/linux-wireless/f6a7d3272fe7635c6a83698dfab5d85500437ca6@linux.dev/ Fixes: 479c4ee931a6 ("rtw88: add dynamic cck pd mechanism") Signed-off-by: Zeshan Ahmed Nobin <zeshanahmednobin@gmail.com> --- Notes: Testing, only on an RTL8822CE (PCIe). There a failed read gives all ones, so bw is 3 as well and patch 1 returns first. A debug-only change forced nrx to 2 on a working chip instead: - With this patch, in 12 s the function ran 6 times and returned early each time. rtw8822c_phy_cck_pd_set_reg() was never called with nrx 2, and there was no UBSAN report. - With the new check skipped, rtw8822c_phy_cck_pd_set_reg() ran with nrx 2, and UBSAN reported "shift exponent 64 is too large for 32-bit type 'unsigned int'" in rtw_read32_mask() and rtw_write32_mask(). - Not tested on USB hardware. - Build-tested on rtw-next (dc16902cad9c) with W=1: no warnings. drivers/net/wireless/realtek/rtw88/rtw8822c.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c index 6343568285bc..acd192684bb1 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c @@ -4413,6 +4413,14 @@ static void rtw8822c_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl) if (bw >= ARRAY_SIZE(dm_info->cck_pd_lv)) return; + /* + * rtw8822c_cck_pd_reg[] only has registers for one and two RX paths + * (nrx 0 and 1); its entries for nrx 2 and 3 are all zero. A device + * that stops responding can still return those values. + */ + if (!rtw8822c_cck_pd_reg[bw][nrx].mask_pd) + 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); -- 2.43.0 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH RESEND rtw-next v2 2/2] wifi: rtw88: 8822c: ignore nrx values without CCK PD registers 2026-11-08 18:28 ` [PATCH RESEND rtw-next v2 2/2] wifi: rtw88: 8822c: ignore nrx values without CCK PD registers Zeshan Ahmed Nobin @ 2026-11-09 6:43 ` Luka Gejak 0 siblings, 0 replies; 7+ messages in thread From: Luka Gejak @ 2026-11-09 6:43 UTC (permalink / raw) To: Zeshan Ahmed Nobin, linux-wireless; +Cc: linux-kernel, Ping-Ke Shih, Kalle Valo On November 8, 2026 7:28:37 PM GMT+01:00, Zeshan Ahmed Nobin <zeshanahmednobin@gmail.com> wrote: >rtw8822c_phy_cck_pd_set() reads nrx, the number of CCK RX paths minus >one, from a 2-bit register field. The driver only ever sets it to 0 or >1, for one or two RX paths (see rtw8822c_config_cck_rx_path()), and >rtw8822c_cck_pd_reg[] only has registers for those two values; its >entries for nrx 2 and 3 are all zero. > >A device that stops responding can return any value. On USB, a failed >read returns whatever an earlier read left in the buffer, so bw can be >0 or 1 while nrx is 2 or 3. When the level then changes, >rtw8822c_phy_cck_pd_set_reg() gets past its WARN_ON(), which only >checks nrx against RTW_RF_PATH_MAX, and calls rtw_read32_mask() and >rtw_write32_mask() on register 0x0 with a zero mask. Both compute >__ffs(0), which is undefined, and the write puts back whatever was read >from register 0x0. > >Return early when rtw8822c_cck_pd_reg[] has no registers for nrx; bw >has already been checked at that point. > >The fix and this message were drafted with an AI coding assistant >(Claude Opus 5.5 by Anthropic), then reviewed and tested by the >submitter. > >Reported-by: Luka Gejak <luka.gejak@linux.dev> >Closes: https://lore.kernel.org/linux-wireless/f6a7d3272fe7635c6a83698dfab5d85500437ca6@linux.dev/ >Fixes: 479c4ee931a6 ("rtw88: add dynamic cck pd mechanism") >Signed-off-by: Zeshan Ahmed Nobin <zeshanahmednobin@gmail.com> >--- Looks good to me, Reviewed-by: Luka Gejak <luka.gejak@linux.dev> Best regards, Luka Gejak ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-11-09 19:24 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-11-08 18:28 [PATCH RESEND rtw-next v2 0/2] wifi: rtw88: 8822c: check register values in cck_pd_set Zeshan Ahmed Nobin 2026-11-08 18:28 ` [PATCH RESEND rtw-next v2 1/2] wifi: rtw88: 8822c: fix out-of-bounds access " Zeshan Ahmed Nobin 2026-11-09 6:41 ` Luka Gejak 2026-11-09 18:20 ` Zeshan Ahmed Nobin 2026-11-09 19:24 ` Luka Gejak 2026-11-08 18:28 ` [PATCH RESEND rtw-next v2 2/2] wifi: rtw88: 8822c: ignore nrx values without CCK PD registers Zeshan Ahmed Nobin 2026-11-09 6:43 ` Luka Gejak
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®