All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Luka Gejak" <luka.gejak@linux.dev>
To: "Zeshan Ahmed Nobin" <zeshanahmednobin@gmail.com>,
	linux-wireless@vger.kernel.org
Cc: "Ping-Ke Shih" <pkshih@realtek.com>
Subject: Re: [PATCH rtw-next] wifi: rtw88: 8822c: fix out-of-bounds access in cck_pd_set
Date: Fri, 06 Nov 2026 15:07:46 +0000	[thread overview]
Message-ID: <f6a7d3272fe7635c6a83698dfab5d85500437ca6@linux.dev> (raw)
In-Reply-To: <20261105113415.73184-1-zeshanahmednobin@gmail.com>

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

  reply	other threads:[~2026-11-06 15:07 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
2026-11-07 12:42   ` Zeshan Ahmed Nobin
2026-11-07 14:39     ` Luka Gejak

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=f6a7d3272fe7635c6a83698dfab5d85500437ca6@linux.dev \
    --to=luka.gejak@linux.dev \
    --cc=linux-wireless@vger.kernel.org \
    --cc=pkshih@realtek.com \
    --cc=zeshanahmednobin@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.