* [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* Re: [PATCH rtw-next] wifi: rtw88: 8822c: fix out-of-bounds access in cck_pd_set
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
0 siblings, 1 reply; 4+ messages in thread
From: Luka Gejak @ 2026-11-06 15:07 UTC (permalink / raw)
To: Zeshan Ahmed Nobin, linux-wireless; +Cc: Ping-Ke Shih
Hi Zeshan,
Thanks for tracking this down. Few things below.
November 5, 2026 at 12:34 PM, "Zeshan Ahmed Nobin" <zeshanahmednobin@gmail.com> wrote:
>
> 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>
> ---
This is a lot of testing data in commit message. Are you sure all of
it is necessary or maybe big chunk of it can be moved under ---, so
commit message stays clean?
> 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.
> + */
We do not use this style for comments anymore. Current style is:
/*
* text
* text
*/
> + if (bw >= ARRAY_SIZE(dm_info->cck_pd_lv) ||
> + nrx >= ARRAY_SIZE(dm_info->cck_pd_lv[0]))
> + return;
As far as I can see the nrx part can never be true, since nrx is a two bit
field and cck_pd_lv[0] has RTW_RF_PATH_MAX entries. The commit message
says that too.
The array where nrx seems to matter is rtw8822c_cck_pd_reg[], which only
has entries for nrx 0 and 1. For 2 and 3 the rows are all zero, so
rtw8822c_phy_cck_pd_set_reg() gets past its WARN_ON() and does a read
modify write of register 0x0 with a zero mask, with __ffs(0) in
rtw_read32_mask(rtwdev, 0x0, 0x0)
rtw_write32_mask(rtwdev, 0x0, 0x0, pd)
With all ones from PCIe bw is 3 as well, so your check catches that. But
on USB a failed read returns whatever was left in its usb_data[] slot, so
if I read it right bw 0 or 1 with nrx 2 or 3 is possible there once the
device stops answering.
That is not new with this patch. But since nrx is checked anyway, maybe
check it against the two entries rtw8822c_cck_pd_reg[] has for each bw,
or drop the nrx part if you want to keep the fix to bw only.
Best regards,
Luka Gejak
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH rtw-next] wifi: rtw88: 8822c: fix out-of-bounds access in cck_pd_set
2026-11-06 15:07 ` Luka Gejak
@ 2026-11-07 12:42 ` Zeshan Ahmed Nobin
2026-11-07 14:39 ` Luka Gejak
0 siblings, 1 reply; 4+ messages in thread
From: Zeshan Ahmed Nobin @ 2026-11-07 12:42 UTC (permalink / raw)
To: Luka Gejak; +Cc: linux-wireless, Ping-Ke Shih
Hi Luka,
Thanks for the review.
> This is a lot of testing data in commit message. Are you sure all of
> it is necessary or maybe big chunk of it can be moved under ---, so
> commit message stays clean?
Agreed. In v2 the commit message is much shorter (the problem, one
trace and the fix), and the test data is below the --- line.
> We do not use this style for comments anymore. Current style is:
>
> /*
> * text
> * text
> */
Will fix in v2.
> The array where nrx seems to matter is rtw8822c_cck_pd_reg[], which only
> has entries for nrx 0 and 1. For 2 and 3 the rows are all zero, so
> rtw8822c_phy_cck_pd_set_reg() gets past its WARN_ON() and does a read
> modify write of register 0x0 with a zero mask, with __ffs(0) in
[...]
> That is not new with this patch. But since nrx is checked anyway, maybe
> check it against the two entries rtw8822c_cck_pd_reg[] has for each bw,
> or drop the nrx part if you want to keep the fix to bw only.
Good catch, you are right. I only have the PCIe card. There a failed
read returns all ones, so nrx = 3 always comes with bw = 3, and the bw
check returns before rtw8822c_phy_cck_pd_set_reg() is reached. I can't
test the USB case.
So I'd like to keep this patch to bw only and drop the nrx part in v2.
The nrx case is worth its own fix. I'm happy to send a separate patch
for it (I could only test it on PCIe by forcing the value, not on a USB
device), unless you'd rather send it yourself since you found it.
Thanks,
Zeshan
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH rtw-next] wifi: rtw88: 8822c: fix out-of-bounds access in cck_pd_set
2026-11-07 12:42 ` Zeshan Ahmed Nobin
@ 2026-11-07 14:39 ` Luka Gejak
0 siblings, 0 replies; 4+ messages in thread
From: Luka Gejak @ 2026-11-07 14:39 UTC (permalink / raw)
To: Zeshan Ahmed Nobin; +Cc: linux-wireless, Ping-Ke Shih
November 7, 2026 at 1:42 PM, "Zeshan Ahmed Nobin" <zeshanahmednobin@gmail.com> wrote:
[ ... ]
> So I'd like to keep this patch to bw only and drop the nrx part in v2.
> The nrx case is worth its own fix. I'm happy to send a separate patch
> for it (I could only test it on PCIe by forcing the value, not on a USB
> device), unless you'd rather send it yourself since you found it.
Sounds good to me. Please go ahead and send it whenever you have time.
The USB device I have is an RTL8723DU, so I can't test that either.
Forcing the value on PCIe seems fine to me. Maybe just note under the
--- line that this is how it was tested.
Best regards,
Luka Gejak
^ permalink raw reply [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