Skip to content

Commit 940d91c

Browse files
committed
Merge tag 'staging-7.2-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging driver fixes from Greg KH: "Here are some staging driver fixes for 7.2-rc3 for some reported bugs in the vme_user and rtl8723bs drivers. These include: - many rtl8723bs OOB fixes for when connecting to "bad" wifi hosts - vme_user bugfixes to correctly validate some user-provided data All of these have been in linux-next for a while with no reported issues" * tag 'staging-7.2-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: staging: rtl8723bs: fix OOB reads in rtw_get_sec_ie(), rtw_get_wapi_ie(), and rtw_get_wps_attr() staging: rtl8723bs: fix OOB reads in is_ap_in_tkip() IE loop staging: rtl8723bs: fix OOB read in OnAssocRsp() IE loop staging: rtl8723bs: fix OOB write in HT_caps_handler() staging: rtl8723bs: fix heap buffer overflow in rtw_cfg80211_set_wpa_ie() staging: rtl8723bs: fix OOB reads in IE loops in issue_assocreq() and join_cmd_hdl() staging: rtl8723bs: fix OOB read in update_beacon_info() IE loop staging: rtl8723bs: fix WEP length underflow and OOB read in OnAuth() staging: vme_user: fix location monitor leak in tsi148 bridge staging: vme_user: fix location monitor leak in fake bridge staging: vme_user: bound slave read/write to the kern_buf size staging: rtl8723bs: don't drop short TX frames in _rtw_pktfile_read()
2 parents bffa972 + 1463ca3 commit 940d91c

8 files changed

Lines changed: 102 additions & 8 deletions

File tree

drivers/staging/rtl8723bs/core/rtw_ieee80211.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,9 +583,14 @@ int rtw_get_wapi_ie(u8 *in_ie, uint in_len, u8 *wapi_ie, u16 *wapi_len)
583583
cnt = (_TIMESTAMP_ + _BEACON_ITERVAL_ + _CAPABILITY_);
584584

585585
while (cnt < in_len) {
586+
if (cnt + 2 > in_len)
587+
break;
588+
if (cnt + 2 + in_ie[cnt + 1] > in_len)
589+
break;
586590
authmode = in_ie[cnt];
587591

588592
if (authmode == WLAN_EID_BSS_AC_ACCESS_DELAY &&
593+
in_ie[cnt + 1] >= 8 &&
589594
(!memcmp(&in_ie[cnt + 6], wapi_oui1, 4) ||
590595
!memcmp(&in_ie[cnt + 6], wapi_oui2, 4))) {
591596
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
615620
cnt = (_TIMESTAMP_ + _BEACON_ITERVAL_ + _CAPABILITY_);
616621

617622
while (cnt < in_len) {
623+
if (cnt + 2 > in_len)
624+
break;
625+
if (cnt + 2 + in_ie[cnt + 1] > in_len)
626+
break;
618627
authmode = in_ie[cnt];
619628

620629
if ((authmode == WLAN_EID_VENDOR_SPECIFIC) &&
630+
in_ie[cnt + 1] >= 4 &&
621631
(!memcmp(&in_ie[cnt + 2], &wpa_oui[0], 4))) {
622632
if (wpa_ie)
623633
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_att
698708
if (len_attr)
699709
*len_attr = 0;
700710

711+
if (wps_ielen < 6)
712+
return attr_ptr;
713+
701714
if ((wps_ie[0] != WLAN_EID_VENDOR_SPECIFIC) ||
702715
(memcmp(wps_ie + 2, wps_oui, 4))) {
703716
return attr_ptr;
@@ -708,6 +721,8 @@ u8 *rtw_get_wps_attr(u8 *wps_ie, uint wps_ielen, u16 target_attr_id, u8 *buf_att
708721

709722
while (attr_ptr - wps_ie < wps_ielen) {
710723
/* 4 = 2(Attribute ID) + 2(Length) */
724+
if (attr_ptr + 4 > wps_ie + wps_ielen)
725+
break;
711726
u16 attr_id = get_unaligned_be16(attr_ptr);
712727
u16 attr_data_len = get_unaligned_be16(attr_ptr + 2);
713728
u16 attr_len = attr_data_len + 4;

drivers/staging/rtl8723bs/core/rtw_mlme_ext.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,9 @@ unsigned int OnAuth(struct adapter *padapter, union recv_frame *precv_frame)
677677
if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
678678
return _FAIL;
679679

680+
if (len < WLAN_HDR_A3_LEN)
681+
return _FAIL;
682+
680683
sa = GetAddr2Ptr(pframe);
681684

682685
auth_mode = psecuritypriv->dot11AuthAlgrthm;
@@ -688,6 +691,9 @@ unsigned int OnAuth(struct adapter *padapter, union recv_frame *precv_frame)
688691
prxattrib->hdrlen = WLAN_HDR_A3_LEN;
689692
prxattrib->encrypt = _WEP40_;
690693

694+
if (len < WLAN_HDR_A3_LEN + 8)
695+
return _FAIL;
696+
691697
iv = pframe+prxattrib->hdrlen;
692698
prxattrib->key_index = ((iv[3]>>6)&0x3);
693699

@@ -787,7 +793,7 @@ unsigned int OnAuth(struct adapter *padapter, union recv_frame *precv_frame)
787793
p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_, WLAN_EID_CHALLENGE, (int *)&ie_len,
788794
len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
789795

790-
if (!p || ie_len <= 0) {
796+
if (!p || ie_len != 128) {
791797
status = WLAN_STATUS_CHALLENGE_FAIL;
792798
goto auth_fail;
793799
}
@@ -1365,7 +1371,11 @@ unsigned int OnAssocRsp(struct adapter *padapter, union recv_frame *precv_frame)
13651371
/* to handle HT, WMM, rate adaptive, update MAC reg */
13661372
/* for not to handle the synchronous IO in the tasklet */
13671373
for (i = (6 + WLAN_HDR_A3_LEN); i < pkt_len;) {
1374+
if (i + sizeof(*pIE) > pkt_len)
1375+
break;
13681376
pIE = (struct ndis_80211_var_ie *)(pframe + i);
1377+
if (i + sizeof(*pIE) + pIE->length > pkt_len)
1378+
break;
13691379

13701380
switch (pIE->element_id) {
13711381
case WLAN_EID_VENDOR_SPECIFIC:
@@ -2855,7 +2865,11 @@ void issue_assocreq(struct adapter *padapter)
28552865

28562866
/* vendor specific IE, such as WPA, WMM, WPS */
28572867
for (i = sizeof(struct ndis_802_11_fix_ie); i < pmlmeinfo->network.ie_length;) {
2868+
if (i + sizeof(*pIE) > pmlmeinfo->network.ie_length)
2869+
break;
28582870
pIE = (struct ndis_80211_var_ie *)(pmlmeinfo->network.ies + i);
2871+
if (i + sizeof(*pIE) + pIE->length > pmlmeinfo->network.ie_length)
2872+
break;
28592873

28602874
switch (pIE->element_id) {
28612875
case WLAN_EID_VENDOR_SPECIFIC:
@@ -5183,7 +5197,11 @@ u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf)
51835197

51845198
/* sizeof(struct ndis_802_11_fix_ie) */
51855199
for (i = _FIXED_IE_LENGTH_; i < pnetwork->ie_length;) {
5200+
if (i + sizeof(*pIE) > pnetwork->ie_length)
5201+
break;
51865202
pIE = (struct ndis_80211_var_ie *)(pnetwork->ies + i);
5203+
if (i + sizeof(*pIE) + pIE->length > pnetwork->ie_length)
5204+
break;
51875205

51885206
switch (pIE->element_id) {
51895207
case WLAN_EID_VENDOR_SPECIFIC:/* Get WMM IE. */

drivers/staging/rtl8723bs/core/rtw_wlan_util.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -909,7 +909,8 @@ void HT_caps_handler(struct adapter *padapter, struct ndis_80211_var_ie *pIE)
909909

910910
pmlmeinfo->HT_caps_enable = 1;
911911

912-
for (i = 0; i < (pIE->length); i++) {
912+
for (i = 0; i < umin(pIE->length,
913+
sizeof(pmlmeinfo->HT_caps.u.HT_cap)); i++) {
913914
if (i != 2) {
914915
/* Commented by Albert 2010/07/12 */
915916
/* Got the endian issue here. */
@@ -1262,7 +1263,11 @@ void update_beacon_info(struct adapter *padapter, u8 *pframe, uint pkt_len, stru
12621263
len = pkt_len - (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN);
12631264

12641265
for (i = 0; i < len;) {
1266+
if (i + sizeof(*pIE) > len)
1267+
break;
12651268
pIE = (struct ndis_80211_var_ie *)(pframe + (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN) + i);
1269+
if (i + sizeof(*pIE) + pIE->length > len)
1270+
break;
12661271

12671272
switch (pIE->element_id) {
12681273
case WLAN_EID_VENDOR_SPECIFIC:
@@ -1287,7 +1292,7 @@ void update_beacon_info(struct adapter *padapter, u8 *pframe, uint pkt_len, stru
12871292
break;
12881293
}
12891294

1290-
i += (pIE->length + 2);
1295+
i += sizeof(*pIE) + pIE->length;
12911296
}
12921297
}
12931298

@@ -1303,23 +1308,31 @@ unsigned int is_ap_in_tkip(struct adapter *padapter)
13031308
for (i = sizeof(struct ndis_802_11_fix_ie); i < pmlmeinfo->network.ie_length;) {
13041309
pIE = (struct ndis_80211_var_ie *)(pmlmeinfo->network.ies + i);
13051310

1311+
if (i + sizeof(*pIE) > pmlmeinfo->network.ie_length)
1312+
break;
1313+
if (i + sizeof(*pIE) + pIE->length > pmlmeinfo->network.ie_length)
1314+
break;
1315+
13061316
switch (pIE->element_id) {
13071317
case WLAN_EID_VENDOR_SPECIFIC:
1308-
if ((!memcmp(pIE->data, RTW_WPA_OUI, 4)) && (!memcmp((pIE->data + 12), WPA_TKIP_CIPHER, 4)))
1318+
if (pIE->length >= 16 &&
1319+
!memcmp(pIE->data, RTW_WPA_OUI, 4) &&
1320+
!memcmp((pIE->data + 12), WPA_TKIP_CIPHER, 4))
13091321
return true;
13101322

13111323
break;
13121324

13131325
case WLAN_EID_RSN:
1314-
if (!memcmp((pIE->data + 8), RSN_TKIP_CIPHER, 4))
1326+
if (pIE->length >= 12 &&
1327+
!memcmp((pIE->data + 8), RSN_TKIP_CIPHER, 4))
13151328
return true;
13161329
break;
13171330

13181331
default:
13191332
break;
13201333
}
13211334

1322-
i += (pIE->length + 2);
1335+
i += sizeof(*pIE) + pIE->length;
13231336
}
13241337

13251338
return false;

drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,6 +1446,10 @@ static int rtw_cfg80211_set_wpa_ie(struct adapter *padapter, u8 *pie, size_t iel
14461446

14471447
pwpa = rtw_get_wpa_ie(buf, &wpa_ielen, ielen);
14481448
if (pwpa && wpa_ielen > 0) {
1449+
if (wpa_ielen + 2 > sizeof(padapter->securitypriv.supplicant_ie)) {
1450+
ret = -EINVAL;
1451+
goto exit;
1452+
}
14491453
if (rtw_parse_wpa_ie(pwpa, wpa_ielen + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
14501454
padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
14511455
padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK;
@@ -1455,6 +1459,10 @@ static int rtw_cfg80211_set_wpa_ie(struct adapter *padapter, u8 *pie, size_t iel
14551459

14561460
pwpa2 = rtw_get_wpa2_ie(buf, &wpa2_ielen, ielen);
14571461
if (pwpa2 && wpa2_ielen > 0) {
1462+
if (wpa2_ielen + 2 > sizeof(padapter->securitypriv.supplicant_ie)) {
1463+
ret = -EINVAL;
1464+
goto exit;
1465+
}
14581466
if (rtw_parse_wpa2_ie(pwpa2, wpa2_ielen + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
14591467
padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
14601468
padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK;

drivers/staging/rtl8723bs/os_dep/xmit_linux.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@ void _rtw_open_pktfile(struct sk_buff *pktptr, struct pkt_file *pfile)
2424
int _rtw_pktfile_read(struct pkt_file *pfile, u8 *rmem, unsigned int rlen)
2525
{
2626
int ret;
27+
unsigned int remain = rtw_remainder_len(pfile);
2728

28-
if (rtw_remainder_len(pfile) < rlen)
29-
return -EINVAL;
29+
/* clamp to bytes remaining; the coalesce loop relies on short reads */
30+
if (rlen > remain)
31+
rlen = remain;
3032

3133
if (rmem) {
3234
ret = skb_copy_bits(pfile->pkt, pfile->buf_len - pfile->pkt_len, rmem, rlen);

drivers/staging/vme_user/vme_fake.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,6 +1239,7 @@ static void __exit fake_exit(void)
12391239
{
12401240
struct list_head *pos = NULL;
12411241
struct list_head *tmplist;
1242+
struct vme_lm_resource *lm;
12421243
struct vme_master_resource *master_image;
12431244
struct vme_slave_resource *slave_image;
12441245
int i;
@@ -1268,6 +1269,13 @@ static void __exit fake_exit(void)
12681269
vme_unregister_bridge(fake_bridge);
12691270

12701271
fake_crcsr_exit(fake_bridge);
1272+
/* resources are stored in link list */
1273+
list_for_each_safe(pos, tmplist, &fake_bridge->lm_resources) {
1274+
lm = list_entry(pos, struct vme_lm_resource, list);
1275+
list_del(pos);
1276+
kfree(lm);
1277+
}
1278+
12711279
/* resources are stored in link list */
12721280
list_for_each_safe(pos, tmplist, &fake_bridge->slave_resources) {
12731281
slave_image = list_entry(pos, struct vme_slave_resource, list);

drivers/staging/vme_user/vme_tsi148.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2534,6 +2534,7 @@ static void tsi148_remove(struct pci_dev *pdev)
25342534
{
25352535
struct list_head *pos = NULL;
25362536
struct list_head *tmplist;
2537+
struct vme_lm_resource *lm;
25372538
struct vme_master_resource *master_image;
25382539
struct vme_slave_resource *slave_image;
25392540
struct vme_dma_resource *dma_ctrlr;
@@ -2590,6 +2591,13 @@ static void tsi148_remove(struct pci_dev *pdev)
25902591

25912592
tsi148_crcsr_exit(tsi148_bridge, pdev);
25922593

2594+
/* resources are stored in link list */
2595+
list_for_each_safe(pos, tmplist, &tsi148_bridge->lm_resources) {
2596+
lm = list_entry(pos, struct vme_lm_resource, list);
2597+
list_del(pos);
2598+
kfree(lm);
2599+
}
2600+
25932601
/* resources are stored in link list */
25942602
list_for_each_safe(pos, tmplist, &tsi148_bridge->dma_resources) {
25952603
dma_ctrlr = list_entry(pos, struct vme_dma_resource, list);

drivers/staging/vme_user/vme_user.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,17 @@ static ssize_t buffer_to_user(unsigned int minor, char __user *buf,
156156
{
157157
void *image_ptr;
158158

159+
/*
160+
* The slave window (image_size) can exceed the fixed kern_buf
161+
* (size_buf == PCI_BUF_SIZE), so bound the copy to kern_buf.
162+
* *ppos is >= 0 here (checked by the caller), so the
163+
* subtraction below cannot wrap.
164+
*/
165+
if (*ppos >= image[minor].size_buf)
166+
return 0;
167+
if (count > image[minor].size_buf - *ppos)
168+
count = image[minor].size_buf - *ppos;
169+
159170
image_ptr = image[minor].kern_buf + *ppos;
160171
if (copy_to_user(buf, image_ptr, (unsigned long)count))
161172
return -EFAULT;
@@ -168,6 +179,17 @@ static ssize_t buffer_from_user(unsigned int minor, const char __user *buf,
168179
{
169180
void *image_ptr;
170181

182+
/*
183+
* The slave window (image_size) can exceed the fixed kern_buf
184+
* (size_buf == PCI_BUF_SIZE), so bound the copy to kern_buf.
185+
* *ppos is >= 0 here (checked by the caller), so the
186+
* subtraction below cannot wrap.
187+
*/
188+
if (*ppos >= image[minor].size_buf)
189+
return 0;
190+
if (count > image[minor].size_buf - *ppos)
191+
count = image[minor].size_buf - *ppos;
192+
171193
image_ptr = image[minor].kern_buf + *ppos;
172194
if (copy_from_user(image_ptr, buf, (unsigned long)count))
173195
return -EFAULT;

0 commit comments

Comments
 (0)