FAILED: patch "[PATCH] staging: rtl8723bs: fix OOB reads in rtw_get_sec_ie()," failed to apply to 5.15-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y
git checkout FETCH_HEAD
git cherry-pick -x 1463ca3ec6601cbb097d8d87dbf5dcf1cb86a344
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026071359-gecko-previous-ef42@gregkh' --subject-prefix 'PATCH 5.15.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 1463ca3ec6601cbb097d8d87dbf5dcf1cb86a344 Mon Sep 17 00:00:00 2001
From: Alexandru Hossu <[email protected]>
Date: Fri, 22 May 2026 02:45:31 +0200
Subject: [PATCH] staging: rtl8723bs: fix OOB reads in rtw_get_sec_ie(),
rtw_get_wapi_ie(), and rtw_get_wps_attr()
Three IE/attribute parsing functions have missing bounds checks.
rtw_get_sec_ie() and rtw_get_wapi_ie() iterate over a raw IE buffer without verifying that the header bytes (tag + length) are within the remaining buffer before reading them. Additionally, rtw_get_sec_ie() compares the 4-byte WPA OUI at cnt+2 without checking that at least 6 bytes remain, and rtw_get_wapi_ie() compares a 4-byte WAPI OUI at cnt+6 without checking that at least 10 bytes remain.
rtw_get_wps_attr() reads wps_ie[0] and wps_ie+2 unconditionally at entry, before verifying that wps_ielen is large enough to contain the 6-byte WPS IE header (element_id + length + 4-byte OUI). Inside the attribute loop, get_unaligned_be16() is called on attr_ptr and attr_ptr+2 without checking that 4 bytes remain in the buffer.
Add a cnt+2 bounds check before each loop body in rtw_get_sec_ie() and rtw_get_wapi_ie(), guard each multi-byte comparison with a minimum IE length requirement, add a wps_ielen < 6 early return in rtw_get_wps_attr(), and add a 4-byte bounds check in its inner loop.
drivers/staging/rtl8723bs/core/rtw_ieee80211.c +15 -0
@@ -583,9 +583,14 @@ int rtw_get_wapi_ie(u8 *in_ie, uint in_len, u8 *wapi_ie, u16 *wapi_len) cnt = (_TIMESTAMP_ + _BEACON_ITERVAL_ + _CAPABILITY_);while (cnt < in_len) { +if (cnt +2 > in_len) +break ; +if (cnt +2 + in_ie[cnt +1 ] > in_len) +break ; authmode = in_ie[cnt];if (authmode ==WLAN_EID_BSS_AC_ACCESS_DELAY && + in_ie[cnt +1 ] >=8 && (!memcmp (&in_ie[cnt +6 ], wapi_oui1,4 ) || !memcmp (&in_ie[cnt +6 ], wapi_oui2,4 ))) {if (wapi_ie)
@@ -615,9 +620,14 @@ void rtw_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len, u8 *wpa_ie cnt = (_TIMESTAMP_ + _BEACON_ITERVAL_ + _CAPABILITY_);while (cnt < in_len) { +if (cnt +2 > in_len) +break ; +if (cnt +2 + in_ie[cnt +1 ] > in_len) +break ; authmode = in_ie[cnt];if ((authmode ==WLAN_EID_VENDOR_SPECIFIC ) && + in_ie[cnt +1 ] >=4 && (!memcmp (&in_ie[cnt +2 ], &wpa_oui[0 ],4 ))) {if (wpa_ie)memcpy (wpa_ie, &in_ie[cnt], in_ie[cnt +1 ] +2 );
@@ -698,6 +708,9 @@ u8 *rtw_get_wps_attr(u8 *wps_ie, uint wps_ielen, u16 target_attr_id, u8 *buf_attif (len_attr) *len_attr =0 ; +if (wps_ielen <6 ) +return attr_ptr; +if ((wps_ie[0 ] !=WLAN_EID_VENDOR_SPECIFIC ) || (memcmp (wps_ie +2 , wps_oui,4 ))) {return attr_ptr;
@@ -708,6 +721,8 @@ u8 *rtw_get_wps_attr(u8 *wps_ie, uint wps_ielen, u16 target_attr_id, u8 *buf_attwhile (attr_ptr - wps_ie < wps_ielen) {/* 4 = 2(Attribute ID) + 2(Length) */ +if (attr_ptr +4 > wps_ie + wps_ielen) +break ;u16 attr_id =get_unaligned_be16 (attr_ptr);u16 attr_data_len =get_unaligned_be16 (attr_ptr +2 );u16 attr_len = attr_data_len +4 ;
Sasha Levin
maintainerPATCH 1/5 staging: rtl8723bs: Remove redundant else branches.
From: Sevinj Aghayeva <[email protected]>
[ Upstream commit 4610e57a7d2edeef14aa852cd945f9920e1759da ]
This patch fixes the following checkpatch.pl warning:
WARNING: else is not generally useful after a break or return
Stable-dep-of: 1463ca3ec660 ("staging: rtl8723bs: fix OOB reads in rtw_get_sec_ie(), rtw_get_wapi_ie(), and rtw_get_wps_attr()")
--- .../staging/rtl8723bs/core/rtw_ieee80211.c | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-)
drivers/staging/rtl8723bs/core/rtw_ieee80211.c +11 -16
@@ -94,16 +94,14 @@ bool rtw_is_cckratesonly_included(u8 *rate)int rtw_check_network_type (unsigned char *rate,int ratelen,int channel) { -if (channel >14 ) { +if (channel >14 )return WIRELESS_INVALID ; - }else {/* could be pure B, pure G, or B/G */ -if (rtw_is_cckratesonly_included (rate)) -return WIRELESS_11B ; -else if (rtw_is_cckrates_included (rate)) -return WIRELESS_11BG ; -else -return WIRELESS_11G ; - } +/* could be pure B, pure G, or B/G */ +if (rtw_is_cckratesonly_included (rate)) +return WIRELESS_11B ; +if (rtw_is_cckrates_included (rate)) +return WIRELESS_11BG ; +return WIRELESS_11G ; } u8 *rtw_set_fixed_ie(unsigned char *pbuf, unsigned int len, unsigned char *source,
@@ -155,10 +153,9 @@ u8 *rtw_get_ie(u8 *pbuf, signed int index, signed int *len, signed int limit)if (*p == index) { *len = tmp;return p; - }else { - p += (tmp +2 ); - i += (tmp +2 ); } + p += (tmp +2 ); + i += (tmp +2 ); }return NULL ; }
@@ -702,9 +699,8 @@ u8 *rtw_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen) cnt += in_ie[cnt+1 ]+2 ;break ; - }else { - cnt += in_ie[cnt+1 ]+2 ;/* goto next */ } + cnt += in_ie[cnt+1 ]+2 ;/* goto next */ }return wpsie_ptr;
@@ -753,9 +749,8 @@ u8 *rtw_get_wps_attr(u8 *wps_ie, uint wps_ielen, u16 target_attr_id, u8 *buf_att *len_attr = attr_len;break ; - }else { - attr_ptr += attr_len;/* goto next */ } + attr_ptr += attr_len;/* goto next */ }return target_attr_ptr;
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/5 staging: rtl8723bs: remove redundant braces in if statements
From: Sevinj Aghayeva <[email protected]>
[ Upstream commit 94579b02720bb63096312c4bc7694fd2f6df7cbb ]
Adhere to Linux kernel coding style.
Reported by checkpatch:
WARNING: braces {} are not necessary for single statement blocks
Stable-dep-of: 1463ca3ec660 ("staging: rtl8723bs: fix OOB reads in rtw_get_sec_ie(), rtw_get_wapi_ie(), and rtw_get_wps_attr()")
--- drivers/staging/rtl8723bs/core/rtw_ieee80211.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)
drivers/staging/rtl8723bs/core/rtw_ieee80211.c +4 -8
@@ -341,9 +341,8 @@ int rtw_generate_ie(struct registry_priv *pregistrypriv) ie =rtw_set_ie (ie,WLAN_EID_IBSS_PARAMS ,2 , (u8 *)&(pdev_network->configuration.atim_window), &sz); -if (rateLen >8 ) { +if (rateLen >8 ) ie =rtw_set_ie (ie,WLAN_EID_EXT_SUPP_RATES , (rateLen -8 ), (pdev_network->supported_rates +8 ), &sz); - }/* HT Cap. */ if ((pregistrypriv->wireless_mode & WIRELESS_11_24N) &&
@@ -372,9 +371,8 @@ unsigned char *rtw_get_wpa_ie(unsigned char *pie, int *wpa_ie_len, int limit)if (pbuf) {/* check if oui matches... */ -if (memcmp ((pbuf +2 ), wpa_oui_type,sizeof (wpa_oui_type))) { +if (memcmp ((pbuf +2 ), wpa_oui_type,sizeof (wpa_oui_type))) goto check_next_ie; - }/* check version... */ memcpy ((u8 *)&le_tmp, (pbuf +6 ),sizeof (val16));
@@ -499,9 +497,8 @@ int rtw_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwisif (is_8021x) {if (left >=6 ) { pos +=2 ; -if (!memcmp (pos,SUITE_1X ,4 )) { +if (!memcmp (pos,SUITE_1X ,4 )) *is_8021x =1 ; - } } }
@@ -520,9 +517,8 @@ int rtw_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher, int *pairwireturn _FAIL; } -if ((*rsn_ie !=WLAN_EID_RSN ) || (*(rsn_ie+1 ) != (u8)(rsn_ie_len -2 ))) { +if ((*rsn_ie !=WLAN_EID_RSN ) || (*(rsn_ie+1 ) != (u8)(rsn_ie_len -2 )))return _FAIL; - } pos = rsn_ie; pos +=4 ;
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 3/5 staging: rtl8723bs: core: move constants to right side in comparison
In reply to Sasha LevinFrom: William Hansen-Baird <[email protected]>
[ Upstream commit cf0f2680c30d4b438a5e84b73dc70be405936b54 ]
Move constants to right side in if-statement conditions.
Stable-dep-of: 1463ca3ec660 ("staging: rtl8723bs: fix OOB reads in rtw_get_sec_ie(), rtw_get_wapi_ie(), and rtw_get_wps_attr()")
--- drivers/staging/rtl8723bs/core/rtw_ieee80211.c | 4 ++-- drivers/staging/rtl8723bs/core/rtw_security.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
drivers/staging/rtl8723bs/core/rtw_ieee80211.c +2 -2
@@ -1028,7 +1028,7 @@ static int rtw_get_cipher_info(struct wlan_network *pnetwork) pbuf =rtw_get_wpa_ie (&pnetwork->network.ies[12 ], &wpa_ielen, pnetwork->network.ie_length-12 );if (pbuf && (wpa_ielen >0 )) { -if (_SUCCESS ==rtw_parse_wpa_ie (pbuf, wpa_ielen+2 , &group_cipher, &pairwise_cipher, &is8021x)) { +if (rtw_parse_wpa_ie (pbuf, wpa_ielen+2 , &group_cipher, &pairwise_cipher, &is8021x) == _SUCCESS) { pnetwork->bcn_info.pairwise_cipher = pairwise_cipher; pnetwork->bcn_info.group_cipher = group_cipher; pnetwork->bcn_info.is_8021x = is8021x;
@@ -1038,7 +1038,7 @@ static int rtw_get_cipher_info(struct wlan_network *pnetwork) pbuf =rtw_get_wpa2_ie (&pnetwork->network.ies[12 ], &wpa_ielen, pnetwork->network.ie_length-12 );if (pbuf && (wpa_ielen >0 )) { -if (_SUCCESS ==rtw_parse_wpa2_ie (pbuf, wpa_ielen+2 , &group_cipher, &pairwise_cipher, &is8021x)) { +if (rtw_parse_wpa2_ie (pbuf, wpa_ielen+2 , &group_cipher, &pairwise_cipher, &is8021x) == _SUCCESS) { pnetwork->bcn_info.pairwise_cipher = pairwise_cipher; pnetwork->bcn_info.group_cipher = group_cipher; pnetwork->bcn_info.is_8021x = is8021x;
drivers/staging/rtl8723bs/core/rtw_security.c +1 -1
@@ -1538,7 +1538,7 @@ void rtw_sec_restore_wep_key(struct adapter *adapter)struct security_priv *securitypriv = &(adapter->securitypriv);signed int keyid; -if ((_WEP40_ == securitypriv->dot11PrivacyAlgrthm) || (_WEP104_ == securitypriv->dot11PrivacyAlgrthm)) { +if ((securitypriv->dot11PrivacyAlgrthm == _WEP40_) || (securitypriv->dot11PrivacyAlgrthm == _WEP104_)) {for (keyid =0 ; keyid <4 ; keyid++) {if (securitypriv->key_mask &BIT (keyid)) {if (keyid == securitypriv->dot11PrivacyKeyIndex)
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 4/5 staging: rtl8723bs: fix spaces around binary operators
In reply to Sasha LevinFrom: Nikolay Kulikov <[email protected]>
[ Upstream commit 0c9d1b56f9af0762a5be5118e1bb962f23784dc4 ]
Add missing spaces and fix line length to comply with kernel coding style.
Stable-dep-of: 1463ca3ec660 ("staging: rtl8723bs: fix OOB reads in rtw_get_sec_ie(), rtw_get_wapi_ie(), and rtw_get_wps_attr()")
--- .../staging/rtl8723bs/core/rtw_ieee80211.c | 78 ++++++++++--------- 1 file changed, 42 insertions(+), 36 deletions(-)
drivers/staging/rtl8723bs/core/rtw_ieee80211.c +42 -36
@@ -454,10 +454,10 @@ int rtw_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwisreturn _FAIL; } -if ((*wpa_ie !=WLAN_EID_VENDOR_SPECIFIC ) || (*(wpa_ie+1 ) != (u8)(wpa_ie_len -2 )) || - (memcmp (wpa_ie+2 ,RTW_WPA_OUI_TYPE ,WPA_SELECTOR_LEN ))) { +if ((*wpa_ie !=WLAN_EID_VENDOR_SPECIFIC ) || + (*(wpa_ie +1 ) != (u8)(wpa_ie_len -2 )) || + (memcmp (wpa_ie +2 ,RTW_WPA_OUI_TYPE ,WPA_SELECTOR_LEN )))return _FAIL; - } pos = wpa_ie;
@@ -517,7 +517,7 @@ int rtw_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher, int *pairwireturn _FAIL; } -if ((*rsn_ie !=WLAN_EID_RSN ) || (*(rsn_ie+1 ) != (u8)(rsn_ie_len -2 ))) +if ((*rsn_ie !=WLAN_EID_RSN ) || (*(rsn_ie +1 ) != (u8)(rsn_ie_len -2 )))return _FAIL; pos = rsn_ie;
@@ -585,18 +585,18 @@ int rtw_get_wapi_ie(u8 *in_ie, uint in_len, u8 *wapi_ie, u16 *wapi_len)while (cnt < in_len) { authmode = in_ie[cnt]; -/* if (authmode == WLAN_EID_BSS_AC_ACCESS_DELAY) */ -if (authmode ==WLAN_EID_BSS_AC_ACCESS_DELAY && (!memcmp (&in_ie[cnt+6 ], wapi_oui1,4 ) || - !memcmp (&in_ie[cnt+6 ], wapi_oui2,4 ))) { +if (authmode ==WLAN_EID_BSS_AC_ACCESS_DELAY && + (!memcmp (&in_ie[cnt +6 ], wapi_oui1,4 ) || + !memcmp (&in_ie[cnt +6 ], wapi_oui2,4 ))) {if (wapi_ie) -memcpy (wapi_ie, &in_ie[cnt], in_ie[cnt+1 ]+2 ); +memcpy (wapi_ie, &in_ie[cnt], in_ie[cnt +1 ] +2 );if (wapi_len) - *wapi_len = in_ie[cnt+1 ]+2 ; + *wapi_len = in_ie[cnt +1 ] +2 ; - cnt += in_ie[cnt+1 ]+2 ;/* get next */ + cnt += in_ie[cnt +1 ] +2 ;/* get next */ }else { - cnt += in_ie[cnt+1 ]+2 ;/* get next */ + cnt += in_ie[cnt +1 ] +2 ;/* get next */ } }
@@ -620,9 +620,10 @@ void rtw_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len, u8 *wpa_iewhile (cnt < in_len) { authmode = in_ie[cnt]; -if ((authmode ==WLAN_EID_VENDOR_SPECIFIC ) && (!memcmp (&in_ie[cnt+2 ], &wpa_oui[0 ],4 ))) { +if ((authmode ==WLAN_EID_VENDOR_SPECIFIC ) && + (!memcmp (&in_ie[cnt +2 ], &wpa_oui[0 ],4 ))) {if (wpa_ie) -memcpy (wpa_ie, &in_ie[cnt], in_ie[cnt+1 ]+2 ); +memcpy (wpa_ie, &in_ie[cnt], in_ie[cnt +1 ] +2 ); *wpa_len = in_ie[cnt +1 ] +2 ; cnt += in_ie[cnt +1 ] +2 ;/* get next */
@@ -631,10 +632,10 @@ void rtw_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len, u8 *wpa_ieif (rsn_ie)memcpy (rsn_ie, &in_ie[cnt], in_ie[cnt +1 ] +2 ); - *rsn_len = in_ie[cnt+1 ]+2 ; - cnt += in_ie[cnt+1 ]+2 ;/* get next */ + *rsn_len = in_ie[cnt +1 ] +2 ; + cnt += in_ie[cnt +1 ] +2 ;/* get next */ }else { - cnt += in_ie[cnt+1 ]+2 ;/* get next */ + cnt += in_ie[cnt +1 ] +2 ;/* get next */ } } }
@@ -683,20 +684,20 @@ u8 *rtw_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen)while (cnt < in_len) { eid = in_ie[cnt]; -if ((eid ==WLAN_EID_VENDOR_SPECIFIC ) && (!memcmp (&in_ie[cnt+2 ], wps_oui,4 ))) { +if ((eid ==WLAN_EID_VENDOR_SPECIFIC ) && (!memcmp (&in_ie[cnt +2 ], wps_oui,4 ))) { wpsie_ptr = &in_ie[cnt];if (wps_ie) -memcpy (wps_ie, &in_ie[cnt], in_ie[cnt+1 ]+2 ); +memcpy (wps_ie, &in_ie[cnt], in_ie[cnt +1 ] +2 );if (wps_ielen) - *wps_ielen = in_ie[cnt+1 ]+2 ; + *wps_ielen = in_ie[cnt +1 ] +2 ; - cnt += in_ie[cnt+1 ]+2 ; + cnt += in_ie[cnt +1 ] +2 ;break ; } - cnt += in_ie[cnt+1 ]+2 ;/* goto next */ + cnt += in_ie[cnt +1 ] +2 ;/* goto next */ }return wpsie_ptr;
@@ -774,12 +775,12 @@ u8 *rtw_get_wps_attr_content(u8 *wps_ie, uint wps_ielen, u16 target_attr_id, u8if (attr_ptr && attr_len) {if (buf_content) -memcpy (buf_content, attr_ptr+4 , attr_len-4 ); +memcpy (buf_content, attr_ptr +4 , attr_len -4 );if (len_content) - *len_content = attr_len-4 ; + *len_content = attr_len -4 ; -return attr_ptr+4 ; +return attr_ptr +4 ; }return NULL ;
@@ -1025,20 +1026,25 @@ static int rtw_get_cipher_info(struct wlan_network *pnetwork)int group_cipher =0 , pairwise_cipher =0 , is8021x =0 ;int ret = _FAIL; - pbuf =rtw_get_wpa_ie (&pnetwork->network.ies[12 ], &wpa_ielen, pnetwork->network.ie_length-12 ); + pbuf =rtw_get_wpa_ie (&pnetwork->network.ies[12 ], + &wpa_ielen, + pnetwork->network.ie_length -12 );if (pbuf && (wpa_ielen >0 )) { -if (rtw_parse_wpa_ie (pbuf, wpa_ielen+2 , &group_cipher, &pairwise_cipher, &is8021x) == _SUCCESS) { +if (rtw_parse_wpa_ie (pbuf, wpa_ielen +2 , &group_cipher, + &pairwise_cipher, &is8021x) == _SUCCESS) { pnetwork->bcn_info.pairwise_cipher = pairwise_cipher; pnetwork->bcn_info.group_cipher = group_cipher; pnetwork->bcn_info.is_8021x = is8021x; ret = _SUCCESS; } }else { - pbuf =rtw_get_wpa2_ie (&pnetwork->network.ies[12 ], &wpa_ielen, pnetwork->network.ie_length-12 ); + pbuf =rtw_get_wpa2_ie (&pnetwork->network.ies[12 ], &wpa_ielen, + pnetwork->network.ie_length -12 );if (pbuf && (wpa_ielen >0 )) { -if (rtw_parse_wpa2_ie (pbuf, wpa_ielen+2 , &group_cipher, &pairwise_cipher, &is8021x) == _SUCCESS) { +if (rtw_parse_wpa2_ie (pbuf, wpa_ielen +2 , &group_cipher, + &pairwise_cipher, &is8021x) == _SUCCESS) { pnetwork->bcn_info.pairwise_cipher = pairwise_cipher; pnetwork->bcn_info.group_cipher = group_cipher; pnetwork->bcn_info.is_8021x = is8021x;
@@ -1107,21 +1113,21 @@ u16 rtw_mcs_rate(u8 bw_40MHz, u8 short_GI, unsigned char *MCS_rate)u16 max_rate =0 ;if (MCS_rate[0 ] &BIT (7 )) - max_rate = (bw_40MHz) ? ((short_GI)?1500 :1350 ):((short_GI)?722 :650 ); + max_rate = (bw_40MHz) ? ((short_GI) ?1500 :1350 ) : ((short_GI) ?722 :650 );else if (MCS_rate[0 ] &BIT (6 )) - max_rate = (bw_40MHz) ? ((short_GI)?1350 :1215 ):((short_GI)?650 :585 ); + max_rate = (bw_40MHz) ? ((short_GI) ?1350 :1215 ) : ((short_GI) ?650 :585 );else if (MCS_rate[0 ] &BIT (5 )) - max_rate = (bw_40MHz) ? ((short_GI)?1200 :1080 ):((short_GI)?578 :520 ); + max_rate = (bw_40MHz) ? ((short_GI) ?1200 :1080 ) : ((short_GI) ?578 :520 );else if (MCS_rate[0 ] &BIT (4 )) - max_rate = (bw_40MHz) ? ((short_GI)?900 :810 ):((short_GI)?433 :390 ); + max_rate = (bw_40MHz) ? ((short_GI) ?900 :810 ) : ((short_GI) ?433 :390 );else if (MCS_rate[0 ] &BIT (3 )) - max_rate = (bw_40MHz) ? ((short_GI)?600 :540 ):((short_GI)?289 :260 ); + max_rate = (bw_40MHz) ? ((short_GI) ?600 :540 ) : ((short_GI) ?289 :260 );else if (MCS_rate[0 ] &BIT (2 )) - max_rate = (bw_40MHz) ? ((short_GI)?450 :405 ):((short_GI)?217 :195 ); + max_rate = (bw_40MHz) ? ((short_GI) ?450 :405 ) : ((short_GI) ?217 :195 );else if (MCS_rate[0 ] &BIT (1 )) - max_rate = (bw_40MHz) ? ((short_GI)?300 :270 ):((short_GI)?144 :130 ); + max_rate = (bw_40MHz) ? ((short_GI) ?300 :270 ) : ((short_GI) ?144 :130 );else if (MCS_rate[0 ] &BIT (0 )) - max_rate = (bw_40MHz) ? ((short_GI)?150 :135 ):((short_GI)?72 :65 ); + max_rate = (bw_40MHz) ? ((short_GI) ?150 :135 ) : ((short_GI) ?72 :65 );return max_rate; }
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 5/5 staging: rtl8723bs: fix OOB reads in rtw_get_sec_ie(), rtw_get_wapi_ie(), and rtw_get_wps_attr()
In reply to Sasha LevinFrom: Alexandru Hossu <[email protected]>
[ Upstream commit 1463ca3ec6601cbb097d8d87dbf5dcf1cb86a344 ]
Three IE/attribute parsing functions have missing bounds checks.
rtw_get_sec_ie() and rtw_get_wapi_ie() iterate over a raw IE buffer without verifying that the header bytes (tag + length) are within the remaining buffer before reading them. Additionally, rtw_get_sec_ie() compares the 4-byte WPA OUI at cnt+2 without checking that at least 6 bytes remain, and rtw_get_wapi_ie() compares a 4-byte WAPI OUI at cnt+6 without checking that at least 10 bytes remain.
rtw_get_wps_attr() reads wps_ie[0] and wps_ie+2 unconditionally at entry, before verifying that wps_ielen is large enough to contain the 6-byte WPS IE header (element_id + length + 4-byte OUI). Inside the attribute loop, get_unaligned_be16() is called on attr_ptr and attr_ptr+2 without checking that 4 bytes remain in the buffer.
Add a cnt+2 bounds check before each loop body in rtw_get_sec_ie() and rtw_get_wapi_ie(), guard each multi-byte comparison with a minimum IE length requirement, add a wps_ielen < 6 early return in rtw_get_wps_attr(), and add a 4-byte bounds check in its inner loop.
--- drivers/staging/rtl8723bs/core/rtw_ieee80211.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
drivers/staging/rtl8723bs/core/rtw_ieee80211.c +15 -0
@@ -583,9 +583,14 @@ int rtw_get_wapi_ie(u8 *in_ie, uint in_len, u8 *wapi_ie, u16 *wapi_len) cnt = (_TIMESTAMP_ + _BEACON_ITERVAL_ + _CAPABILITY_);while (cnt < in_len) { +if (cnt +2 > in_len) +break ; +if (cnt +2 + in_ie[cnt +1 ] > in_len) +break ; authmode = in_ie[cnt];if (authmode ==WLAN_EID_BSS_AC_ACCESS_DELAY && + in_ie[cnt +1 ] >=8 && (!memcmp (&in_ie[cnt +6 ], wapi_oui1,4 ) || !memcmp (&in_ie[cnt +6 ], wapi_oui2,4 ))) {if (wapi_ie)
@@ -618,9 +623,14 @@ void rtw_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len, u8 *wpa_ie cnt = (_TIMESTAMP_ + _BEACON_ITERVAL_ + _CAPABILITY_);while (cnt < in_len) { +if (cnt +2 > in_len) +break ; +if (cnt +2 + in_ie[cnt +1 ] > in_len) +break ; authmode = in_ie[cnt];if ((authmode ==WLAN_EID_VENDOR_SPECIFIC ) && + in_ie[cnt +1 ] >=4 && (!memcmp (&in_ie[cnt +2 ], &wpa_oui[0 ],4 ))) {if (wpa_ie)memcpy (wpa_ie, &in_ie[cnt], in_ie[cnt +1 ] +2 );
@@ -722,6 +732,9 @@ u8 *rtw_get_wps_attr(u8 *wps_ie, uint wps_ielen, u16 target_attr_id, u8 *buf_attif (len_attr) *len_attr =0 ; +if (wps_ielen <6 ) +return attr_ptr; +if ((wps_ie[0 ] !=WLAN_EID_VENDOR_SPECIFIC ) || (memcmp (wps_ie +2 , wps_oui,4 ))) {return attr_ptr;
@@ -732,6 +745,8 @@ u8 *rtw_get_wps_attr(u8 *wps_ie, uint wps_ielen, u16 target_attr_id, u8 *buf_attwhile (attr_ptr - wps_ie < wps_ielen) {/* 4 = 2(Attribute ID) + 2(Length) */ +if (attr_ptr +4 > wps_ie + wps_ielen) +break ;u16 attr_id =get_unaligned_be16 (attr_ptr);u16 attr_data_len =get_unaligned_be16 (attr_ptr +2 );u16 attr_len = attr_data_len +4 ;
Signature · 1 line
2.53.0