Accumulative patch from commit 6ea1f4135b72199988393f34dd7f5ad8040b7a42

6ea1f41 Try to set WPA-None key after IBSS-joined event
66562e9 Use cached driver capabilities instead of new fetch for each operation
55293aa TDLS: Do not overwrite the reason code in the Tear Down Request
4aa8186 Add a configration parameter for sched_scan interval
03565bc Synchronize with wireless-testing.git include/uapi/linux/nl80211.h
f11b72c TDLS: Move AID=1 workaround into driver_nl80211.c
7853369 TDLS: Pass peer's AID information to kernel
55a2df4 HS 2.0: Include HS 2.0 Indication element only for HS 2.0 association
ad0685e edit: Fix history processing on running old command
9be3714 wpa_cli: Fetch the current BSSID list when starting interactive mode
69aa334 wpa_cli: Add BSSID tab completion for set bssid_filter
2156587 wpa_cli: Replace set command help with completion routine
f1fb042 wpa_cli: Allow space in the set command value
f5ffc34 wpa_supplicant: Allow global scan frequencies configuration
abfc3ad Synchronize build config comments for wpa_supplicant
a01e10d Android: Enable WPS ER and NFC support in the build
11e5a49 WPS: Do not use void* in arithmetic
0f105f9 HS 2.0: Move Probe Request Indication IE addition to proper place
8543ed8 WPA: Print pairwise EAPOL-Key flag as a bool
7af092a hostapd: Add Key MIC in group EAPOL-Key frames corruption test option
b691dcb nl80211: Fix max_remain_on_chan capability reading
41b1a76 P2P: Clone beacon_int when initializing new group interface
741ed9f WPS: Remove duplicate networks after WPS

Change-Id: I9a2a0cb2acf87dfd7548318d2bda5f342b815884
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index 70b26a6..7ab86fc 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -168,6 +168,7 @@
 	conf->ignore_auth_probability = 0.0d;
 	conf->ignore_assoc_probability = 0.0d;
 	conf->ignore_reassoc_probability = 0.0d;
+	conf->corrupt_gtk_rekey_mic_probability = 0.0d;
 #endif /* CONFIG_TESTING_OPTIONS */
 
 	return conf;
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index f9629a2..16134da 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -526,6 +526,7 @@
 	double ignore_auth_probability;
 	double ignore_assoc_probability;
 	double ignore_reassoc_probability;
+	double corrupt_gtk_rekey_mic_probability;
 #endif /* CONFIG_TESTING_OPTIONS */
 };
 
diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
index 4f1f6fb..18ae86c 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -1232,7 +1232,7 @@
 	else
 		version = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
 
-	pairwise = key_info & WPA_KEY_INFO_KEY_TYPE;
+	pairwise = !!(key_info & WPA_KEY_INFO_KEY_TYPE);
 
 	wpa_printf(MSG_DEBUG, "WPA: Send EAPOL(version=%d secure=%d mic=%d "
 		   "ack=%d install=%d pairwise=%d kde_len=%lu keyidx=%d "
@@ -1347,6 +1347,16 @@
 		}
 		wpa_eapol_key_mic(sm->PTK.kck, version, (u8 *) hdr, len,
 				  key->key_mic);
+#ifdef CONFIG_TESTING_OPTIONS
+		if (!pairwise &&
+		    wpa_auth->conf.corrupt_gtk_rekey_mic_probability > 0.0d &&
+		    drand48() <
+		    wpa_auth->conf.corrupt_gtk_rekey_mic_probability) {
+			wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
+					"Corrupting group EAPOL-Key Key MIC");
+			key->key_mic[0]++;
+		}
+#endif /* CONFIG_TESTING_OPTIONS */
 	}
 
 	wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_inc_EapolFramesTx,
diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h
index 465eec6..9126b90 100644
--- a/src/ap/wpa_auth.h
+++ b/src/ap/wpa_auth.h
@@ -160,6 +160,9 @@
 #endif /* CONFIG_IEEE80211R */
 	int disable_gtk;
 	int ap_mlme;
+#ifdef CONFIG_TESTING_OPTIONS
+	double corrupt_gtk_rekey_mic_probability;
+#endif /* CONFIG_TESTING_OPTIONS */
 };
 
 typedef enum {
diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c
index fdaaaff..e2be1ea 100644
--- a/src/ap/wpa_auth_glue.c
+++ b/src/ap/wpa_auth_glue.c
@@ -28,6 +28,7 @@
 
 
 static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
+				  struct hostapd_config *iconf,
 				  struct wpa_auth_config *wconf)
 {
 	os_memset(wconf, 0, sizeof(*wconf));
@@ -74,6 +75,10 @@
 #ifdef CONFIG_HS20
 	wconf->disable_gtk = conf->disable_dgaf;
 #endif /* CONFIG_HS20 */
+#ifdef CONFIG_TESTING_OPTIONS
+	wconf->corrupt_gtk_rekey_mic_probability =
+		iconf->corrupt_gtk_rekey_mic_probability;
+#endif /* CONFIG_TESTING_OPTIONS */
 }
 
 
@@ -509,7 +514,7 @@
 	const u8 *wpa_ie;
 	size_t wpa_ie_len;
 
-	hostapd_wpa_auth_conf(hapd->conf, &_conf);
+	hostapd_wpa_auth_conf(hapd->conf, hapd->iconf, &_conf);
 	if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_EAPOL_TX_STATUS)
 		_conf.tx_status = 1;
 	if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_AP_MLME)
@@ -583,7 +588,7 @@
 void hostapd_reconfig_wpa(struct hostapd_data *hapd)
 {
 	struct wpa_auth_config wpa_auth_conf;
-	hostapd_wpa_auth_conf(hapd->conf, &wpa_auth_conf);
+	hostapd_wpa_auth_conf(hapd->conf, hapd->iconf, &wpa_auth_conf);
 	wpa_reconfig(hapd->wpa_auth, &wpa_auth_conf);
 }
 
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 6125015..213f3c3 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -2747,9 +2747,6 @@
 static void wiphy_info_max_roc(struct wpa_driver_capa *capa,
 			       struct nlattr *tb)
 {
-	/* default to 5000 since early versions of mac80211 don't set it */
-	capa->max_remain_on_chan = 5000;
-
 	if (tb)
 		capa->max_remain_on_chan = nla_get_u32(tb);
 }
@@ -2941,6 +2938,11 @@
 			   "concurrent (driver advertised support)");
 		drv->capa.flags |= WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT;
 	}
+
+	/* default to 5000 since early versions of mac80211 don't set it */
+	if (!drv->capa.max_remain_on_chan)
+		drv->capa.max_remain_on_chan = 5000;
+
 	return 0;
 nla_put_failure:
 	nlmsg_free(msg);
@@ -6092,8 +6094,18 @@
 	wpa_hexdump(MSG_DEBUG, "  * supported rates", params->supp_rates,
 		    params->supp_rates_len);
 	if (!params->set) {
-		wpa_printf(MSG_DEBUG, "  * aid=%u", params->aid);
-		NLA_PUT_U16(msg, NL80211_ATTR_STA_AID, params->aid);
+		if (params->aid) {
+			wpa_printf(MSG_DEBUG, "  * aid=%u", params->aid);
+			NLA_PUT_U16(msg, NL80211_ATTR_STA_AID, params->aid);
+		} else {
+			/*
+			 * cfg80211 validates that AID is non-zero, so we have
+			 * to make this a non-zero value for the TDLS case where
+			 * a dummy STA entry is used for now.
+			 */
+			wpa_printf(MSG_DEBUG, "  * aid=1 (TDLS workaround)");
+			NLA_PUT_U16(msg, NL80211_ATTR_STA_AID, 1);
+		}
 		wpa_printf(MSG_DEBUG, "  * listen_interval=%u",
 			   params->listen_interval);
 		NLA_PUT_U16(msg, NL80211_ATTR_STA_LISTEN_INTERVAL,
diff --git a/src/drivers/nl80211_copy.h b/src/drivers/nl80211_copy.h
index 79da871..d1e48b5 100644
--- a/src/drivers/nl80211_copy.h
+++ b/src/drivers/nl80211_copy.h
@@ -639,6 +639,13 @@
  *	with the relevant Information Elements. This event is used to report
  *	received FT IEs (MDIE, FTIE, RSN IE, TIE, RICIE).
  *
+ * @NL80211_CMD_CRIT_PROTOCOL_START: Indicates user-space will start running
+ *	a critical protocol that needs more reliability in the connection to
+ *	complete.
+ *
+ * @NL80211_CMD_CRIT_PROTOCOL_STOP: Indicates the connection reliability can
+ *	return back to normal.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -798,6 +805,9 @@
 	NL80211_CMD_UPDATE_FT_IES,
 	NL80211_CMD_FT_EVENT,
 
+	NL80211_CMD_CRIT_PROTOCOL_START,
+	NL80211_CMD_CRIT_PROTOCOL_STOP,
+
 	/* add new commands above here */
 
 	/* used to define NL80211_CMD_MAX below */
@@ -1414,6 +1424,11 @@
  * @NL80211_ATTR_IE_RIC: Resource Information Container Information
  *	Element
  *
+ * @NL80211_ATTR_CRIT_PROT_ID: critical protocol identifier requiring increased
+ *	reliability, see &enum nl80211_crit_proto_id (u16).
+ * @NL80211_ATTR_MAX_CRIT_PROT_DURATION: duration in milliseconds in which
+ *      the connection should have increased reliability (u16).
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -1709,6 +1724,9 @@
 	NL80211_ATTR_MDID,
 	NL80211_ATTR_IE_RIC,
 
+	NL80211_ATTR_CRIT_PROT_ID,
+	NL80211_ATTR_MAX_CRIT_PROT_DURATION,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -3682,4 +3700,25 @@
 	NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP =	1 << 0,
 };
 
+/**
+ * enum nl80211_crit_proto_id - nl80211 critical protocol identifiers
+ *
+ * @NL80211_CRIT_PROTO_UNSPEC: protocol unspecified.
+ * @NL80211_CRIT_PROTO_DHCP: BOOTP or DHCPv6 protocol.
+ * @NL80211_CRIT_PROTO_EAPOL: EAPOL protocol.
+ * @NL80211_CRIT_PROTO_APIPA: APIPA protocol.
+ * @NUM_NL80211_CRIT_PROTO: must be kept last.
+ */
+enum nl80211_crit_proto_id {
+	NL80211_CRIT_PROTO_UNSPEC,
+	NL80211_CRIT_PROTO_DHCP,
+	NL80211_CRIT_PROTO_EAPOL,
+	NL80211_CRIT_PROTO_APIPA,
+	/* add other protocols before this one */
+	NUM_NL80211_CRIT_PROTO
+};
+
+/* maximum duration for critical protocol measures */
+#define NL80211_CRIT_PROTO_MAX_DURATION		5000 /* msec */
+
 #endif /* __LINUX_NL80211_H */
diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c
index 069e22b..81e2a5c 100644
--- a/src/rsn_supp/tdls.c
+++ b/src/rsn_supp/tdls.c
@@ -127,6 +127,8 @@
 
 	u8 qos_info;
 
+	u16 aid;
+
 	u8 *ext_capab;
 	size_t ext_capab_len;
 };
@@ -696,13 +698,8 @@
 		return -1;
 	pos = rbuf;
 
-	if (!wpa_tdls_get_privacy(sm) || !peer->tpk_set || !peer->tpk_success) {
-		if (reason_code != WLAN_REASON_DEAUTH_LEAVING) {
-			/* Overwrite the reason code */
-			reason_code = WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED;
-		}
+	if (!wpa_tdls_get_privacy(sm) || !peer->tpk_set || !peer->tpk_success)
 		goto skip_ies;
-	}
 
 	ftie = (struct wpa_tdls_ftie *) pos;
 	ftie->ie_type = WLAN_EID_FAST_BSS_TRANSITION;
@@ -1558,6 +1555,8 @@
 
 	peer->qos_info = kde.qosinfo;
 
+	peer->aid = kde.aid;
+
 #ifdef CONFIG_TDLS_TESTING
 	if (tdls_testing & TDLS_TESTING_CONCURRENT_INIT) {
 		peer = wpa_tdls_add_peer(sm, src_addr, NULL);
@@ -1735,7 +1734,7 @@
 
 skip_rsn_check:
 	/* add the peer to the driver as a "setup in progress" peer */
-	wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, NULL, 0, NULL, NULL, 0,
+	wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0,
 				NULL, 0);
 
 	wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Response / TPK M2");
@@ -1777,7 +1776,8 @@
 	}
 
 	/* add supported rates, capabilities, and qos_info to the TDLS peer */
-	if (wpa_sm_tdls_peer_addset(sm, peer->addr, 0, peer->capability,
+	if (wpa_sm_tdls_peer_addset(sm, peer->addr, 0, peer->aid,
+				    peer->capability,
 				    peer->supp_rates, peer->supp_rates_len,
 				    peer->ht_capabilities,
 				    peer->vht_capabilities,
@@ -1908,6 +1908,8 @@
 
 	peer->qos_info = kde.qosinfo;
 
+	peer->aid = kde.aid;
+
 	if (!wpa_tdls_get_privacy(sm)) {
 		peer->rsnie_p_len = 0;
 		peer->cipher = WPA_CIPHER_NONE;
@@ -2235,7 +2237,7 @@
 	peer->initiator = 1;
 
 	/* add the peer to the driver as a "setup in progress" peer */
-	wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, NULL, 0, NULL, NULL, 0,
+	wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0,
 				NULL, 0);
 
 	if (wpa_tdls_send_tpk_m1(sm, peer) < 0) {
diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h
index d4533a8..78dfb52 100644
--- a/src/rsn_supp/wpa.h
+++ b/src/rsn_supp/wpa.h
@@ -56,7 +56,7 @@
 			      u8 action_code, u8 dialog_token,
 			      u16 status_code, const u8 *buf, size_t len);
 	int (*tdls_oper)(void *ctx, int oper, const u8 *peer);
-	int (*tdls_peer_addset)(void *ctx, const u8 *addr, int add,
+	int (*tdls_peer_addset)(void *ctx, const u8 *addr, int add, u16 aid,
 				u16 capability, const u8 *supp_rates,
 				size_t supp_rates_len,
 				const struct ieee80211_ht_capabilities *ht_capab,
diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h
index 877e6de..0e0d373 100644
--- a/src/rsn_supp/wpa_i.h
+++ b/src/rsn_supp/wpa_i.h
@@ -282,7 +282,7 @@
 
 static inline int
 wpa_sm_tdls_peer_addset(struct wpa_sm *sm, const u8 *addr, int add,
-			u16 capability, const u8 *supp_rates,
+			u16 aid, u16 capability, const u8 *supp_rates,
 			size_t supp_rates_len,
 			const struct ieee80211_ht_capabilities *ht_capab,
 			const struct ieee80211_vht_capabilities *vht_capab,
@@ -290,7 +290,7 @@
 {
 	if (sm->ctx->tdls_peer_addset)
 		return sm->ctx->tdls_peer_addset(sm->ctx->ctx, addr, add,
-						 capability, supp_rates,
+						 aid, capability, supp_rates,
 						 supp_rates_len, ht_capab,
 						 vht_capab, qosinfo,
 						 ext_capab, ext_capab_len);
diff --git a/src/rsn_supp/wpa_ie.c b/src/rsn_supp/wpa_ie.c
index 652197f..ba203e6 100644
--- a/src/rsn_supp/wpa_ie.c
+++ b/src/rsn_supp/wpa_ie.c
@@ -430,6 +430,9 @@
 		} else if (*pos == WLAN_EID_HT_CAP) {
 			ie->ht_capabilities = pos + 2;
 			ie->ht_capabilities_len = pos[1];
+		} else if (*pos == WLAN_EID_VHT_AID) {
+			if (pos[1] >= 2)
+				ie->aid = WPA_GET_LE16(pos + 2);
 		} else if (*pos == WLAN_EID_VHT_CAP) {
 			ie->vht_capabilities = pos + 2;
 			ie->vht_capabilities_len = pos[1];
diff --git a/src/rsn_supp/wpa_ie.h b/src/rsn_supp/wpa_ie.h
index 82a5c08..2c78801 100644
--- a/src/rsn_supp/wpa_ie.h
+++ b/src/rsn_supp/wpa_ie.h
@@ -54,6 +54,7 @@
 	const u8 *vht_capabilities;
 	size_t vht_capabilities_len;
 	u8 qosinfo;
+	u16 aid;
 };
 
 int wpa_supplicant_parse_ies(const u8 *buf, size_t len,
diff --git a/src/utils/edit.c b/src/utils/edit.c
index b01e08d..177ecf4 100644
--- a/src/utils/edit.c
+++ b/src/utils/edit.c
@@ -345,7 +345,7 @@
 
 static void process_cmd(void)
 {
-
+	currbuf_valid = 0;
 	if (cmdbuf_len == 0) {
 		printf("\n%s> ", ps2 ? ps2 : "");
 		fflush(stdout);
diff --git a/src/wps/http_client.c b/src/wps/http_client.c
index c6d6c7f..0290013 100644
--- a/src/wps/http_client.c
+++ b/src/wps/http_client.c
@@ -92,7 +92,7 @@
 		   (unsigned long) wpabuf_len(c->req),
 		   (unsigned long) wpabuf_len(c->req) - c->req_pos);
 
-	res = send(c->sd, wpabuf_head(c->req) + c->req_pos,
+	res = send(c->sd, wpabuf_head_u8(c->req) + c->req_pos,
 		   wpabuf_len(c->req) - c->req_pos, 0);
 	if (res < 0) {
 		wpa_printf(MSG_DEBUG, "HTTP: Failed to send buffer: %s",