]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
wifi: wilc1000: fix potential RCU dereference issue in wilc_parse_join_bss_param
authorJiawei Ye <jiawei.ye@foxmail.com>
Thu, 29 Aug 2024 08:17:09 +0000 (08:17 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 4 Oct 2024 14:32:28 +0000 (16:32 +0200)
[ Upstream commit 6d7c6ae1efb1ff68bc01d79d94fdf0388f86cdd8 ]

In the `wilc_parse_join_bss_param` function, the TSF field of the `ies`
structure is accessed after the RCU read-side critical section is
unlocked. According to RCU usage rules, this is illegal. Reusing this
pointer can lead to unpredictable behavior, including accessing memory
that has been updated or causing use-after-free issues.

This possible bug was identified using a static analysis tool developed
by myself, specifically designed to detect RCU-related issues.

To address this, the TSF value is now stored in a local variable
`ies_tsf` before the RCU lock is released. The `param->tsf_lo` field is
then assigned using this local variable, ensuring that the TSF value is
safely accessed.

Fixes: 205c50306acf ("wifi: wilc1000: fix RCU usage in connect path")
Signed-off-by: Jiawei Ye <jiawei.ye@foxmail.com>
Reviewed-by: Alexis Lothoré <alexis.lothore@bootlin.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://patch.msgid.link/tencent_466225AA599BA49627FB26F707EE17BC5407@qq.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/wireless/microchip/wilc1000/hif.c

index 7719e4f3e2a23a3736788e781e305bc90aba56ab..2ee8c8e365f89f7ce5fc5d6c03f9327355cf81d3 100644 (file)
@@ -384,6 +384,7 @@ wilc_parse_join_bss_param(struct cfg80211_bss *bss,
        struct wilc_join_bss_param *param;
        u8 rates_len = 0;
        int ies_len;
+       u64 ies_tsf;
        int ret;
 
        param = kzalloc(sizeof(*param), GFP_KERNEL);
@@ -399,6 +400,7 @@ wilc_parse_join_bss_param(struct cfg80211_bss *bss,
                return NULL;
        }
        ies_len = ies->len;
+       ies_tsf = ies->tsf;
        rcu_read_unlock();
 
        param->beacon_period = cpu_to_le16(bss->beacon_interval);
@@ -454,7 +456,7 @@ wilc_parse_join_bss_param(struct cfg80211_bss *bss,
                                    IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
                                    (u8 *)&noa_attr, sizeof(noa_attr));
        if (ret > 0) {
-               param->tsf_lo = cpu_to_le32(ies->tsf);
+               param->tsf_lo = cpu_to_le32(ies_tsf);
                param->noa_enabled = 1;
                param->idx = noa_attr.index;
                if (noa_attr.oppps_ctwindow & IEEE80211_P2P_OPPPS_ENABLE_BIT) {