rtl8188eu: Change some locking around rtw_get_sec_ie()

Routine rtw_get_sec_ie() appears to suffer from a bug triggered under
unusual circumstances. This bug is exposed by first sending a deauthentication
frame and at the same time sending a much larger frame. After doing some debugging
the cause of the lockup of the CPU was that while rtw_get_sec_ie() attempts to
read the beacon frame sent by the router/AP, the size of the beacon is changed
since it is a reference and not a copy. By having a "rogue" beacon frame being
very large which isn't normal and not considered in the design, the computer
was stuck in an endless CPU lockup.

Routine translate_scan(), which calls rtw_get_sec_ie() is protected by a
spinlock. Add that spinlock around other calls of the routine.

Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
This commit is contained in:
Larry Finger 2022-07-20 15:20:33 -05:00
parent 5f636ea7dd
commit 24b960c5c0
4 changed files with 6 additions and 2 deletions

View file

@ -658,7 +658,7 @@ int rtw_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher, int *pairwi
int rtw_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len, u8 *wpa_ie, u16 *wpa_len)
{
u8 authmode, sec_idx;
int i;
u8 i;
u8 wpa_oui[4] = {0x0, 0x50, 0xf2, 0x01};
uint cnt;

View file

@ -683,7 +683,9 @@ unsigned int OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame)
if (pbss) {
if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) {
update_network(&(pmlmepriv->cur_network.network), pbss, padapter, true);
spin_lock_bh(&padapter->mlmepriv.scanned_queue.lock);
rtw_get_bcn_info(&(pmlmepriv->cur_network));
spin_unlock_bh(&padapter->mlmepriv.scanned_queue.lock);
}
kfree(pbss);
}

View file

@ -946,6 +946,7 @@ int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len)
bssid->Length = sizeof(struct wlan_bssid_ex) - MAX_IE_SZ + len;
spin_lock_bh(&Adapter->mlmepriv.scanned_queue.lock);
/* below is to copy the information element */
bssid->IELength = len;
memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength);
@ -1047,6 +1048,7 @@ int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len)
}
rtw_get_sec_ie(bssid->IEs, bssid->IELength, NULL, &rsn_len, NULL, &wpa_len);
spin_unlock_bh(&Adapter->mlmepriv.scanned_queue.lock);
if (rsn_len > 0) {
encryp_protocol = ENCRYP_PROTOCOL_WPA2;
@ -1102,6 +1104,7 @@ int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len)
return _SUCCESS;
_mismatch:
spin_unlock_bh(&Adapter->mlmepriv.scanned_queue.lock);
kfree(bssid);
return _FAIL;

View file

@ -218,7 +218,6 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
pxmitpriv->ack_tx = false;
_rtw_mutex_init(&pxmitpriv->ack_tx_mutex);
rtw_sctx_init(&pxmitpriv->ack_tx_ops, 0);
rtw_hal_init_xmit_priv(padapter);
exit: