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