Cumulative patch from commit 6590b6400f73762fc6a53ad6ca05a73246cc5e54

6590b64 EAP-TNC: Limit maximum message buffer to 75000 bytes (CID 62873)
49d13df P2P: Fix wfd_dev_info parsing for P2P-DEVICE-FOUND (CID 68127)
1851e17 dbus: Clean up P2P group vendor ext getter
137ff33 HS 2.0R2: Fix OSEN IE parsing for in cipher setup (CID 68132)
2703fb4 WNM: Use cleaner way of generating pointer to a field (CID 68100)
da995b2 WNM: Use cleaner way of generating pointer to a field (CID 68099)
062833c GAS server: Fix request frame length validation (CID 68098)
5ce3ae4 HT: Use cleaner way of generating pointer to a field (CID 68097)
fb5d417 P2P: Use cleaner way of generating pointer to a field (CID 68096)
35c0318 P2P: Use cleaner way of generating pointer to a field (CID 68095)
e987c70 dbus: Add explicit break statements to switch-default
6446420 dbus: Initialize temporary entry properly (CID 62877)
70d9537 Use clearer way of getting pointer to a frame (CID 62835)
c02f35f WPS: Clean up indentation level (CID 68109)
0e87e79 Fix HS20_GET_NAI_HOME_REALM_LIST hex length check (CID 68108)
beb9e11 dbus: Avoid theoretical memory leaks with duplicated dict entries
ceb4cd8 dbus: Fix a potential double-free in on error path (CID 62880)
68e2b88 TNC: Fix minor memory leak (CID 62848)
5519241 GAS: Limit TX wait time based on driver maximum value
a0ab408 P2P: Fix SD and DevDisc to limit maximum wait time per driver support

Change-Id: If9bdd7b9961c775e39ce1a8fb58220052434b395
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/ap/gas_serv.c b/src/ap/gas_serv.c
index 52d1b24..ad07107 100644
--- a/src/ap/gas_serv.c
+++ b/src/ap/gas_serv.c
@@ -1213,13 +1213,11 @@
 {
 	struct hostapd_data *hapd = ctx;
 	const struct ieee80211_mgmt *mgmt;
-	size_t hdr_len;
 	const u8 *sa, *data;
 	int prot;
 
 	mgmt = (const struct ieee80211_mgmt *) buf;
-	hdr_len = (const u8 *) &mgmt->u.action.u.vs_public_action.action - buf;
-	if (hdr_len > len)
+	if (len < IEEE80211_HDRLEN + 2)
 		return;
 	if (mgmt->u.action.category != WLAN_ACTION_PUBLIC &&
 	    mgmt->u.action.category != WLAN_ACTION_PROTECTED_DUAL)
@@ -1231,8 +1229,8 @@
 	 */
 	prot = mgmt->u.action.category == WLAN_ACTION_PROTECTED_DUAL;
 	sa = mgmt->sa;
-	len -= hdr_len;
-	data = &mgmt->u.action.u.public_action.action;
+	len -= IEEE80211_HDRLEN + 1;
+	data = buf + IEEE80211_HDRLEN + 1;
 	switch (data[0]) {
 	case WLAN_PA_GAS_INITIAL_REQ:
 		gas_serv_rx_gas_initial_req(hapd, sa, data + 1, len - 1, prot);
diff --git a/src/ap/ieee802_11_ht.c b/src/ap/ieee802_11_ht.c
index c0a7cd4..fe87883 100644
--- a/src/ap/ieee802_11_ht.c
+++ b/src/ap/ieee802_11_ht.c
@@ -211,8 +211,7 @@
 	struct ieee80211_2040_intol_chan_report *ic_report;
 	int is_ht_allowed = 1;
 	int i;
-	const u8 *data = (const u8 *) &mgmt->u.action.u.public_action.action;
-	size_t hdr_len;
+	const u8 *data = ((const u8 *) mgmt) + 1;
 
 	hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
 		       HOSTAPD_LEVEL_DEBUG, "hostapd_public_action - action=%d",
@@ -221,8 +220,7 @@
 	if (!(iface->conf->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
 		return;
 
-	hdr_len = data - (u8 *) mgmt;
-	if (hdr_len > len)
+	if (len < IEEE80211_HDRLEN + 1)
 		return;
 	data++;
 
diff --git a/src/ap/wnm_ap.c b/src/ap/wnm_ap.c
index 8e5bdcb..cf25dbb 100644
--- a/src/ap/wnm_ap.c
+++ b/src/ap/wnm_ap.c
@@ -376,10 +376,9 @@
 	if (len < IEEE80211_HDRLEN + 2)
 		return -1;
 
-	payload = &mgmt->u.action.category;
-	payload++;
+	payload = ((const u8 *) mgmt) + IEEE80211_HDRLEN + 1;
 	action = *payload++;
-	plen = (((const u8 *) mgmt) + len) - payload;
+	plen = len - IEEE80211_HDRLEN - 2;
 
 	switch (action) {
 	case WNM_BSS_TRANS_MGMT_QUERY:
diff --git a/src/eap_peer/eap_tnc.c b/src/eap_peer/eap_tnc.c
index bc13647..25b9f12 100644
--- a/src/eap_peer/eap_tnc.c
+++ b/src/eap_peer/eap_tnc.c
@@ -243,7 +243,8 @@
 		message_length = WPA_GET_BE32(pos);
 		pos += 4;
 
-		if (message_length < (u32) (end - pos)) {
+		if (message_length < (u32) (end - pos) ||
+		    message_length > 75000) {
 			wpa_printf(MSG_DEBUG, "EAP-TNC: Invalid Message "
 				   "Length (%d; %ld remaining in this msg)",
 				   message_length, (long) (end - pos));
diff --git a/src/eap_peer/tncc.c b/src/eap_peer/tncc.c
index 5b1a2d4..7ca956e 100644
--- a/src/eap_peer/tncc.c
+++ b/src/eap_peer/tncc.c
@@ -1092,8 +1092,10 @@
 			int error = 0;
 
 			imc = tncc_parse_imc(pos + 4, line_end, &error);
-			if (error)
+			if (error) {
+				os_free(config);
 				return -1;
+			}
 			if (imc) {
 				if (last == NULL)
 					tncc->imc = imc;
diff --git a/src/eap_server/eap_server_tnc.c b/src/eap_server/eap_server_tnc.c
index 67a3dfa..21bd26f 100644
--- a/src/eap_server/eap_server_tnc.c
+++ b/src/eap_server/eap_server_tnc.c
@@ -480,7 +480,8 @@
 		message_length = WPA_GET_BE32(pos);
 		pos += 4;
 
-		if (message_length < (u32) (end - pos)) {
+		if (message_length < (u32) (end - pos) ||
+		    message_length > 75000) {
 			wpa_printf(MSG_DEBUG, "EAP-TNC: Invalid Message "
 				   "Length (%d; %ld remaining in this msg)",
 				   message_length, (long) (end - pos));
diff --git a/src/p2p/p2p_dev_disc.c b/src/p2p/p2p_dev_disc.c
index 76d01cf..86bae1a 100644
--- a/src/p2p/p2p_dev_disc.c
+++ b/src/p2p/p2p_dev_disc.c
@@ -68,6 +68,7 @@
 {
 	struct p2p_device *go;
 	struct wpabuf *req;
+	unsigned int wait_time;
 
 	go = p2p_get_device(p2p, dev->member_in_go_dev);
 	if (go == NULL || dev->oper_freq <= 0) {
@@ -88,9 +89,12 @@
 	os_memcpy(p2p->pending_client_disc_addr, dev->info.p2p_device_addr,
 		  ETH_ALEN);
 	p2p->pending_action_state = P2P_PENDING_DEV_DISC_REQUEST;
+	wait_time = 1000;
+	if (p2p->cfg->max_listen && wait_time > p2p->cfg->max_listen)
+		wait_time = p2p->cfg->max_listen;
 	if (p2p_send_action(p2p, dev->oper_freq, go->info.p2p_device_addr,
 			    p2p->cfg->dev_addr, go->info.p2p_device_addr,
-			    wpabuf_head(req), wpabuf_len(req), 1000) < 0) {
+			    wpabuf_head(req), wpabuf_len(req), wait_time) < 0) {
 		p2p_dbg(p2p, "Failed to send Action frame");
 		wpabuf_free(req);
 		/* TODO: how to recover from failure? */
diff --git a/src/p2p/p2p_sd.c b/src/p2p/p2p_sd.c
index 9df834c..6235b1d 100644
--- a/src/p2p/p2p_sd.c
+++ b/src/p2p/p2p_sd.c
@@ -266,6 +266,7 @@
 	int ret = 0;
 	struct p2p_sd_query *query;
 	int freq;
+	unsigned int wait_time;
 
 	freq = dev->listen_freq > 0 ? dev->listen_freq : dev->oper_freq;
 	if (freq <= 0) {
@@ -290,9 +291,12 @@
 	p2p->sd_query = query;
 	p2p->pending_action_state = P2P_PENDING_SD;
 
+	wait_time = 5000;
+	if (p2p->cfg->max_listen && wait_time > p2p->cfg->max_listen)
+		wait_time = p2p->cfg->max_listen;
 	if (p2p_send_action(p2p, freq, dev->info.p2p_device_addr,
 			    p2p->cfg->dev_addr, dev->info.p2p_device_addr,
-			    wpabuf_head(req), wpabuf_len(req), 5000) < 0) {
+			    wpabuf_head(req), wpabuf_len(req), wait_time) < 0) {
 		p2p_dbg(p2p, "Failed to send Action frame");
 		ret = -1;
 	}
diff --git a/src/wps/httpread.c b/src/wps/httpread.c
index 6d2d11c..2f08f37 100644
--- a/src/wps/httpread.c
+++ b/src/wps/httpread.c
@@ -413,8 +413,8 @@
 		 */
 		if (httpread_debug >= 10)
 			wpa_printf(MSG_DEBUG, "httpread ok eof(%p)", h);
-			h->got_body = 1;
-			goto got_file;
+		h->got_body = 1;
+		goto got_file;
 	}
 	rbp = readbuf;