[PATCH v2] staging: rtl8723bs: Fix uninitialized variable

From: Wenli Looi
Date: Sun Jun 06 2021 - 14:49:29 EST


Uninitialized struct with invalid pointer causes BUG and prevents access
point from working. Access point works once I apply this patch.

This problem seems to have been present from the time the driver was
added to staging. Most users probably do not use access point so they
will not encounter this bug.

https://forum.armbian.com/topic/14727-wifi-ap-kernel-bug-in-kernel-5444/
has more details.

kzalloc() seems to be what other drivers are doing in the same situation
of creating struct station_info and calling cfg80211_new_sta. In
particular, other drivers like ath6kl and mwifiex will silently return
when kzalloc fails, so this seems like the right behavior. (mwifiex
returns -ENOMEM from the place kzalloc is called, but if you follow the
chain of calls, the return value is ultimately ignored)

Links to same situation in other drivers:
https://github.com/torvalds/linux/blob/f5b6eb1e018203913dfefcf6fa988649ad11ad6e/drivers/net/wireless/ath/ath6kl/main.c#L488
https://github.com/torvalds/linux/blob/f5b6eb1e018203913dfefcf6fa988649ad11ad6e/drivers/net/wireless/marvell/mwifiex/uap_event.c#L120

Signed-off-by: Wenli Looi <wlooi@xxxxxxxxxxx>
---

v1 -> v2: Switched from large stack variable to kzalloc
---
.../staging/rtl8723bs/os_dep/ioctl_cfg80211.c | 28 ++++++++++---------
1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
index 9a6e47877..3bc498558 100644
--- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
+++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
@@ -2082,20 +2082,22 @@ static int cfg80211_rtw_flush_pmksa(struct wiphy *wiphy,
void rtw_cfg80211_indicate_sta_assoc(struct adapter *padapter, u8 *pmgmt_frame, uint frame_len)
{
struct net_device *ndev = padapter->pnetdev;
+ struct station_info *sinfo;
+ u8 ie_offset;

- {
- struct station_info sinfo;
- u8 ie_offset;
- if (GetFrameSubType(pmgmt_frame) == WIFI_ASSOCREQ)
- ie_offset = _ASOCREQ_IE_OFFSET_;
- else /* WIFI_REASSOCREQ */
- ie_offset = _REASOCREQ_IE_OFFSET_;
-
- sinfo.filled = 0;
- sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset;
- sinfo.assoc_req_ies_len = frame_len - WLAN_HDR_A3_LEN - ie_offset;
- cfg80211_new_sta(ndev, GetAddr2Ptr(pmgmt_frame), &sinfo, GFP_ATOMIC);
- }
+ sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL);
+ if (!sinfo)
+ return;
+
+ if (GetFrameSubType(pmgmt_frame) == WIFI_ASSOCREQ)
+ ie_offset = _ASOCREQ_IE_OFFSET_;
+ else /* WIFI_REASSOCREQ */
+ ie_offset = _REASOCREQ_IE_OFFSET_;
+
+ sinfo->assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset;
+ sinfo->assoc_req_ies_len = frame_len - WLAN_HDR_A3_LEN - ie_offset;
+ cfg80211_new_sta(ndev, GetAddr2Ptr(pmgmt_frame), sinfo, GFP_ATOMIC);
+ kfree(sinfo);
}

void rtw_cfg80211_indicate_sta_disassoc(struct adapter *padapter, unsigned char *da, unsigned short reason)
--
2.25.1