Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f5d197b6 authored by Jes Sorensen's avatar Jes Sorensen Committed by Greg Kroah-Hartman
Browse files

staging: rtl8723au: Fix buffer overflow in rtw_get_wfd_ie()



Add bounds checking to not allow WFD Information Elements larger than
128, and make sure we use the correct buffer size MAX_WFD_IE_LEN
instea of hardcoding the size.

This also simplifies rtw_get_wfd_ie() by using the cfg80211
infrastructure.

Reported-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: default avatarJes Sorensen <Jes.Sorensen@redhat.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 14e6e35d
Loading
Loading
Loading
Loading
+12 −34
Original line number Diff line number Diff line
@@ -1496,45 +1496,23 @@ void rtw_wlan_bssid_ex_remove_p2p_attr23a(struct wlan_bssid_ex *bss_ex, u8 attr_
int rtw_get_wfd_ie(u8 *in_ie, int in_len, u8 *wfd_ie, uint *wfd_ielen)
{
	int match;
	uint cnt = 0;
	u8 eid, wfd_oui[4] = {0x50, 0x6F, 0x9A, 0x0A};
	const u8 *ie;

	match = false;
	match = 0;

	if (in_len < 0) {
	if (in_len < 0)
		return match;
	}

	while (cnt < in_len)
	{
		eid = in_ie[cnt];

		if ((eid == _VENDOR_SPECIFIC_IE_) &&
		    !memcmp(&in_ie[cnt+2], wfd_oui, 4)) {
			if (wfd_ie != NULL) {
				memcpy(wfd_ie, &in_ie[cnt], in_ie[cnt + 1] + 2);

			} else {
				if (wfd_ielen != NULL) {
	ie = cfg80211_find_vendor_ie(0x506F9A, 0x0A, in_ie, in_len);
	if (ie && (ie[1] <= (MAX_WFD_IE_LEN - 2))) {
		if (wfd_ie) {
			*wfd_ielen = ie[1] + 2;
			memcpy(wfd_ie, ie, ie[1] + 2);
		} else
			if (wfd_ielen)
				*wfd_ielen = 0;
				}
			}

			if (wfd_ielen != NULL) {
				*wfd_ielen = in_ie[cnt + 1] + 2;
			}

			cnt += in_ie[cnt + 1] + 2;

			match = true;
			break;
		} else {
			cnt += in_ie[cnt + 1] +2; /* goto next */
		}
	}

	if (match == true) {
		match = cnt;
		match = 1;
	}

	return match;
+1 −1
Original line number Diff line number Diff line
@@ -1281,7 +1281,7 @@ unsigned int OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *prec
	u8 p2p_status_code = P2P_STATUS_SUCCESS;
	u8 *p2pie;
	u32 p2pielen = 0;
	u8	wfd_ie[ 128 ] = { 0x00 };
	u8	wfd_ie[MAX_WFD_IE_LEN] = { 0x00 };
	u32	wfd_ielen = 0;
#endif /* CONFIG_8723AU_P2P */

+2 −2
Original line number Diff line number Diff line
@@ -2535,7 +2535,7 @@ u8 process_p2p_group_negotation_req23a(struct wifidirect_info *pwdinfo, u8 *pfra
	u16		wps_devicepassword_id = 0x0000;
	uint	wps_devicepassword_id_len = 0;
#ifdef CONFIG_8723AU_P2P
	u8	wfd_ie[ 128 ] = { 0x00 };
	u8	wfd_ie[MAX_WFD_IE_LEN] = { 0x00 };
	u32	wfd_ielen = 0;
#endif /*  CONFIG_8723AU_P2P */

@@ -2741,7 +2741,7 @@ u8 process_p2p_group_negotation_resp23a(struct wifidirect_info *pwdinfo, u8 *pfr
	u32 ies_len;
	u8 * p2p_ie;
#ifdef CONFIG_8723AU_P2P
	u8	wfd_ie[ 128 ] = { 0x00 };
	u8	wfd_ie[MAX_WFD_IE_LEN] = { 0x00 };
	u32	wfd_ielen = 0;
#endif /*  CONFIG_8723AU_P2P */

+1 −1
Original line number Diff line number Diff line
@@ -570,7 +570,7 @@ void flush_all_cam_entry23a(struct rtw_adapter *padapter)
int WFD_info_handler(struct rtw_adapter *padapter, struct ndis_802_11_var_ies *	pIE)
{
	struct wifidirect_info	*pwdinfo;
	u8	wfd_ie[128] = {0x00};
	u8	wfd_ie[MAX_WFD_IE_LEN] = {0x00};
	u32	wfd_ielen = 0;

	pwdinfo = &padapter->wdinfo;