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;
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index b02c424..d10583b 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -373,18 +373,16 @@
#ifdef CONFIG_P2P
struct wpa_supplicant *wpa_s = ctx;
const struct ieee80211_mgmt *mgmt;
- size_t hdr_len;
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 + 1)
return;
if (mgmt->u.action.category != WLAN_ACTION_PUBLIC)
return;
wpas_p2p_rx_action(wpa_s, mgmt->da, mgmt->sa, mgmt->bssid,
mgmt->u.action.category,
- &mgmt->u.action.u.vs_public_action.action,
- len - hdr_len, freq);
+ buf + IEEE80211_HDRLEN + 1,
+ len - IEEE80211_HDRLEN - 1, freq);
#endif /* CONFIG_P2P */
}
@@ -440,16 +438,14 @@
#ifdef CONFIG_P2P
struct wpa_supplicant *wpa_s = ctx;
const struct ieee80211_mgmt *mgmt;
- size_t hdr_len;
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 + 1)
return -1;
wpas_p2p_rx_action(wpa_s, mgmt->da, mgmt->sa, mgmt->bssid,
mgmt->u.action.category,
- &mgmt->u.action.u.vs_public_action.action,
- len - hdr_len, freq);
+ buf + IEEE80211_HDRLEN + 1,
+ len - IEEE80211_HDRLEN - 1, freq);
#endif /* CONFIG_P2P */
return 0;
}
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 53e23ff..4311208 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -5368,7 +5368,7 @@
if (len == 0 && cred && cred->realm)
return hs20_nai_home_realm_list(wpa_s, dst_addr, cred->realm);
- if (len % 1)
+ if (len & 1)
return -1;
len /= 2;
buf = os_malloc(len);
diff --git a/wpa_supplicant/dbus/dbus_dict_helpers.c b/wpa_supplicant/dbus/dbus_dict_helpers.c
index 61a9430..949ce7c 100644
--- a/wpa_supplicant/dbus/dbus_dict_helpers.c
+++ b/wpa_supplicant/dbus/dbus_dict_helpers.c
@@ -881,6 +881,8 @@
}
dbus_message_iter_recurse(iter, &iter_array);
+ os_memset(&tmpentry, 0, sizeof(tmpentry));
+ tmpentry.type = DBUS_TYPE_ARRAY;
if (_wpa_dbus_dict_entry_get_byte_array(&iter_array, &tmpentry)
== FALSE)
goto cleanup;
@@ -932,6 +934,7 @@
break;
case DBUS_TYPE_ARRAY:
success = _wpa_dbus_dict_entry_get_binarray(&iter_array, entry);
+ break;
default:
break;
}
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index 6e1eedb..a89a87d 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -271,6 +271,7 @@
wpa_config_update_prio_list(wpa_s->conf);
os_free(value);
+ value = NULL;
wpa_dbus_dict_entry_clear(&entry);
}
@@ -561,24 +562,28 @@
goto error;
if (!os_strcmp(entry.key, "Driver") &&
(entry.type == DBUS_TYPE_STRING)) {
+ os_free(driver);
driver = os_strdup(entry.str_value);
wpa_dbus_dict_entry_clear(&entry);
if (driver == NULL)
goto error;
} else if (!os_strcmp(entry.key, "Ifname") &&
(entry.type == DBUS_TYPE_STRING)) {
+ os_free(ifname);
ifname = os_strdup(entry.str_value);
wpa_dbus_dict_entry_clear(&entry);
if (ifname == NULL)
goto error;
} else if (!os_strcmp(entry.key, "ConfigFile") &&
(entry.type == DBUS_TYPE_STRING)) {
+ os_free(confname);
confname = os_strdup(entry.str_value);
wpa_dbus_dict_entry_clear(&entry);
if (confname == NULL)
goto error;
} else if (!os_strcmp(entry.key, "BridgeIfname") &&
(entry.type == DBUS_TYPE_STRING)) {
+ os_free(bridge_ifname);
bridge_ifname = os_strdup(entry.str_value);
wpa_dbus_dict_entry_clear(&entry);
if (bridge_ifname == NULL)
diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
index 8be8288..857b527 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
@@ -1143,6 +1143,7 @@
break;
default:
str = "device";
+ break;
}
return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, &str,
@@ -2026,11 +2027,9 @@
/* Parse WPS Vendor Extensions sent in Beacon/Probe Response */
for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) {
if (hapd->conf->wps_vendor_ext[i] == NULL)
- vendor_ext[i] = NULL;
- else {
- vendor_ext[num_vendor_ext++] =
- hapd->conf->wps_vendor_ext[i];
- }
+ continue;
+ vendor_ext[num_vendor_ext++] =
+ hapd->conf->wps_vendor_ext[i];
}
}
@@ -2039,7 +2038,7 @@
DBUS_TYPE_BYTE,
vendor_ext,
num_vendor_ext,
- error);
+ error);
}
diff --git a/wpa_supplicant/dbus/dbus_old_handlers.c b/wpa_supplicant/dbus/dbus_old_handlers.c
index 7c4630e..c0cb1c2 100644
--- a/wpa_supplicant/dbus/dbus_old_handlers.c
+++ b/wpa_supplicant/dbus/dbus_old_handlers.c
@@ -113,24 +113,28 @@
goto error;
if (!strcmp(entry.key, "driver") &&
(entry.type == DBUS_TYPE_STRING)) {
+ os_free(driver);
driver = os_strdup(entry.str_value);
wpa_dbus_dict_entry_clear(&entry);
if (driver == NULL)
goto error;
} else if (!strcmp(entry.key, "driver-params") &&
(entry.type == DBUS_TYPE_STRING)) {
+ os_free(driver_param);
driver_param = os_strdup(entry.str_value);
wpa_dbus_dict_entry_clear(&entry);
if (driver_param == NULL)
goto error;
} else if (!strcmp(entry.key, "config-file") &&
(entry.type == DBUS_TYPE_STRING)) {
+ os_free(confname);
confname = os_strdup(entry.str_value);
wpa_dbus_dict_entry_clear(&entry);
if (confname == NULL)
goto error;
} else if (!strcmp(entry.key, "bridge-ifname") &&
(entry.type == DBUS_TYPE_STRING)) {
+ os_free(bridge_ifname);
bridge_ifname = os_strdup(entry.str_value);
wpa_dbus_dict_entry_clear(&entry);
if (bridge_ifname == NULL)
@@ -1200,16 +1204,19 @@
goto error;
if (!strcmp(entry.key, "opensc_engine_path") &&
(entry.type == DBUS_TYPE_STRING)) {
+ os_free(opensc_engine_path);
opensc_engine_path = os_strdup(entry.str_value);
if (opensc_engine_path == NULL)
goto error;
} else if (!strcmp(entry.key, "pkcs11_engine_path") &&
(entry.type == DBUS_TYPE_STRING)) {
+ os_free(pkcs11_engine_path);
pkcs11_engine_path = os_strdup(entry.str_value);
if (pkcs11_engine_path == NULL)
goto error;
} else if (!strcmp(entry.key, "pkcs11_module_path") &&
(entry.type == DBUS_TYPE_STRING)) {
+ os_free(pkcs11_module_path);
pkcs11_module_path = os_strdup(entry.str_value);
if (pkcs11_module_path == NULL)
goto error;
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index f511e1a..a9291a4 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -2792,9 +2792,9 @@
static void wpas_event_rx_mgmt_action(struct wpa_supplicant *wpa_s,
- const struct ieee80211_mgmt *mgmt,
- size_t len, int freq)
+ const u8 *frame, size_t len, int freq)
{
+ const struct ieee80211_mgmt *mgmt;
const u8 *payload;
size_t plen;
u8 category;
@@ -2802,9 +2802,10 @@
if (len < IEEE80211_HDRLEN + 2)
return;
- payload = &mgmt->u.action.category;
+ mgmt = (const struct ieee80211_mgmt *) frame;
+ payload = frame + IEEE80211_HDRLEN;
category = *payload++;
- plen = (((const u8 *) mgmt) + len) - payload;
+ plen = len - IEEE80211_HDRLEN - 1;
wpa_dbg(wpa_s, MSG_DEBUG, "Received Action frame: SA=" MACSTR
" Category=%u DataLen=%d freq=%d MHz",
@@ -3227,7 +3228,8 @@
if (stype == WLAN_FC_STYPE_ACTION) {
wpas_event_rx_mgmt_action(
- wpa_s, mgmt, data->rx_mgmt.frame_len,
+ wpa_s, data->rx_mgmt.frame,
+ data->rx_mgmt.frame_len,
data->rx_mgmt.freq);
break;
}
diff --git a/wpa_supplicant/gas_query.c b/wpa_supplicant/gas_query.c
index aff1950..3986268 100644
--- a/wpa_supplicant/gas_query.c
+++ b/wpa_supplicant/gas_query.c
@@ -256,6 +256,7 @@
static int gas_query_tx(struct gas_query *gas, struct gas_query_pending *query,
struct wpabuf *req)
{
+ unsigned int wait_time;
int res, prot = pmf_in_use(gas->wpa_s, query->addr);
wpa_printf(MSG_DEBUG, "GAS: Send action frame to " MACSTR " len=%u "
@@ -266,10 +267,14 @@
*categ = WLAN_ACTION_PROTECTED_DUAL;
}
os_get_reltime(&query->last_oper);
+ wait_time = 1000;
+ if (gas->wpa_s->max_remain_on_chan &&
+ wait_time > gas->wpa_s->max_remain_on_chan)
+ wait_time = gas->wpa_s->max_remain_on_chan;
res = offchannel_send_action(gas->wpa_s, query->freq, query->addr,
gas->wpa_s->own_addr, query->addr,
- wpabuf_head(req), wpabuf_len(req), 1000,
- gas_query_tx_status, 0);
+ wpabuf_head(req), wpabuf_len(req),
+ wait_time, gas_query_tx_status, 0);
if (res == 0)
query->offchannel_tx_started = 1;
return res;
diff --git a/wpa_supplicant/wifi_display.c b/wpa_supplicant/wifi_display.c
index 8435b63..f0c4364 100644
--- a/wpa_supplicant/wifi_display.c
+++ b/wpa_supplicant/wifi_display.c
@@ -276,6 +276,8 @@
while (i + WIFI_DISPLAY_SUBELEM_HEADER_LEN < buflen) {
elen = WPA_GET_BE16(buf + i + 1);
+ if (i + WIFI_DISPLAY_SUBELEM_HEADER_LEN + elen > buflen)
+ break; /* truncated subelement */
if (buf[i] == id) {
subelem = os_zalloc(2 * elen + 1);
diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c
index e395ef1..4a792c4 100644
--- a/wpa_supplicant/wnm_sta.c
+++ b/wpa_supplicant/wnm_sta.c
@@ -921,8 +921,7 @@
if (len < IEEE80211_HDRLEN + 2)
return;
- pos = &mgmt->u.action.category;
- pos++;
+ pos = ((const u8 *) mgmt) + IEEE80211_HDRLEN + 1;
act = *pos++;
end = ((const u8 *) mgmt) + len;
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index ffba0f5..c4d5cb2 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -984,6 +984,7 @@
} else if (bss_osen && (ssid->proto & WPA_PROTO_OSEN)) {
wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: using OSEN");
/* TODO: parse OSEN element */
+ os_memset(&ie, 0, sizeof(ie));
ie.group_cipher = WPA_CIPHER_CCMP;
ie.pairwise_cipher = WPA_CIPHER_CCMP;
ie.key_mgmt = WPA_KEY_MGMT_OSEN;