Cumulative patch from commit 1b56d398a7646c66fd3df8f0a5159c920f99de36
1b56d39 wpa_supplicant: Fix misplaced os_free
8597ebd Fix hostapd segfault on beacon hint event
c69ed4d bsd: Fix hostapd compiler warning
d950477 Fix authentication algorithm negotiation in SME code
1412bee nl80211: Show DFS region info in debug messages
fd92413 hostapd: Increase timeout for channel list update to 5 seconds
ff5e1d1 nl80211: Treat RSSI as part of each sched scan matchset
04c366c Fix memory leaks and wrong memory access
fd67275 wpa_supplicant: Fix wrong size memory allocation
4b0f228 nl80211: Fix channel switching with VHT80
e28f39b nl80211: Verify that ifindex attribute is included in survey
4701f37 wpa_cli: Add tdls_external_control to tab completion for SET
Change-Id: Iad3348c5c012c018cc1bfb759a36dbdb237b6468
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index 79ab4ba..368b202 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -140,6 +140,7 @@
bss->radius = os_zalloc(sizeof(*bss->radius));
if (bss->radius == NULL) {
+ os_free(conf->bss);
os_free(conf);
os_free(bss);
return NULL;
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index 220211c..f9edf3b 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -1028,7 +1028,7 @@
if (os_strncmp(previous_country, country, 2) != 0) {
wpa_printf(MSG_DEBUG, "Continue interface setup after channel list update");
iface->wait_channel_update = 1;
- eloop_register_timeout(1, 0,
+ eloop_register_timeout(5, 0,
channel_list_update_timeout,
iface, NULL);
return 0;
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 2f4536e..7ad8576 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -47,6 +47,7 @@
REGDOM_SET_BY_USER,
REGDOM_SET_BY_DRIVER,
REGDOM_SET_BY_COUNTRY_IE,
+ REGDOM_BEACON_HINT,
};
/**
diff --git a/src/drivers/driver_bsd.c b/src/drivers/driver_bsd.c
index 71c9ce9..ca64d5c 100644
--- a/src/drivers/driver_bsd.c
+++ b/src/drivers/driver_bsd.c
@@ -68,34 +68,6 @@
/* Generic functions for hostapd and wpa_supplicant */
-static enum ieee80211_opmode
-get80211opmode(struct bsd_driver_data *drv)
-{
- struct ifmediareq ifmr;
-
- (void) memset(&ifmr, 0, sizeof(ifmr));
- (void) os_strlcpy(ifmr.ifm_name, drv->ifname, sizeof(ifmr.ifm_name));
-
- if (ioctl(drv->sock, SIOCGIFMEDIA, (caddr_t)&ifmr) >= 0) {
- if (ifmr.ifm_current & IFM_IEEE80211_ADHOC) {
- if (ifmr.ifm_current & IFM_FLAG0)
- return IEEE80211_M_AHDEMO;
- else
- return IEEE80211_M_IBSS;
- }
- if (ifmr.ifm_current & IFM_IEEE80211_HOSTAP)
- return IEEE80211_M_HOSTAP;
- if (ifmr.ifm_current & IFM_IEEE80211_MONITOR)
- return IEEE80211_M_MONITOR;
-#ifdef IEEE80211_M_MBSS
- if (ifmr.ifm_current & IFM_IEEE80211_MBSS)
- return IEEE80211_M_MBSS;
-#endif /* IEEE80211_M_MBSS */
- }
- return IEEE80211_M_STA;
-}
-
-
static int
bsd_set80211(void *priv, int op, int val, const void *arg, int arg_len)
{
@@ -314,14 +286,6 @@
return 0;
}
-#ifdef HOSTAPD
-static int
-bsd_commit(void *priv)
-{
- return bsd_ctrl_iface(priv, 1);
-}
-#endif /* HOSTAPD */
-
static int
bsd_set_key(const char *ifname, void *priv, enum wpa_alg alg,
const unsigned char *addr, int key_idx, int set_tx, const u8 *seq,
@@ -530,28 +494,6 @@
return bsd_ctrl_iface(priv, 1);
}
-#ifdef HOSTAPD
-static int
-bsd_set_sta_authorized(void *priv, const u8 *addr,
- int total_flags, int flags_or, int flags_and)
-{
- int authorized = -1;
-
- /* For now, only support setting Authorized flag */
- if (flags_or & WPA_STA_AUTHORIZED)
- authorized = 1;
- if (!(flags_and & WPA_STA_AUTHORIZED))
- authorized = 0;
-
- if (authorized < 0)
- return 0;
-
- return bsd_send_mlme_param(priv, authorized ?
- IEEE80211_MLME_AUTHORIZE :
- IEEE80211_MLME_UNAUTHORIZE, 0, addr);
-}
-#endif /* HOSTAPD */
-
static void
bsd_new_sta(void *priv, void *ctx, u8 addr[IEEE80211_ADDR_LEN])
{
@@ -933,6 +875,33 @@
os_free(drv);
}
+
+static int
+bsd_commit(void *priv)
+{
+ return bsd_ctrl_iface(priv, 1);
+}
+
+
+static int
+bsd_set_sta_authorized(void *priv, const u8 *addr,
+ int total_flags, int flags_or, int flags_and)
+{
+ int authorized = -1;
+
+ /* For now, only support setting Authorized flag */
+ if (flags_or & WPA_STA_AUTHORIZED)
+ authorized = 1;
+ if (!(flags_and & WPA_STA_AUTHORIZED))
+ authorized = 0;
+
+ if (authorized < 0)
+ return 0;
+
+ return bsd_send_mlme_param(priv, authorized ?
+ IEEE80211_MLME_AUTHORIZE :
+ IEEE80211_MLME_UNAUTHORIZE, 0, addr);
+}
#else /* HOSTAPD */
static int
@@ -1485,6 +1454,33 @@
return 0;
}
+static enum ieee80211_opmode
+get80211opmode(struct bsd_driver_data *drv)
+{
+ struct ifmediareq ifmr;
+
+ (void) memset(&ifmr, 0, sizeof(ifmr));
+ (void) os_strlcpy(ifmr.ifm_name, drv->ifname, sizeof(ifmr.ifm_name));
+
+ if (ioctl(drv->sock, SIOCGIFMEDIA, (caddr_t)&ifmr) >= 0) {
+ if (ifmr.ifm_current & IFM_IEEE80211_ADHOC) {
+ if (ifmr.ifm_current & IFM_FLAG0)
+ return IEEE80211_M_AHDEMO;
+ else
+ return IEEE80211_M_IBSS;
+ }
+ if (ifmr.ifm_current & IFM_IEEE80211_HOSTAP)
+ return IEEE80211_M_HOSTAP;
+ if (ifmr.ifm_current & IFM_IEEE80211_MONITOR)
+ return IEEE80211_M_MONITOR;
+#ifdef IEEE80211_M_MBSS
+ if (ifmr.ifm_current & IFM_IEEE80211_MBSS)
+ return IEEE80211_M_MBSS;
+#endif /* IEEE80211_M_MBSS */
+ }
+ return IEEE80211_M_STA;
+}
+
static void *
wpa_driver_bsd_init(void *ctx, const char *ifname)
{
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 646d3f8..5323e99 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -1550,6 +1550,33 @@
}
+static int calculate_chan_offset(int width, int freq, int cf1, int cf2)
+{
+ int freq1 = 0;
+
+ switch (convert2width(width)) {
+ case CHAN_WIDTH_20_NOHT:
+ case CHAN_WIDTH_20:
+ return 0;
+ case CHAN_WIDTH_40:
+ freq1 = cf1 - 10;
+ break;
+ case CHAN_WIDTH_80:
+ freq1 = cf1 - 30;
+ break;
+ case CHAN_WIDTH_160:
+ freq1 = cf1 - 70;
+ break;
+ case CHAN_WIDTH_UNKNOWN:
+ case CHAN_WIDTH_80P80:
+ /* FIXME: implement this */
+ return 0;
+ }
+
+ return (abs(freq - freq1) / 20) % 2 == 0 ? 1 : -1;
+}
+
+
static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
struct nlattr *ifindex, struct nlattr *freq,
struct nlattr *type, struct nlattr *bw,
@@ -1591,6 +1618,14 @@
chan_offset = -1;
break;
}
+ } else if (bw && cf1) {
+ /* This can happen for example with VHT80 ch switch */
+ chan_offset = calculate_chan_offset(nla_get_u32(bw),
+ nla_get_u32(freq),
+ nla_get_u32(cf1),
+ cf2 ? nla_get_u32(cf2) : 0);
+ } else {
+ wpa_printf(MSG_WARNING, "nl80211: Unknown secondary channel information - following channel definition calculations may fail");
}
os_memset(&data, 0, sizeof(data));
@@ -2965,8 +3000,10 @@
break;
case NL80211_CMD_REG_BEACON_HINT:
wpa_printf(MSG_DEBUG, "nl80211: Regulatory beacon hint");
+ os_memset(&data, 0, sizeof(data));
+ data.channel_list_changed.initiator = REGDOM_BEACON_HINT;
wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED,
- NULL);
+ &data);
break;
case NL80211_CMD_NEW_STATION:
nl80211_new_station_event(drv, tb);
@@ -4960,10 +4997,20 @@
NLA_PUT(msg, NL80211_ATTR_SCHED_SCAN_MATCH_SSID,
drv->filter_ssids[i].ssid_len,
drv->filter_ssids[i].ssid);
+ if (params->filter_rssi)
+ NLA_PUT_U32(msg,
+ NL80211_SCHED_SCAN_MATCH_ATTR_RSSI,
+ params->filter_rssi);
nla_nest_end(msg, match_set_ssid);
}
+ /*
+ * Due to backward compatibility code, newer kernels treat this
+ * matchset (with only an RSSI filter) as the default for all
+ * other matchsets, unless it's the only one, in which case the
+ * matchset will actually allow all SSIDs above the RSSI.
+ */
if (params->filter_rssi) {
struct nlattr *match_set_rssi;
match_set_rssi = nla_nest_start(msg, 0);
@@ -6537,6 +6584,23 @@
}
+static const char * dfs_domain_name(enum nl80211_dfs_regions region)
+{
+ switch (region) {
+ case NL80211_DFS_UNSET:
+ return "DFS-UNSET";
+ case NL80211_DFS_FCC:
+ return "DFS-FCC";
+ case NL80211_DFS_ETSI:
+ return "DFS-ETSI";
+ case NL80211_DFS_JP:
+ return "DFS-JP";
+ default:
+ return "DFS-invalid";
+ }
+}
+
+
static int nl80211_get_reg(struct nl_msg *msg, void *arg)
{
struct phy_info_arg *results = arg;
@@ -6563,8 +6627,16 @@
return NL_SKIP;
}
- wpa_printf(MSG_DEBUG, "nl80211: Regulatory information - country=%s",
- (char *) nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]));
+ if (tb_msg[NL80211_ATTR_DFS_REGION]) {
+ enum nl80211_dfs_regions dfs_domain;
+ dfs_domain = nla_get_u8(tb_msg[NL80211_ATTR_DFS_REGION]);
+ wpa_printf(MSG_DEBUG, "nl80211: Regulatory information - country=%s (%s)",
+ (char *) nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]),
+ dfs_domain_name(dfs_domain));
+ } else {
+ wpa_printf(MSG_DEBUG, "nl80211: Regulatory information - country=%s",
+ (char *) nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]));
+ }
nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
{
@@ -10619,6 +10691,9 @@
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL);
+ if (!tb[NL80211_ATTR_IFINDEX])
+ return NL_SKIP;
+
ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
if (!tb[NL80211_ATTR_SURVEY_INFO])
diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
index ca347e7..957dee5 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -3862,8 +3862,10 @@
os_memset(&msg, 0, sizeof(msg));
if (p2p_parse_ies(ie, ie_len, &msg))
return;
- if (msg.minor_reason_code == NULL)
+ if (msg.minor_reason_code == NULL) {
+ p2p_parse_free(&msg);
return;
+ }
p2p_dbg(p2p, "Deauthentication notification BSSID " MACSTR
" reason_code=%u minor_reason_code=%u",
@@ -3884,8 +3886,10 @@
os_memset(&msg, 0, sizeof(msg));
if (p2p_parse_ies(ie, ie_len, &msg))
return;
- if (msg.minor_reason_code == NULL)
+ if (msg.minor_reason_code == NULL) {
+ p2p_parse_free(&msg);
return;
+ }
p2p_dbg(p2p, "Disassociation notification BSSID " MACSTR
" reason_code=%u minor_reason_code=%u",
diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c
index 76436f5..e28f93e 100644
--- a/src/p2p/p2p_go_neg.c
+++ b/src/p2p/p2p_go_neg.c
@@ -1136,6 +1136,7 @@
if (!(dev->flags & P2P_DEV_WAIT_GO_NEG_CONFIRM)) {
p2p_dbg(p2p, "Was not expecting GO Negotiation Confirm - ignore");
+ p2p_parse_free(&msg);
return;
}
dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM;
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index b43a72a..2dd7054 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -2912,6 +2912,7 @@
{
size_t len;
char *tmp;
+ int res;
tmp = wpa_config_parse_string(pos, &len);
if (tmp == NULL) {
@@ -2920,7 +2921,9 @@
return -1;
}
- return wpa_global_config_parse_str(data, config, line, tmp);
+ res = wpa_global_config_parse_str(data, config, line, tmp);
+ os_free(tmp);
+ return res;
}
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 8d6c381..2928b6f 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -1684,9 +1684,9 @@
info->dev_capab, info->group_capab,
wfd_dev_info_hex ? " wfd_dev_info=0x" : "",
wfd_dev_info_hex ? wfd_dev_info_hex : "");
-#endif /* CONFIG_NO_STDOUT_DEBUG */
os_free(wfd_dev_info_hex);
+#endif /* CONFIG_NO_STDOUT_DEBUG */
wpas_notify_p2p_device_found(ctx, info->p2p_device_addr, new_device);
}
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 30da097..18d243e 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -1765,12 +1765,13 @@
}
if (src->filter_ssids) {
- params->filter_ssids = os_malloc(sizeof(params->filter_ssids) *
+ params->filter_ssids = os_malloc(sizeof(*params->filter_ssids) *
src->num_filter_ssids);
if (params->filter_ssids == NULL)
goto failed;
os_memcpy(params->filter_ssids, src->filter_ssids,
- sizeof(params->filter_ssids) * src->num_filter_ssids);
+ sizeof(*params->filter_ssids) *
+ src->num_filter_ssids);
params->num_filter_ssids = src->num_filter_ssids;
}
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index 43f40cd..451f5ae 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -636,6 +636,8 @@
return;
}
+ wpas_connect_work_done(wpa_s);
+
switch (data->auth.auth_type) {
case WLAN_AUTH_OPEN:
wpa_s->current_ssid->auth_alg = WPA_AUTH_ALG_SHARED;
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index 358c2fe..d66e864 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -627,7 +627,8 @@
"wps_nfc_dev_pw", "ext_password_backend",
"p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
"sae_groups", "dtim_period", "beacon_int", "ap_vendor_elements",
- "ignore_old_scan_res", "freq_list", "external_sim"
+ "ignore_old_scan_res", "freq_list", "external_sim",
+ "tdls_external_control"
};
int i, num_fields = ARRAY_SIZE(fields);
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 35f5693..455b158 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -2083,7 +2083,7 @@
}
if (pkcs11_module_path != NULL) {
pkcs11_module_path_copy = os_strdup(pkcs11_module_path);
- if (pkcs11_engine_path_copy == NULL) {
+ if (pkcs11_module_path_copy == NULL) {
os_free(pkcs11_engine_path_copy);
return -1;
}