From 3988009733a9d54e455e2a4fc0f631c8bf40715a Mon Sep 17 00:00:00 2001 From: longli Date: Mon, 1 Mar 2021 15:11:36 +0800 Subject: [PATCH] Issue: WCSWREL-119 Fix RCU warning when call ieee80211_bss_get_ie [Description] [ 179.414989] ============================= [ 179.419033] WARNING: suspicious RCU usage [ 179.428095] 5.11.0-rc1-next-20210104-04456-g31eb08622591 #1 Tainted: G O [ 179.438042] ----------------------------- [ 179.443768] net/wireless/util.c:911 suspicious rcu_dereference_check() usage! [ 179.453802] [ 179.453802] other info that might help us debug this: [ 179.453802] [ 179.463924] [ 179.463924] rcu_scheduler_active = 2, debug_locks = 1 [ 179.472528] 3 locks held by wpa_supplicant/586: [ 179.477109] #0: c18c5058 (cb_lock){++++}-{3:3}, at: genl_rcv+0x14/0x34 [ 179.486226] #1: c18be65c (rtnl_mutex){+.+.}-{3:3}, at: nl80211_pre_doit+0x104/0x1e8 [ 179.496033] #2: c8382da0 (&wdev->mtx){+.+.}-{3:3}, at: nl80211_connect+0x580/0x7ac [ 179.505687] [ 179.505687] stack backtrace: [ 179.511970] CPU: 0 PID: 586 Comm: wpa_supplicant Tainted: G O 5.11.0-rc1-next-20210104-04456-g31eb08622591 #1 [ 179.523233] Hardware name: Freescale i.MX6 SoloX (Device Tree) [ 179.529093] [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [ 179.536883] [] (show_stack) from [] (dump_stack+0xcc/0xf4) [ 179.544142] [] (dump_stack) from [] (ieee80211_bss_get_elem+0x84/0x98) [ 179.552443] [] (ieee80211_bss_get_elem) from [] (woal_cfg80211_assoc+0x50c/0x98c [moal]) [ 179.562737] [] (woal_cfg80211_assoc [moal]) from [] (woal_cfg80211_connect+0x174/0x584 [moal]) [ 179.573748] [] (woal_cfg80211_connect [moal]) from [] (cfg80211_connect+0x1d8/0x7fc) [ 179.583590] [] (cfg80211_connect) from [] (nl80211_connect+0x59c/0x7ac) [ 179.591985] [] (nl80211_connect) from [] (genl_rcv_msg+0x174/0x35c) [ 179.600029] [] (genl_rcv_msg) from [] (netlink_rcv_skb+0xbc/0x11c) [ 179.607975] [] (netlink_rcv_skb) from [] (genl_rcv+0x20/0x34) [ 179.615486] [] (genl_rcv) from [] (netlink_unicast+0x1ac/0x2e0) [ 179.623173] [] (netlink_unicast) from [] (netlink_sendmsg+0x1d4/0x408) [ 179.631465] [] (netlink_sendmsg) from [] (____sys_sendmsg+0x1c4/0x274) [ 179.639764] [] (____sys_sendmsg) from [] (___sys_sendmsg+0xa4/0xd8) [ 179.647803] [] (___sys_sendmsg) from [] (sys_sendmsg+0x50/0x94) [ 179.655491] [] (sys_sendmsg) from [] (ret_fast_syscall+0x0/0x2c) [ 179.663265] Exception stack(0xc839bfa8 to 0xc839bff0) [ 179.668342] bfa0: 01352b30 01351da0 00000005 bec05770 00000000 00000000 [ 179.676545] bfc0: 01352b30 01351da0 b6f49550 00000128 bec05770 bec057e8 00000001 00000004 [ 179.684744] bfe0: 00000128 bec05720 b6c24bbf b6ba4616 [ 179.718172] wlan: Connected to bssid c0:XX:XX:XX:3e:85 successfully [Analysis] RCU warning is happened at rcu_dereference -> rcu_dereference_check, rcu_read_lock_held() is a condition check in it. When rcu_read_lock_held() return false, warning will be printed. [Fix] When call ieee80211_bss_get_ie(), the code and related ie need be wrapped around by rcu_read_lock()/rcu_read_unlock(). Signed-off-by: longli Reviewed-by: Sherry Sun --- mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c b/mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c index a3dd636..bde2558 100644 --- a/mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c +++ b/mxm_wifiex/wlan_src/mlinux/moal_sta_cfg80211.c @@ -1535,8 +1535,10 @@ static int woal_process_country_ie(moal_private *priv, struct cfg80211_bss *bss) mlan_status status = MLAN_STATUS_SUCCESS; ENTER(); + rcu_read_lock(); country_ie = (u8 *)ieee80211_bss_get_ie(bss, WLAN_EID_COUNTRY); if (!country_ie) { + rcu_read_unlock(); PRINTM(MIOCTL, "No country IE found!\n"); woal_send_domain_info_cmd_fw(priv, MOAL_IOCTL_WAIT); LEAVE(); @@ -1545,6 +1547,7 @@ static int woal_process_country_ie(moal_private *priv, struct cfg80211_bss *bss) country_ie_len = country_ie[1]; if (country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN) { + rcu_read_unlock(); PRINTM(MIOCTL, "Wrong Country IE length!\n"); woal_send_domain_info_cmd_fw(priv, MOAL_IOCTL_WAIT); LEAVE(); @@ -1554,6 +1557,7 @@ static int woal_process_country_ie(moal_private *priv, struct cfg80211_bss *bss) priv->phandle->country_code[1] = country_ie[3]; priv->phandle->country_code[2] = ' '; if (is_cfg80211_special_region_code(priv->phandle->country_code)) { + rcu_read_unlock(); PRINTM(MIOCTL, "Skip special region code in CountryIE"); LEAVE(); return 0; @@ -1565,6 +1569,7 @@ static int woal_process_country_ie(moal_private *priv, struct cfg80211_bss *bss) /* Allocate an IOCTL request buffer */ req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11d_cfg)); if (req == NULL) { + rcu_read_unlock(); PRINTM(MERROR, "Fail to allocate mlan_ds_11d_cfg buffer\n"); ret = MLAN_STATUS_FAILURE; goto done; @@ -1599,6 +1604,8 @@ static int woal_process_country_ie(moal_private *priv, struct cfg80211_bss *bss) PRINTM(MCMND, "11D: Country IE: %c%c band=%d no_of_sub_band=%d\n", country_ie[2], country_ie[3], priv->phandle->band, cfg_11d->param.domain_info.no_of_sub_band); + rcu_read_unlock(); + /* Send domain info command to FW */ status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT); if (status != MLAN_STATUS_SUCCESS) { @@ -2366,11 +2373,13 @@ static int woal_cfg80211_associate(struct wiphy *wiphy, struct net_device *dev, priv->auth_alg = 0xFFFF; memset(&ssid_bssid, 0, sizeof(mlan_ssid_bssid)); + rcu_read_lock(); ssid_ie = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID); moal_memcpy_ext(priv->phandle, ssid_bssid.bssid, req->bss->bssid, ETH_ALEN, sizeof(ssid_bssid.bssid)); if (!ssid_ie) { + rcu_read_unlock(); ret = -EINVAL; goto done; } @@ -2378,6 +2387,7 @@ static int woal_cfg80211_associate(struct wiphy *wiphy, struct net_device *dev, moal_memcpy_ext(priv->phandle, ssid_bssid.ssid.ssid, ssid_ie + 2, ssid_ie[1], sizeof(ssid_bssid.ssid.ssid)); ssid_bssid.ssid.ssid_len = ssid_ie[1]; + rcu_read_unlock(); if (ssid_bssid.ssid.ssid_len > MW_ESSID_MAX_SIZE) { PRINTM(MERROR, "Invalid SSID - aborting\n");