All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Seiderer <ps.report@gmx.net>
To: Lech Perczak <lech.perczak@camlingroup.com>
Cc: "Jérôme Pouiller" <jerome.pouiller@silabs.com>,
	linux-wireless@vger.kernel.org,
	"Paweł Lenkow" <pawel.lenkow@camlingroup.com>,
	"Kalle Valo" <kvalo@kernel.org>,
	"Krzysztof Drobiński" <krzysztof.drobinski@camlingroup.com>,
	"Johannes Berg" <johannes@sipsolutions.net>
Subject: Re: [PATCH] wifi: wfx: fix memory corruption by limiting max_rates to 4
Date: Thu, 15 Sep 2022 20:21:57 +0200	[thread overview]
Message-ID: <20220915202157.6fff5ef8@gmx.net> (raw)
In-Reply-To: <41f23be7-3385-e6cc-9c76-f88b1dd5ebd2@camlingroup.com>

Hello *,

On Thu, 15 Sep 2022 16:02:34 +0200, Lech Perczak <lech.perczak@camlingroup.com> wrote:

> Hi Jérôme,
> 
> Answers inline.
> [Add Krzysztof in Cc:]
> 
> W dniu 15.09.2022 o 15:39, Jérôme Pouiller pisze:
> > [Add Peter in Cc:]
> >
> > On Thursday 15 September 2022 15:14:45 CEST Lech Perczak wrote:  
> > > From: Paweł Lenkow <pawel.lenkow@camlingroup.com>
> > >
> > > During our testing of WFM200 module over SDIO on i.MX6Q-based platform,
> > > we discovered a memory corruption on the system, tracing back to the wfx
> > > driver. Using kfence, it was possible to trace it back to the root
> > > cause, which is hw->max_rates set to 8 in wfx_init_common,
> > > while the maximum defined by IEEE80211_TX_TABLE_SIZE is 4.
> > >
> > > This causes array out-of-bounds writes during updates of the rate table,
> > > as seen below:
> > >
> > > BUG: KFENCE: memory corruption in kfree_rcu_work+0x320/0x36c
> > >
> > > Corrupted memory at 0xe0a4ffe0 [ 0x03 0x03 0x03 0x03 0x01 0x00 0x00
> > > 0x02 0x02 0x02 0x09 0x00 0x21 0xbb 0xbb 0xbb ] (in kfence-#81):
> > > kfree_rcu_work+0x320/0x36c
> > > process_one_work+0x3ec/0x920
> > > worker_thread+0x60/0x7a4
> > > kthread+0x174/0x1b4
> > > ret_from_fork+0x14/0x2c
> > > 0x0
> > >
> > > kfence-#81: 0xe0a4ffc0-0xe0a4ffdf, size=32, cache=kmalloc-64
> > >
> > > allocated by task 297 on cpu 0 at 631.039555s:
> > > minstrel_ht_update_rates+0x38/0x2b0 [mac80211]
> > > rate_control_tx_status+0xb4/0x148 [mac80211]
> > > ieee80211_tx_status_ext+0x364/0x1030 [mac80211]
> > > ieee80211_tx_status+0xe0/0x118 [mac80211]
> > > ieee80211_tasklet_handler+0xb0/0xe0 [mac80211]
> > > tasklet_action_common.constprop.0+0x11c/0x148
> > > __do_softirq+0x1a4/0x61c
> > > irq_exit+0xcc/0x104
> > > call_with_stack+0x18/0x20
> > > __irq_svc+0x80/0xb0
> > > wq_worker_sleeping+0x10/0x100
> > > wq_worker_sleeping+0x10/0x100
> > > schedule+0x50/0xe0
> > > schedule_timeout+0x2e0/0x474
> > > wait_for_completion+0xdc/0x1ec
> > > mmc_wait_for_req_done+0xc4/0xf8
> > > mmc_io_rw_extended+0x3b4/0x4ec
> > > sdio_io_rw_ext_helper+0x290/0x384
> > > sdio_memcpy_toio+0x30/0x38
> > > wfx_sdio_copy_to_io+0x88/0x108 [wfx]
> > > wfx_data_write+0x88/0x1f0 [wfx]
> > > bh_work+0x1c8/0xcc0 [wfx]
> > > process_one_work+0x3ec/0x920
> > > worker_thread+0x60/0x7a4
> > > kthread+0x174/0x1b4
> > > ret_from_fork+0x14/0x2c 0x0
> > >
> > > Limit hw->max_rates to not exceed IEEE80211_TX_RATE_TABLE_SIZE (4).
> > >
> > > To bring back previous value, the global table size limit needs to be
> > > increased beforehand in mac80211.h, or by limiting the iteration count
> > > in minstrel_ht_update_rates against IEEE80211_TX_RATE_TABLE_SIZE as
> > > well.
> > >
> > > Fixes: e16e7f0716a6 ("staging: wfx: instantiate mac80211 data")  
> >
> > I think the issue has been introduced by ee0e16ab756a ("mac80211:
> > minstrel_ht: fill all requested rates").

Ups, sorry for creating a regression (and many thanks for investigation)...

> >
> >  
> > > Cc: Jérôme Pouiller <jerome.pouiller@silabs.com>
> > > Cc: Kalle Valo <kvalo@kernel.org>
> > > Link: https://urldefense.com/v3/__https://lore.kernel.org/all/12e5adcd-8aed-f0f7-70cc-4fb7b656b829@camlingroup.com/__;!!N30Cs7Jr!ReVaYMRjWoJzG95KRgrZTGAw0bmt5lnLLpRkt574SRvIoKLD2xl53YKUiLpN4PfXpjSLIQ9KvgVy9Wi4jeJE8axP9M4Odgk$ <https://urldefense.com/v3/__https://lore.kernel.org/all/12e5adcd-8aed-f0f7-70cc-4fb7b656b829@camlingroup.com/__;!!N30Cs7Jr!ReVaYMRjWoJzG95KRgrZTGAw0bmt5lnLLpRkt574SRvIoKLD2xl53YKUiLpN4PfXpjSLIQ9KvgVy9Wi4jeJE8axP9M4Odgk$>
> > >
> > > Signed-off-by: Paweł Lenkow <pawel.lenkow@camlingroup.com>
> > > Signed-off-by: Lech Perczak <lech.perczak@camlingroup.com>
> > > ---
> > > drivers/net/wireless/silabs/wfx/main.c | 2 +-
> > > 1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/net/wireless/silabs/wfx/main.c b/drivers/net/wireless/silabs/wfx/main.c
> > > index 84d82ddded56..7463fe4b5cae 100644
> > > --- a/drivers/net/wireless/silabs/wfx/main.c
> > > +++ b/drivers/net/wireless/silabs/wfx/main.c
> > > @@ -273,7 +273,7 @@ struct wfx_dev *wfx_init_common(struct device *dev, const struct wfx_platform_da
> > > hw->vif_data_size = sizeof(struct wfx_vif);
> > > hw->sta_data_size = sizeof(struct wfx_sta_priv);
> > > hw->queues = 4;
> > > - hw->max_rates = 8;
> > > + hw->max_rates = 4;

Quick grep for max_rates did show the same for:

drivers/net/wireless/st/cw1200/main.c:  hw->max_rates = 8;

> > > hw->max_rate_tries = 8;
> > > hw->extra_tx_headroom = sizeof(struct wfx_hif_msg) + sizeof(struct wfx_hif_req_tx) +
> > > 4 /* alignment */ + 8 /* TKIP IV */;  
> >

Think the following suggested fix is the right way to go (and keep hw->max_rates
value according to the hardware capabilities(?) of the wifi device)...

> > Do you think the fix should rather be:
> >
> > ------8<----------8<--------
> > --- i/net/mac80211/rc80211_minstrel_ht.c
> > +++ w/net/mac80211/rc80211_minstrel_ht.c
> > @@ -1559,7 +1559,7 @@ minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
> > minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_tp_rate[0]);
> >
> > /* Fill up remaining, keep one entry for max_probe_rate */
> > - for (; i < (mp->hw->max_rates - 1); i++)
> > + for (; i < min(mp->hw->max_rates, IEEE80211_TX_RATE_TABLE_SIZE) - 1; i++)
> > minstrel_ht_set_rate(mp, mi, rates, i, mi->max_tp_rate[i]);
> >

Same change needed here:

> > if (i < mp->hw->max_rates)

    if (i < min(mp->hw->max_rates, IEEE80211_TX_RATE_TABLE_SIZE))

> > ------8<----------8<--------
> >  
> We thought about this as well - or about adding assertion to the function which does the memory allocation,
> but there are more 4-element arrays in mac80211, handled under different defines, which can be confusing.
> 
> carl9170 driver has BUILD_BUG_ON to guard from that precisely - see:
> https://elixir.bootlin.com/linux/latest/source/drivers/net/wireless/ath/carl9170/tx.c#L879
> I think, that the second BUILD_BUG_ON could be moved to mac80211 core, so that it is checked always,
> not only when CARL9170 is enabled.
> 
> I think both changes should be applied - or, alternatively, in minstrel_ht_set_rate, we could use:
> BUG_ON(mp->hw->max_rates > IEEE80211_TX_RATE_TABLE_SIZE);
> to quickly catch misbehaving drivers in future.

Think with the suggested changes to minstrel_ht_set_rate no further assertion
is needed...

Regards,
Peter

> 
> Since this concerns mac80211 core, let's add Johannes to the loop as well.
> >
> >
> > -- 
> > Jérôme Pouiller
> >
> >  


  reply	other threads:[~2022-09-15 18:22 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-15 13:14 [PATCH] wifi: wfx: fix memory corruption by limiting max_rates to 4 Lech Perczak
2022-09-15 13:39 ` Jérôme Pouiller
2022-09-15 14:02   ` Lech Perczak
2022-09-15 18:21     ` Peter Seiderer [this message]
2022-09-19 15:17       ` Pawel Lenkow

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=20220915202157.6fff5ef8@gmx.net \
    --to=ps.report@gmx.net \
    --cc=jerome.pouiller@silabs.com \
    --cc=johannes@sipsolutions.net \
    --cc=krzysztof.drobinski@camlingroup.com \
    --cc=kvalo@kernel.org \
    --cc=lech.perczak@camlingroup.com \
    --cc=linux-wireless@vger.kernel.org \
    --cc=pawel.lenkow@camlingroup.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.