* [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; 5+ 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] 5+ 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; 5+ 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] 5+ 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; 5+ 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] 5+ 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
0 siblings, 0 replies; 5+ 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] 5+ 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; 5+ 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] 5+ messages in thread
end of thread, other threads:[~2026-11-09 6:43 UTC | newest]
Thread overview: 5+ 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-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®