2019-03-15 15:39:17

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 00/11] cfg80211/mac80211 patches from our internal tree 2019-03-15

From: Luca Coelho <[email protected]>

Hi,

Some patches with mac80211 and cfg80211 changes from our internal
tree.

Please review, though you have already reviewed most if not all of
them ;)

Cheers,
Luca.


Andrei Otcheretianski (1):
mac80211: Increase MAX_MSG_LEN

Avraham Stern (1):
mac80211_hwsim: set p2p device interface support indication

Ilan Peer (1):
cfg80211: Handle WMM rules in regulatory domain intersection

Liad Kaufman (1):
ieee80211: update HE IEs to D4.0 spec

Luca Coelho (1):
nl80211: copy the length of dst of src in
nl80211_notify_radar_detection()

Sara Sharon (5):
cfg80211: don't skip multi-bssid index element
cfg80211: support non-inheritance element
mac80211: support non-inheritance element
cfg80211: support profile split between elements
mac80211: support profile split between elements

Shaul Triebitz (1):
nl80211: increase NL80211_MAX_SUPP_REG_RULES

drivers/net/wireless/mac80211_hwsim.c | 2 +
include/linux/ieee80211.h | 14 ++-
include/net/cfg80211.h | 22 ++++
include/uapi/linux/nl80211.h | 4 +-
net/mac80211/ieee80211_i.h | 1 -
net/mac80211/trace_msg.h | 7 +-
net/mac80211/util.c | 162 +++++++++++++++---------
net/wireless/nl80211.c | 2 +-
net/wireless/reg.c | 39 ++++++
net/wireless/scan.c | 173 ++++++++++++++++++++++++--
10 files changed, 345 insertions(+), 81 deletions(-)

--
2.20.1



2019-03-15 15:39:17

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 03/11] nl80211: copy the length of dst of src in nl80211_notify_radar_detection()

From: Luca Coelho <[email protected]>

It is generally safer to copy the length of the destination instead of
the length of the source, because if the sizes don't match, it's
usually better to leak some data from the source than to write data
out of bounds in the destination.

Signed-off-by: Luca Coelho <[email protected]>
---
net/wireless/nl80211.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 25a9e3b5c154..239be0e2f9e1 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -8061,7 +8061,7 @@ static int nl80211_notify_radar_detection(struct sk_buff *skb,

cfg80211_sched_dfs_chan_update(rdev);

- memcpy(&rdev->radar_chandef, &chandef, sizeof(chandef));
+ memcpy(&rdev->radar_chandef, &chandef, sizeof(rdev->radar_chandef));

/* Propagate this notification to other radios as well */
queue_work(cfg80211_wq, &rdev->propagate_radar_detect_wk);
--
2.20.1


2019-03-15 15:39:18

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 04/11] cfg80211: Handle WMM rules in regulatory domain intersection

From: Ilan Peer <[email protected]>

The support added for regulatory WMM rules did not handle
the case of regulatory domain intersections. Fix it.

Signed-off-by: Ilan Peer <[email protected]>
Fixes: 230ebaa189af ("cfg80211: read wmm rules from regulatory database")
Signed-off-by: Luca Coelho <[email protected]>
---
net/wireless/reg.c | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)

diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 2f1bf91eb226..0ba778f371cb 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1309,6 +1309,16 @@ reg_intersect_dfs_region(const enum nl80211_dfs_regions dfs_region1,
return dfs_region1;
}

+static void reg_wmm_rules_intersect(const struct ieee80211_wmm_ac *wmm_ac1,
+ const struct ieee80211_wmm_ac *wmm_ac2,
+ struct ieee80211_wmm_ac *intersect)
+{
+ intersect->cw_min = max_t(u16, wmm_ac1->cw_min, wmm_ac2->cw_min);
+ intersect->cw_max = max_t(u16, wmm_ac1->cw_max, wmm_ac2->cw_max);
+ intersect->cot = min_t(u16, wmm_ac1->cot, wmm_ac2->cot);
+ intersect->aifsn = max_t(u8, wmm_ac1->aifsn, wmm_ac2->aifsn);
+}
+
/*
* Helper for regdom_intersect(), this does the real
* mathematical intersection fun
@@ -1323,6 +1333,8 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1,
struct ieee80211_freq_range *freq_range;
const struct ieee80211_power_rule *power_rule1, *power_rule2;
struct ieee80211_power_rule *power_rule;
+ const struct ieee80211_wmm_rule *wmm_rule1, *wmm_rule2;
+ struct ieee80211_wmm_rule *wmm_rule;
u32 freq_diff, max_bandwidth1, max_bandwidth2;

freq_range1 = &rule1->freq_range;
@@ -1333,6 +1345,10 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1,
power_rule2 = &rule2->power_rule;
power_rule = &intersected_rule->power_rule;

+ wmm_rule1 = &rule1->wmm_rule;
+ wmm_rule2 = &rule2->wmm_rule;
+ wmm_rule = &intersected_rule->wmm_rule;
+
freq_range->start_freq_khz = max(freq_range1->start_freq_khz,
freq_range2->start_freq_khz);
freq_range->end_freq_khz = min(freq_range1->end_freq_khz,
@@ -1376,6 +1392,29 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1,
intersected_rule->dfs_cac_ms = max(rule1->dfs_cac_ms,
rule2->dfs_cac_ms);

+ if (rule1->has_wmm && rule2->has_wmm) {
+ u8 ac;
+
+ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
+ reg_wmm_rules_intersect(&wmm_rule1->client[ac],
+ &wmm_rule2->client[ac],
+ &wmm_rule->client[ac]);
+ reg_wmm_rules_intersect(&wmm_rule1->ap[ac],
+ &wmm_rule2->ap[ac],
+ &wmm_rule->ap[ac]);
+ }
+
+ intersected_rule->has_wmm = true;
+ } else if (rule1->has_wmm) {
+ *wmm_rule = *wmm_rule1;
+ intersected_rule->has_wmm = true;
+ } else if (rule2->has_wmm) {
+ *wmm_rule = *wmm_rule2;
+ intersected_rule->has_wmm = true;
+ } else {
+ intersected_rule->has_wmm = false;
+ }
+
if (!is_valid_reg_rule(intersected_rule))
return -EINVAL;

--
2.20.1


2019-03-15 15:39:18

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 02/11] nl80211: increase NL80211_MAX_SUPP_REG_RULES

From: Shaul Triebitz <[email protected]>

The iwlwifi driver creates one rule per channel, thus it needs more
rules than normal. To solve this, increase NL80211_MAX_SUPP_REG_RULES
so iwlwifi can also fit UHB (ultra high band) channels.

Signed-off-by: Shaul Triebitz <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
include/uapi/linux/nl80211.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index dd4f86ee286e..f04f407b14c5 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -11,7 +11,7 @@
* Copyright 2008 Jouni Malinen <[email protected]>
* Copyright 2008 Colin McCabe <[email protected]>
* Copyright 2015-2017 Intel Deutschland GmbH
- * Copyright (C) 2018 Intel Corporation
+ * Copyright (C) 2018-2019 Intel Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -2802,7 +2802,7 @@ enum nl80211_attrs {

#define NL80211_MAX_SUPP_RATES 32
#define NL80211_MAX_SUPP_HT_RATES 77
-#define NL80211_MAX_SUPP_REG_RULES 64
+#define NL80211_MAX_SUPP_REG_RULES 128
#define NL80211_TKIP_DATA_OFFSET_ENCR_KEY 0
#define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY 16
#define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY 24
--
2.20.1


2019-03-15 15:39:19

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 01/11] mac80211: Increase MAX_MSG_LEN

From: Andrei Otcheretianski <[email protected]>

Looks that 100 chars isn't enough for messages, as we keep getting
warnings popping from different places due to message shortening.
Instead of trying to shorten the prints, just increase the buffer size.

Signed-off-by: Andrei Otcheretianski <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
net/mac80211/trace_msg.h | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/net/mac80211/trace_msg.h b/net/mac80211/trace_msg.h
index 366b9e6f043e..40141df09f25 100644
--- a/net/mac80211/trace_msg.h
+++ b/net/mac80211/trace_msg.h
@@ -1,4 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Portions of this file
+ * Copyright (C) 2019 Intel Corporation
+ */
+
#ifdef CONFIG_MAC80211_MESSAGE_TRACING

#if !defined(__MAC80211_MSG_DRIVER_TRACE) || defined(TRACE_HEADER_MULTI_READ)
@@ -11,7 +16,7 @@
#undef TRACE_SYSTEM
#define TRACE_SYSTEM mac80211_msg

-#define MAX_MSG_LEN 100
+#define MAX_MSG_LEN 120

DECLARE_EVENT_CLASS(mac80211_msg_event,
TP_PROTO(struct va_format *vaf),
--
2.20.1


2019-03-15 15:39:20

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 05/11] mac80211_hwsim: set p2p device interface support indication

From: Avraham Stern <[email protected]>

P2P device interface type was not indicated in the supported
interface types even when hwsim was configured with p2p device
support. Fix it.

Signed-off-by: Avraham Stern <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/mac80211_hwsim.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 0838af04d681..d79f3ee2a741 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -3894,6 +3894,8 @@ static int __init init_mac80211_hwsim(void)
param.p2p_device = support_p2p_device;
param.use_chanctx = channels > 1;
param.iftypes = HWSIM_IFTYPE_SUPPORT_MASK;
+ if (param.p2p_device)
+ param.iftypes |= BIT(NL80211_IFTYPE_P2P_DEVICE);

err = mac80211_hwsim_new_radio(NULL, &param);
if (err < 0)
--
2.20.1


2019-03-15 15:39:22

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 07/11] cfg80211: support non-inheritance element

From: Sara Sharon <[email protected]>

Subelement profile may specify element IDs it doesn't inherit
from the management frame. Support it.

Signed-off-by: Sara Sharon <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
include/linux/ieee80211.h | 1 +
include/net/cfg80211.h | 8 +++++
net/wireless/scan.c | 61 ++++++++++++++++++++++++++++++++++++++-
3 files changed, 69 insertions(+), 1 deletion(-)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 48703ec60d06..522881f31938 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -2487,6 +2487,7 @@ enum ieee80211_eid_ext {
WLAN_EID_EXT_HE_MU_EDCA = 38,
WLAN_EID_EXT_MAX_CHANNEL_SWITCH_TIME = 52,
WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION = 55,
+ WLAN_EID_EXT_NON_INHERITANCE = 56,
};

/* Action category code */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index bb307a11ee63..cd47b7085f59 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -5491,6 +5491,14 @@ static inline void cfg80211_gen_new_bssid(const u8 *bssid, u8 max_bssid,
u64_to_ether_addr(new_bssid_u64, new_bssid);
}

+/**
+ * cfg80211_is_element_inherited - returns if element ID should be inherited
+ * @element: element to check
+ * @non_inherit_element: non inheritance element
+ */
+bool cfg80211_is_element_inherited(const struct element *element,
+ const struct element *non_inherit_element);
+
/**
* enum cfg80211_bss_frame_type - frame type that the BSS data came from
* @CFG80211_BSS_FTYPE_UNKNOWN: driver doesn't know whether the data is
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 49f700a1460b..bda9114ded77 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -179,12 +179,63 @@ static bool __cfg80211_unlink_bss(struct cfg80211_registered_device *rdev,
return true;
}

+bool cfg80211_is_element_inherited(const struct element *elem,
+ const struct element *non_inherit_elem)
+{
+ u8 id_len, ext_id_len, i, loop_len, id;
+ const u8 *list;
+
+ if (elem->id == WLAN_EID_MULTIPLE_BSSID)
+ return false;
+
+ if (!non_inherit_elem || non_inherit_elem->datalen < 2)
+ return true;
+
+ /*
+ * non inheritance element format is:
+ * ext ID (56) | IDs list len | list | extension IDs list len | list
+ * Both lists are optional. Both lengths are mandatory.
+ * This means valid length is:
+ * elem_len = 1 (extension ID) + 2 (list len fields) + list lengths
+ */
+ id_len = non_inherit_elem->data[1];
+ if (non_inherit_elem->datalen < 3 + id_len)
+ return true;
+
+ ext_id_len = non_inherit_elem->data[2 + id_len];
+ if (non_inherit_elem->datalen < 3 + id_len + ext_id_len)
+ return true;
+
+ if (elem->id == WLAN_EID_EXTENSION) {
+ if (!ext_id_len)
+ return true;
+ loop_len = ext_id_len;
+ list = &non_inherit_elem->data[3 + id_len];
+ id = elem->data[0];
+ } else {
+ if (!id_len)
+ return true;
+ loop_len = id_len;
+ list = &non_inherit_elem->data[2];
+ id = elem->id;
+ }
+
+ for (i = 0; i < loop_len; i++) {
+ if (list[i] == id)
+ return false;
+ }
+
+ return true;
+}
+EXPORT_SYMBOL(cfg80211_is_element_inherited);
+
static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
const u8 *subelement, size_t subie_len,
u8 *new_ie, gfp_t gfp)
{
u8 *pos, *tmp;
const u8 *tmp_old, *tmp_new;
+ const struct element *non_inherit_elem;
u8 *sub_copy;

/* copy subelement as we need to change its content to
@@ -204,6 +255,11 @@ static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
pos += (tmp_new[1] + 2);
}

+ /* get non inheritance list if exists */
+ non_inherit_elem =
+ cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
+ sub_copy, subie_len);
+
/* go through IEs in ie (skip SSID) and subelement,
* merge them into new_ie
*/
@@ -224,8 +280,11 @@ static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
subie_len);

if (!tmp) {
+ const struct element *old_elem = (void *)tmp_old;
+
/* ie in old ie but not in subelement */
- if (tmp_old[0] != WLAN_EID_MULTIPLE_BSSID) {
+ if (cfg80211_is_element_inherited(old_elem,
+ non_inherit_elem)) {
memcpy(pos, tmp_old, tmp_old[1] + 2);
pos += tmp_old[1] + 2;
}
--
2.20.1


2019-03-15 15:39:21

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 06/11] cfg80211: don't skip multi-bssid index element

From: Sara Sharon <[email protected]>

When creating the IEs for the nontransmitted BSS, the index
element is skipped. However, we need to get DTIM values from
it, so don't skip it.

Signed-off-by: Sara Sharon <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
net/wireless/scan.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 287518c6caa4..49f700a1460b 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -269,8 +269,7 @@ static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
tmp_new = sub_copy;
while (tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) {
if (!(tmp_new[0] == WLAN_EID_NON_TX_BSSID_CAP ||
- tmp_new[0] == WLAN_EID_SSID ||
- tmp_new[0] == WLAN_EID_MULTI_BSSID_IDX)) {
+ tmp_new[0] == WLAN_EID_SSID)) {
memcpy(pos, tmp_new, tmp_new[1] + 2);
pos += tmp_new[1] + 2;
}
--
2.20.1


2019-03-15 15:39:23

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 09/11] cfg80211: support profile split between elements

From: Sara Sharon <[email protected]>

Since an element is limited to 255 octets, a profile may be split
split to several elements. Support the split as defined in the 11ax
draft 3. Detect legacy split and print a net-rate limited warning,
since there is no ROI in supporting this probably non-existent
split.

Signed-off-by: Sara Sharon <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
include/net/cfg80211.h | 14 ++++++
net/wireless/scan.c | 109 ++++++++++++++++++++++++++++++++++++++---
2 files changed, 117 insertions(+), 6 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index cd47b7085f59..f192c65fe9b4 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -5499,6 +5499,20 @@ static inline void cfg80211_gen_new_bssid(const u8 *bssid, u8 max_bssid,
bool cfg80211_is_element_inherited(const struct element *element,
const struct element *non_inherit_element);

+/**
+ * cfg80211_merge_profile - merges a MBSSID profile if it is split between IEs
+ * @ie: ies
+ * @ielen: length of IEs
+ * @mbssid_elem: current MBSSID element
+ * @sub_elem: current MBSSID subelement (profile)
+ * @merged_ie: location of the merged profile
+ * @max_copy_len: max merged profile length
+ */
+size_t cfg80211_merge_profile(const u8 *ie, size_t ielen,
+ const struct element *mbssid_elem,
+ const struct element *sub_elem,
+ u8 **merged_ie, size_t max_copy_len);
+
/**
* enum cfg80211_bss_frame_type - frame type that the BSS data came from
* @CFG80211_BSS_FTYPE_UNKNOWN: driver doesn't know whether the data is
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index bda9114ded77..878c867f3f7d 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -1456,6 +1456,78 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy,
return &res->pub;
}

+static const struct element
+*cfg80211_get_profile_continuation(const u8 *ie, size_t ielen,
+ const struct element *mbssid_elem,
+ const struct element *sub_elem)
+{
+ const u8 *mbssid_end = mbssid_elem->data + mbssid_elem->datalen;
+ const struct element *next_mbssid;
+ const struct element *next_sub;
+
+ next_mbssid = cfg80211_find_elem(WLAN_EID_MULTIPLE_BSSID,
+ mbssid_end,
+ ielen - (mbssid_end - ie));
+
+ /*
+ * If is is not the last subelement in current MBSSID IE or there isn't
+ * a next MBSSID IE - profile is complete.
+ */
+ if ((sub_elem->data + sub_elem->datalen < mbssid_end - 1) ||
+ !next_mbssid)
+ return NULL;
+
+ /* For any length error, just return NULL */
+
+ if (next_mbssid->datalen < 4)
+ return NULL;
+
+ next_sub = (void *)&next_mbssid->data[1];
+
+ if (next_mbssid->data + next_mbssid->datalen <
+ next_sub->data + next_sub->datalen)
+ return NULL;
+
+ if (next_sub->id != 0 || next_sub->datalen < 2)
+ return NULL;
+
+ /*
+ * Check if the first element in the next sub element is a start
+ * of a new profile
+ */
+ return next_sub->data[0] == WLAN_EID_NON_TX_BSSID_CAP ?
+ NULL : next_mbssid;
+}
+
+size_t cfg80211_merge_profile(const u8 *ie, size_t ielen,
+ const struct element *mbssid_elem,
+ const struct element *sub_elem,
+ u8 **merged_ie, size_t max_copy_len)
+{
+ size_t copied_len = sub_elem->datalen;
+ const struct element *next_mbssid;
+
+ if (sub_elem->datalen > max_copy_len)
+ return 0;
+
+ memcpy(*merged_ie, sub_elem->data, sub_elem->datalen);
+
+ while ((next_mbssid = cfg80211_get_profile_continuation(ie, ielen,
+ mbssid_elem,
+ sub_elem))) {
+ const struct element *next_sub = (void *)&next_mbssid->data[1];
+
+ if (copied_len + next_sub->datalen > max_copy_len)
+ break;
+ memcpy(*merged_ie + copied_len, next_sub->data,
+ next_sub->datalen);
+ copied_len += next_sub->datalen;
+ }
+
+ return copied_len;
+}
+EXPORT_SYMBOL(cfg80211_merge_profile);
+
static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
struct cfg80211_inform_bss *data,
enum cfg80211_bss_frame_type ftype,
@@ -1469,7 +1541,8 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
const struct element *elem, *sub;
size_t new_ie_len;
u8 new_bssid[ETH_ALEN];
- u8 *new_ie;
+ u8 *new_ie, *profile;
+ u64 seen_indices = 0;
u16 capability;
struct cfg80211_bss *bss;

@@ -1487,10 +1560,16 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
if (!new_ie)
return;

+ profile = kmalloc(ielen, gfp);
+ if (!profile)
+ goto out;
+
for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, ie, ielen) {
if (elem->datalen < 4)
continue;
for_each_element(sub, elem->data + 1, elem->datalen - 1) {
+ u8 profile_len;
+
if (sub->id != 0 || sub->datalen < 4) {
/* not a valid BSS profile */
continue;
@@ -1505,16 +1584,31 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
continue;
}

+ memset(profile, 0, ielen);
+ profile_len = cfg80211_merge_profile(ie, ielen,
+ elem,
+ sub,
+ &profile,
+ ielen);
+
/* found a Nontransmitted BSSID Profile */
mbssid_index_ie = cfg80211_find_ie
(WLAN_EID_MULTI_BSSID_IDX,
- sub->data, sub->datalen);
+ profile, profile_len);
if (!mbssid_index_ie || mbssid_index_ie[1] < 1 ||
- mbssid_index_ie[2] == 0) {
+ mbssid_index_ie[2] == 0 ||
+ mbssid_index_ie[2] > 46) {
/* No valid Multiple BSSID-Index element */
continue;
}

+ if (seen_indices & BIT(mbssid_index_ie[2]))
+ /* We don't support legacy split of a profile */
+ net_dbg_ratelimited("Partial info for BSSID index %d\n",
+ mbssid_index_ie[2]);
+
+ seen_indices |= BIT(mbssid_index_ie[2]);
+
non_tx_data->bssid_index = mbssid_index_ie[2];
non_tx_data->max_bssid_indicator = elem->data[0];

@@ -1523,13 +1617,14 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
non_tx_data->bssid_index,
new_bssid);
memset(new_ie, 0, IEEE80211_MAX_DATA_LEN);
- new_ie_len = cfg80211_gen_new_ie(ie, ielen, sub->data,
- sub->datalen, new_ie,
+ new_ie_len = cfg80211_gen_new_ie(ie, ielen,
+ profile,
+ profile_len, new_ie,
gfp);
if (!new_ie_len)
continue;

- capability = get_unaligned_le16(sub->data + 2);
+ capability = get_unaligned_le16(profile + 2);
bss = cfg80211_inform_single_bss_data(wiphy, data,
ftype,
new_bssid, tsf,
@@ -1545,7 +1640,9 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
}
}

+out:
kfree(new_ie);
+ kfree(profile);
}

struct cfg80211_bss *
--
2.20.1


2019-03-15 15:39:24

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 08/11] mac80211: support non-inheritance element

From: Sara Sharon <[email protected]>

Subelement profile may specify element IDs it doesn't inherit
from the management frame. Support it.

Signed-off-by: Sara Sharon <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
net/mac80211/util.c | 134 +++++++++++++++++++++++++-------------------
1 file changed, 77 insertions(+), 57 deletions(-)

diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 4c1655972565..08197afdb7b3 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -894,10 +894,10 @@ EXPORT_SYMBOL(ieee80211_queue_delayed_work);
static u32
_ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
struct ieee802_11_elems *elems,
- u64 filter, u32 crc, u8 *transmitter_bssid,
- u8 *bss_bssid)
+ u64 filter, u32 crc,
+ const struct element *check_inherit)
{
- const struct element *elem, *sub;
+ const struct element *elem;
bool calc_crc = filter != 0;
DECLARE_BITMAP(seen_elems, 256);
const u8 *ie;
@@ -910,6 +910,11 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
u8 elen = elem->datalen;
const u8 *pos = elem->data;

+ if (check_inherit &&
+ !cfg80211_is_element_inherited(elem,
+ check_inherit))
+ continue;
+
switch (id) {
case WLAN_EID_SSID:
case WLAN_EID_SUPP_RATES:
@@ -1208,57 +1213,6 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
if (elen >= sizeof(*elems->max_idle_period_ie))
elems->max_idle_period_ie = (void *)pos;
break;
- case WLAN_EID_MULTIPLE_BSSID:
- if (!bss_bssid || !transmitter_bssid || elen < 4)
- break;
-
- elems->max_bssid_indicator = pos[0];
-
- for_each_element(sub, pos + 1, elen - 1) {
- u8 sub_len = sub->datalen;
- u8 new_bssid[ETH_ALEN];
- const u8 *index;
-
- /*
- * we only expect the "non-transmitted BSSID
- * profile" subelement (subelement id 0)
- */
- if (sub->id != 0 || sub->datalen < 4) {
- /* not a valid BSS profile */
- continue;
- }
-
- if (sub->data[0] != WLAN_EID_NON_TX_BSSID_CAP ||
- sub->data[1] != 2) {
- /* The first element of the
- * Nontransmitted BSSID Profile is not
- * the Nontransmitted BSSID Capability
- * element.
- */
- continue;
- }
-
- /* found a Nontransmitted BSSID Profile */
- index = cfg80211_find_ie(WLAN_EID_MULTI_BSSID_IDX,
- sub->data, sub_len);
- if (!index || index[1] < 1 || index[2] == 0) {
- /* Invalid MBSSID Index element */
- continue;
- }
-
- cfg80211_gen_new_bssid(transmitter_bssid,
- pos[0],
- index[2],
- new_bssid);
- if (ether_addr_equal(new_bssid, bss_bssid)) {
- elems->nontransmitted_bssid_profile =
- (void *)sub;
- elems->bssid_index_len = index[1];
- elems->bssid_index = (void *)&index[2];
- break;
- }
- }
- break;
case WLAN_EID_EXTENSION:
if (pos[0] == WLAN_EID_EXT_HE_MU_EDCA &&
elen >= (sizeof(*elems->mu_edca_param_set) + 1)) {
@@ -1300,25 +1254,91 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
return crc;
}

+static void ieee802_11_find_bssid_profile(const u8 *start, size_t len,
+ struct ieee802_11_elems *elems,
+ u8 *transmitter_bssid,
+ u8 *bss_bssid)
+{
+ const struct element *elem, *sub;
+
+ if (!bss_bssid || !transmitter_bssid)
+ return;
+
+ for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, start, len) {
+ if (elem->datalen < 2)
+ continue;
+
+ for_each_element(sub, elem->data + 1, elem->datalen - 1) {
+ u8 new_bssid[ETH_ALEN];
+ const u8 *index;
+
+ if (sub->id != 0 || sub->datalen < 4) {
+ /* not a valid BSS profile */
+ continue;
+ }
+
+ if (sub->data[0] != WLAN_EID_NON_TX_BSSID_CAP ||
+ sub->data[1] != 2) {
+ /* The first element of the
+ * Nontransmitted BSSID Profile is not
+ * the Nontransmitted BSSID Capability
+ * element.
+ */
+ continue;
+ }
+
+ /* found a Nontransmitted BSSID Profile */
+ index = cfg80211_find_ie(WLAN_EID_MULTI_BSSID_IDX,
+ sub->data, sub->datalen);
+ if (!index || index[1] < 1 || index[2] == 0) {
+ /* Invalid MBSSID Index element */
+ continue;
+ }
+
+ cfg80211_gen_new_bssid(transmitter_bssid,
+ elem->data[0],
+ index[2],
+ new_bssid);
+ if (ether_addr_equal(new_bssid, bss_bssid)) {
+ elems->nontransmitted_bssid_profile =
+ elem->data;
+ elems->bssid_index_len = index[1];
+ elems->bssid_index = (void *)&index[2];
+ break;
+ }
+ }
+ }
+}
+
u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
struct ieee802_11_elems *elems,
u64 filter, u32 crc, u8 *transmitter_bssid,
u8 *bss_bssid)
{
+ const struct element *non_inherit = NULL;
+
memset(elems, 0, sizeof(*elems));
elems->ie_start = start;
elems->total_len = len;

+ ieee802_11_find_bssid_profile(start, len, elems, transmitter_bssid,
+ bss_bssid);
+
+ if (elems->nontransmitted_bssid_profile)
+ non_inherit =
+ cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
+ &elems->nontransmitted_bssid_profile[2],
+ elems->nontransmitted_bssid_profile[1]);
+
crc = _ieee802_11_parse_elems_crc(start, len, action, elems, filter,
- crc, transmitter_bssid, bss_bssid);
+ crc, non_inherit);

/* Override with nontransmitted profile, if found */
if (transmitter_bssid && elems->nontransmitted_bssid_profile) {
const u8 *profile = elems->nontransmitted_bssid_profile;

_ieee802_11_parse_elems_crc(&profile[2], profile[1],
- action, elems, 0, 0,
- transmitter_bssid, bss_bssid);
+ action, elems, 0, 0, NULL);
}

if (elems->tim && !elems->parse_error) {
--
2.20.1


2019-03-15 15:54:50

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 10/11] mac80211: support profile split between elements

From: Sara Sharon <[email protected]>

Since an element is limited to 255 octets, a profile may be split
split to several elements. Support the split as defined in the 11ax
draft 3.

Signed-off-by: Sara Sharon <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
net/mac80211/ieee80211_i.h | 1 -
net/mac80211/util.c | 56 +++++++++++++++++++++++++-------------
2 files changed, 37 insertions(+), 20 deletions(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index e170f986d226..c5708f8a7401 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1505,7 +1505,6 @@ struct ieee802_11_elems {
const struct ieee80211_bss_max_idle_period_ie *max_idle_period_ie;
const struct ieee80211_multiple_bssid_configuration *mbssid_config_ie;
const struct ieee80211_bssid_index *bssid_index;
- const u8 *nontransmitted_bssid_profile;
u8 max_bssid_indicator;
u8 dtim_count;
u8 dtim_period;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 08197afdb7b3..99dd58454592 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1254,15 +1254,18 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
return crc;
}

-static void ieee802_11_find_bssid_profile(const u8 *start, size_t len,
- struct ieee802_11_elems *elems,
- u8 *transmitter_bssid,
- u8 *bss_bssid)
+static size_t ieee802_11_find_bssid_profile(const u8 *start, size_t len,
+ struct ieee802_11_elems *elems,
+ u8 *transmitter_bssid,
+ u8 *bss_bssid,
+ u8 **nontransmitted_profile)
{
const struct element *elem, *sub;
+ size_t profile_len = 0;
+ bool found = false;

if (!bss_bssid || !transmitter_bssid)
- return;
+ return profile_len;

for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, start, len) {
if (elem->datalen < 2)
@@ -1287,9 +1290,17 @@ static void ieee802_11_find_bssid_profile(const u8 *start, size_t len,
continue;
}

+ memset(*nontransmitted_profile, 0, len);
+ profile_len = cfg80211_merge_profile(start, len,
+ elem,
+ sub,
+ nontransmitted_profile,
+ len);
+
/* found a Nontransmitted BSSID Profile */
index = cfg80211_find_ie(WLAN_EID_MULTI_BSSID_IDX,
- sub->data, sub->datalen);
+ *nontransmitted_profile,
+ profile_len);
if (!index || index[1] < 1 || index[2] == 0) {
/* Invalid MBSSID Index element */
continue;
@@ -1300,14 +1311,15 @@ static void ieee802_11_find_bssid_profile(const u8 *start, size_t len,
index[2],
new_bssid);
if (ether_addr_equal(new_bssid, bss_bssid)) {
- elems->nontransmitted_bssid_profile =
- elem->data;
+ found = true;
elems->bssid_index_len = index[1];
elems->bssid_index = (void *)&index[2];
break;
}
}
}
+
+ return found ? profile_len : 0;
}

u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
@@ -1316,30 +1328,34 @@ u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
u8 *bss_bssid)
{
const struct element *non_inherit = NULL;
+ u8 *nontransmitted_profile;
+ int nontransmitted_profile_len = 0;

memset(elems, 0, sizeof(*elems));
elems->ie_start = start;
elems->total_len = len;

- ieee802_11_find_bssid_profile(start, len, elems, transmitter_bssid,
- bss_bssid);
-
- if (elems->nontransmitted_bssid_profile)
+ nontransmitted_profile = kmalloc(len, GFP_ATOMIC);
+ if (nontransmitted_profile) {
+ nontransmitted_profile_len =
+ ieee802_11_find_bssid_profile(start, len, elems,
+ transmitter_bssid,
+ bss_bssid,
+ &nontransmitted_profile);
non_inherit =
cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
- &elems->nontransmitted_bssid_profile[2],
- elems->nontransmitted_bssid_profile[1]);
+ nontransmitted_profile,
+ nontransmitted_profile_len);
+ }

crc = _ieee802_11_parse_elems_crc(start, len, action, elems, filter,
crc, non_inherit);

/* Override with nontransmitted profile, if found */
- if (transmitter_bssid && elems->nontransmitted_bssid_profile) {
- const u8 *profile = elems->nontransmitted_bssid_profile;
-
- _ieee802_11_parse_elems_crc(&profile[2], profile[1],
+ if (nontransmitted_profile_len)
+ _ieee802_11_parse_elems_crc(nontransmitted_profile,
+ nontransmitted_profile_len,
action, elems, 0, 0, NULL);
- }

if (elems->tim && !elems->parse_error) {
const struct ieee80211_tim_ie *tim_ie = elems->tim;
@@ -1359,6 +1375,8 @@ u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
offsetofend(struct ieee80211_bssid_index, dtim_count))
elems->dtim_count = elems->bssid_index->dtim_count;

+ kfree(nontransmitted_profile);
+
return crc;
}

--
2.20.1


2019-03-15 15:56:30

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 11/11] ieee80211: update HE IEs to D4.0 spec

From: Liad Kaufman <[email protected]>

Update the out-dated comments as well, and have them point to
the correct sections in the D4.0 spec.

Signed-off-by: Liad Kaufman <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
include/linux/ieee80211.h | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 522881f31938..61f0a316c6ac 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1557,7 +1557,7 @@ struct ieee80211_vht_operation {
* struct ieee80211_he_cap_elem - HE capabilities element
*
* This structure is the "HE capabilities element" fixed fields as
- * described in P802.11ax_D3.0 section 9.4.2.237.2 and 9.4.2.237.3
+ * described in P802.11ax_D4.0 section 9.4.2.242.2 and 9.4.2.242.3
*/
struct ieee80211_he_cap_elem {
u8 mac_cap_info[6];
@@ -1619,12 +1619,12 @@ struct ieee80211_he_mcs_nss_supp {
* struct ieee80211_he_operation - HE capabilities element
*
* This structure is the "HE operation element" fields as
- * described in P802.11ax_D3.0 section 9.4.2.238
+ * described in P802.11ax_D4.0 section 9.4.2.243
*/
struct ieee80211_he_operation {
__le32 he_oper_params;
__le16 he_mcs_nss_set;
- /* Optional 0,1,3 or 4 bytes: depends on @he_oper_params */
+ /* Optional 0,1,3,4,5,7 or 8 bytes: depends on @he_oper_params */
u8 optional[0];
} __packed;

@@ -1632,7 +1632,7 @@ struct ieee80211_he_operation {
* struct ieee80211_he_mu_edca_param_ac_rec - MU AC Parameter Record field
*
* This structure is the "MU AC Parameter Record" fields as
- * described in P802.11ax_D2.0 section 9.4.2.240
+ * described in P802.11ax_D4.0 section 9.4.2.245
*/
struct ieee80211_he_mu_edca_param_ac_rec {
u8 aifsn;
@@ -1644,7 +1644,7 @@ struct ieee80211_he_mu_edca_param_ac_rec {
* struct ieee80211_mu_edca_param_set - MU EDCA Parameter Set element
*
* This structure is the "MU EDCA Parameter Set element" fields as
- * described in P802.11ax_D2.0 section 9.4.2.240
+ * described in P802.11ax_D4.0 section 9.4.2.245
*/
struct ieee80211_mu_edca_param_set {
u8 mu_qos_info;
@@ -2026,6 +2026,7 @@ ieee80211_he_ppe_size(u8 ppe_thres_hdr, const u8 *phy_cap_info)
#define IEEE80211_HE_OPERATION_VHT_OPER_INFO 0x00004000
#define IEEE80211_HE_OPERATION_CO_HOSTED_BSS 0x00008000
#define IEEE80211_HE_OPERATION_ER_SU_DISABLE 0x00010000
+#define IEEE80211_HE_OPERATION_6GHZ_OP_INFO 0x00020000
#define IEEE80211_HE_OPERATION_BSS_COLOR_MASK 0x3f000000
#define IEEE80211_HE_OPERATION_BSS_COLOR_OFFSET 24
#define IEEE80211_HE_OPERATION_PARTIAL_BSS_COLOR 0x40000000
@@ -2056,6 +2057,8 @@ ieee80211_he_oper_size(const u8 *he_oper_ie)
oper_len += 3;
if (he_oper_params & IEEE80211_HE_OPERATION_CO_HOSTED_BSS)
oper_len++;
+ if (he_oper_params & IEEE80211_HE_OPERATION_6GHZ_OP_INFO)
+ oper_len += 4;

/* Add the first byte (extension ID) to the total length */
oper_len++;
--
2.20.1


2019-03-18 10:56:22

by Arend Van Spriel

[permalink] [raw]
Subject: Re: [PATCH 05/11] mac80211_hwsim: set p2p device interface support indication

On 3/15/2019 4:39 PM, Luca Coelho wrote:
> From: Avraham Stern <[email protected]>
>
> P2P device interface type was not indicated in the supported
> interface types even when hwsim was configured with p2p device
> support. Fix it.

Just wondering. Doesn't this affect the hwsim-based tests in wpa_supp?
Or is that the intent behind this patch.

Regards,
Arend

> Signed-off-by: Avraham Stern <[email protected]>
> Signed-off-by: Luca Coelho <[email protected]>
> ---
> drivers/net/wireless/mac80211_hwsim.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
> index 0838af04d681..d79f3ee2a741 100644
> --- a/drivers/net/wireless/mac80211_hwsim.c
> +++ b/drivers/net/wireless/mac80211_hwsim.c
> @@ -3894,6 +3894,8 @@ static int __init init_mac80211_hwsim(void)
> param.p2p_device = support_p2p_device;
> param.use_chanctx = channels > 1;
> param.iftypes = HWSIM_IFTYPE_SUPPORT_MASK;
> + if (param.p2p_device)
> + param.iftypes |= BIT(NL80211_IFTYPE_P2P_DEVICE);
>
> err = mac80211_hwsim_new_radio(NULL, &param);
> if (err < 0)
>

2019-03-19 09:06:32

by Dan Carpenter

[permalink] [raw]
Subject: Re: [PATCH 09/11] cfg80211: support profile split between elements

Hi Luca,

Thank you for the patch! Perhaps something to improve:

url: https://github.com/0day-ci/linux/commits/Luca-Coelho/mac80211-Increase-MAX_MSG_LEN/20190316-083719
base: https://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git master

smatch warnings:
net/wireless/scan.c:1610 cfg80211_parse_mbssid_data() warn: should '1 << (mbssid_index_ie[2])' be a 64 bit type?

# https://github.com/0day-ci/linux/commit/e28e850d09f80732c1e9c04e0079c4e40f23ef7d
git remote add linux-review https://github.com/0day-ci/linux
git remote update linux-review
git checkout e28e850d09f80732c1e9c04e0079c4e40f23ef7d
vim +1610 net/wireless/scan.c

e28e850d Sara Sharon 2019-03-15 1530
0b8fb823 Peng Xu 2019-01-21 1531 static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
0b8fb823 Peng Xu 2019-01-21 1532 struct cfg80211_inform_bss *data,
0b8fb823 Peng Xu 2019-01-21 1533 enum cfg80211_bss_frame_type ftype,
0b8fb823 Peng Xu 2019-01-21 1534 const u8 *bssid, u64 tsf,
0b8fb823 Peng Xu 2019-01-21 1535 u16 beacon_interval, const u8 *ie,
0b8fb823 Peng Xu 2019-01-21 1536 size_t ielen,
0cd01efb Sara Sharon 2019-01-22 1537 struct cfg80211_non_tx_bss *non_tx_data,
0b8fb823 Peng Xu 2019-01-21 1538 gfp_t gfp)
0b8fb823 Peng Xu 2019-01-21 1539 {
1c8745f3 Johannes Berg 2019-02-07 1540 const u8 *mbssid_index_ie;
1c8745f3 Johannes Berg 2019-02-07 1541 const struct element *elem, *sub;
1c8745f3 Johannes Berg 2019-02-07 1542 size_t new_ie_len;
0b8fb823 Peng Xu 2019-01-21 1543 u8 new_bssid[ETH_ALEN];
e28e850d Sara Sharon 2019-03-15 1544 u8 *new_ie, *profile;
e28e850d Sara Sharon 2019-03-15 1545 u64 seen_indices = 0;
0b8fb823 Peng Xu 2019-01-21 1546 u16 capability;
0b8fb823 Peng Xu 2019-01-21 1547 struct cfg80211_bss *bss;
0b8fb823 Peng Xu 2019-01-21 1548
0cd01efb Sara Sharon 2019-01-22 1549 if (!non_tx_data)
0b8fb823 Peng Xu 2019-01-21 1550 return;
0b8fb823 Peng Xu 2019-01-21 1551 if (!cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ie, ielen))
0b8fb823 Peng Xu 2019-01-21 1552 return;
213ed579 Sara Sharon 2019-01-16 1553 if (!wiphy->support_mbssid)
213ed579 Sara Sharon 2019-01-16 1554 return;
213ed579 Sara Sharon 2019-01-16 1555 if (wiphy->support_only_he_mbssid &&
213ed579 Sara Sharon 2019-01-16 1556 !cfg80211_find_ext_ie(WLAN_EID_EXT_HE_CAPABILITY, ie, ielen))
213ed579 Sara Sharon 2019-01-16 1557 return;
0b8fb823 Peng Xu 2019-01-21 1558
0b8fb823 Peng Xu 2019-01-21 1559 new_ie = kmalloc(IEEE80211_MAX_DATA_LEN, gfp);
0b8fb823 Peng Xu 2019-01-21 1560 if (!new_ie)
0b8fb823 Peng Xu 2019-01-21 1561 return;
0b8fb823 Peng Xu 2019-01-21 1562
e28e850d Sara Sharon 2019-03-15 1563 profile = kmalloc(ielen, gfp);
e28e850d Sara Sharon 2019-03-15 1564 if (!profile)
e28e850d Sara Sharon 2019-03-15 1565 goto out;
e28e850d Sara Sharon 2019-03-15 1566
1c8745f3 Johannes Berg 2019-02-07 1567 for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, ie, ielen) {
1c8745f3 Johannes Berg 2019-02-07 1568 if (elem->datalen < 4)
1c8745f3 Johannes Berg 2019-02-07 1569 continue;
1c8745f3 Johannes Berg 2019-02-07 1570 for_each_element(sub, elem->data + 1, elem->datalen - 1) {
e28e850d Sara Sharon 2019-03-15 1571 u8 profile_len;
e28e850d Sara Sharon 2019-03-15 1572
1c8745f3 Johannes Berg 2019-02-07 1573 if (sub->id != 0 || sub->datalen < 4) {
0b8fb823 Peng Xu 2019-01-21 1574 /* not a valid BSS profile */
0b8fb823 Peng Xu 2019-01-21 1575 continue;
0b8fb823 Peng Xu 2019-01-21 1576 }
0b8fb823 Peng Xu 2019-01-21 1577
1c8745f3 Johannes Berg 2019-02-07 1578 if (sub->data[0] != WLAN_EID_NON_TX_BSSID_CAP ||
1c8745f3 Johannes Berg 2019-02-07 1579 sub->data[1] != 2) {
0b8fb823 Peng Xu 2019-01-21 1580 /* The first element within the Nontransmitted
0b8fb823 Peng Xu 2019-01-21 1581 * BSSID Profile is not the Nontransmitted
0b8fb823 Peng Xu 2019-01-21 1582 * BSSID Capability element.
0b8fb823 Peng Xu 2019-01-21 1583 */
0b8fb823 Peng Xu 2019-01-21 1584 continue;
0b8fb823 Peng Xu 2019-01-21 1585 }
0b8fb823 Peng Xu 2019-01-21 1586
e28e850d Sara Sharon 2019-03-15 1587 memset(profile, 0, ielen);
e28e850d Sara Sharon 2019-03-15 1588 profile_len = cfg80211_merge_profile(ie, ielen,
e28e850d Sara Sharon 2019-03-15 1589 elem,
e28e850d Sara Sharon 2019-03-15 1590 sub,
e28e850d Sara Sharon 2019-03-15 1591 &profile,
e28e850d Sara Sharon 2019-03-15 1592 ielen);
e28e850d Sara Sharon 2019-03-15 1593
0b8fb823 Peng Xu 2019-01-21 1594 /* found a Nontransmitted BSSID Profile */
0b8fb823 Peng Xu 2019-01-21 1595 mbssid_index_ie = cfg80211_find_ie
0b8fb823 Peng Xu 2019-01-21 1596 (WLAN_EID_MULTI_BSSID_IDX,
e28e850d Sara Sharon 2019-03-15 1597 profile, profile_len);
0b8fb823 Peng Xu 2019-01-21 1598 if (!mbssid_index_ie || mbssid_index_ie[1] < 1 ||
e28e850d Sara Sharon 2019-03-15 1599 mbssid_index_ie[2] == 0 ||
e28e850d Sara Sharon 2019-03-15 1600 mbssid_index_ie[2] > 46) {
0b8fb823 Peng Xu 2019-01-21 1601 /* No valid Multiple BSSID-Index element */
0b8fb823 Peng Xu 2019-01-21 1602 continue;
0b8fb823 Peng Xu 2019-01-21 1603 }
0b8fb823 Peng Xu 2019-01-21 1604
e28e850d Sara Sharon 2019-03-15 1605 if (seen_indices & BIT(mbssid_index_ie[2]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I should fix Smatch to generate a warning here as well...

e28e850d Sara Sharon 2019-03-15 1606 /* We don't support legacy split of a profile */
e28e850d Sara Sharon 2019-03-15 1607 net_dbg_ratelimited("Partial info for BSSID index %d\n",
e28e850d Sara Sharon 2019-03-15 1608 mbssid_index_ie[2]);
e28e850d Sara Sharon 2019-03-15 1609
e28e850d Sara Sharon 2019-03-15 @1610 seen_indices |= BIT(mbssid_index_ie[2]);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

e28e850d Sara Sharon 2019-03-15 1611
0cd01efb Sara Sharon 2019-01-22 1612 non_tx_data->bssid_index = mbssid_index_ie[2];
0cd01efb Sara Sharon 2019-01-22 1613 non_tx_data->max_bssid_indicator = elem->data[0];
0cd01efb Sara Sharon 2019-01-22 1614
0cd01efb Sara Sharon 2019-01-22 1615 cfg80211_gen_new_bssid(bssid,
0cd01efb Sara Sharon 2019-01-22 1616 non_tx_data->max_bssid_indicator,
0cd01efb Sara Sharon 2019-01-22 1617 non_tx_data->bssid_index,
0b8fb823 Peng Xu 2019-01-21 1618 new_bssid);
0b8fb823 Peng Xu 2019-01-21 1619 memset(new_ie, 0, IEEE80211_MAX_DATA_LEN);
e28e850d Sara Sharon 2019-03-15 1620 new_ie_len = cfg80211_gen_new_ie(ie, ielen,
e28e850d Sara Sharon 2019-03-15 1621 profile,
e28e850d Sara Sharon 2019-03-15 1622 profile_len, new_ie,
0b8fb823 Peng Xu 2019-01-21 1623 gfp);
0b8fb823 Peng Xu 2019-01-21 1624 if (!new_ie_len)
0b8fb823 Peng Xu 2019-01-21 1625 continue;
0b8fb823 Peng Xu 2019-01-21 1626
e28e850d Sara Sharon 2019-03-15 1627 capability = get_unaligned_le16(profile + 2);
0b8fb823 Peng Xu 2019-01-21 1628 bss = cfg80211_inform_single_bss_data(wiphy, data,
0b8fb823 Peng Xu 2019-01-21 1629 ftype,
0b8fb823 Peng Xu 2019-01-21 1630 new_bssid, tsf,
0b8fb823 Peng Xu 2019-01-21 1631 capability,
0b8fb823 Peng Xu 2019-01-21 1632 beacon_interval,
0b8fb823 Peng Xu 2019-01-21 1633 new_ie,
0b8fb823 Peng Xu 2019-01-21 1634 new_ie_len,
0cd01efb Sara Sharon 2019-01-22 1635 non_tx_data,
0cd01efb Sara Sharon 2019-01-22 1636 gfp);
0b8fb823 Peng Xu 2019-01-21 1637 if (!bss)
0b8fb823 Peng Xu 2019-01-21 1638 break;
0b8fb823 Peng Xu 2019-01-21 1639 cfg80211_put_bss(wiphy, bss);
0b8fb823 Peng Xu 2019-01-21 1640 }
0b8fb823 Peng Xu 2019-01-21 1641 }
0b8fb823 Peng Xu 2019-01-21 1642
e28e850d Sara Sharon 2019-03-15 1643 out:
0b8fb823 Peng Xu 2019-01-21 1644 kfree(new_ie);
e28e850d Sara Sharon 2019-03-15 1645 kfree(profile);
0b8fb823 Peng Xu 2019-01-21 1646 }
0b8fb823 Peng Xu 2019-01-21 1647

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation

2019-03-23 12:34:39

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 03/11] nl80211: copy the length of dst of src in nl80211_notify_radar_detection()

On Fri, 2019-03-15 at 17:38 +0200, Luca Coelho wrote:
> From: Luca Coelho <[email protected]>
>
> It is generally safer to copy the length of the destination instead of
> the length of the source, because if the sizes don't match, it's
> usually better to leak some data from the source than to write data
> out of bounds in the destination.
>
> Signed-off-by: Luca Coelho <[email protected]>
> ---
> net/wireless/nl80211.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
> index 25a9e3b5c154..239be0e2f9e1 100644
> --- a/net/wireless/nl80211.c
> +++ b/net/wireless/nl80211.c
> @@ -8061,7 +8061,7 @@ static int nl80211_notify_radar_detection(struct sk_buff *skb,
>
> cfg80211_sched_dfs_chan_update(rdev);
>
> - memcpy(&rdev->radar_chandef, &chandef, sizeof(chandef));
> + memcpy(&rdev->radar_chandef, &chandef, sizeof(rdev->radar_chandef));

I think we're better off doing a struct assignment here.

johannes


2019-03-26 04:26:50

by Chen, Rong A

[permalink] [raw]
Subject: [cfg80211] 83db2c9ebd: hwsim.scan_multi_bssid_check_ie.fail

FYI, we noticed the following commit (built with gcc-7):

commit: 83db2c9ebd071566d3b45e4860b9803dfc36d1ca ("[PATCH 06/11] cfg80211: don't skip multi-bssid index element")
url: https://github.com/0day-ci/linux/commits/Luca-Coelho/mac80211-Increase-MAX_MSG_LEN/20190316-083719
base: https://git.kernel.org/cgit/linux/kernel/git/jberg/mac80211-next.git master

in testcase: hwsim
with following parameters:

group: hwsim-12



on test machine: qemu-system-x86_64 -enable-kvm -cpu SandyBridge -smp 2 -m 4G

caused below changes (please refer to attached dmesg/kmsg for entire log/backtrace):


2019-03-25 02:31:59 ./run-tests.py scan_multi_bssid_check_ie
DEV: wlan0: 02:00:00:00:00:00
DEV: wlan1: 02:00:00:00:01:00
DEV: wlan2: 02:00:00:00:02:00
APDEV: wlan3
APDEV: wlan4
START scan_multi_bssid_check_ie 1/1
Test: Scan and check if nontransmitting BSS inherits IE from transmitting BSS
Starting AP wlan3
trans_bss beacon_ie: [0, 1, 3, 5, 71, 42, 45, 221, 50, 59, 61, 127]
nontrans_bss1 beacon_ie: [0, 1, 3, 5, 42, 45, 221, 50, 85, 59, 61, 127]
check IE failed
Traceback (most recent call last):
File "./run-tests.py", line 466, in main
t(dev, apdev)
File "/lkp/benchmarks/hwsim/tests/hwsim/test_scan.py", line 1703, in test_scan_multi_bssid_check_ie
raise Exception("check IE failed")
Exception: check IE failed
FAIL scan_multi_bssid_check_ie 0.671182 2019-03-25 02:32:01.152626
passed 0 test case(s)
skipped 0 test case(s)
failed tests: scan_multi_bssid_check_ie



To reproduce:

# build kernel
cd linux
cp config-5.0.0-rc7-02371-g83db2c9 .config
make HOSTCC=gcc-7 CC=gcc-7 ARCH=x86_64 olddefconfig
make HOSTCC=gcc-7 CC=gcc-7 ARCH=x86_64 prepare
make HOSTCC=gcc-7 CC=gcc-7 ARCH=x86_64 modules_prepare
make HOSTCC=gcc-7 CC=gcc-7 ARCH=x86_64 SHELL=/bin/bash
make HOSTCC=gcc-7 CC=gcc-7 ARCH=x86_64 bzImage


git clone https://github.com/intel/lkp-tests.git
cd lkp-tests
bin/lkp qemu -k <bzImage> job-script # job-script is attached in this email



Thanks,
Rong Chen


Attachments:
(No filename) (1.97 kB)
config-5.0.0-rc7-02371-g83db2c9 (187.26 kB)
job-script (4.75 kB)
dmesg.xz (124.32 kB)
hwsim (93.12 kB)
Download all attachments

2019-04-17 06:34:48

by Luca Coelho

[permalink] [raw]
Subject: [PATCH v2 03/11] nl80211: do a struct assignment to radar_chandef instead of memcpy()

From: Luca Coelho <[email protected]>

We are copying one entire structure to another of the same type in
nl80211_notify_radar_detection, so it's simpler and safer to do a
struct assignment instead of memcpy().

Signed-off-by: Luca Coelho <[email protected]>
---
net/wireless/nl80211.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 846d25d2dc82..64af8309f397 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -8182,7 +8182,7 @@ static int nl80211_notify_radar_detection(struct sk_buff *skb,

cfg80211_sched_dfs_chan_update(rdev);

- memcpy(&rdev->radar_chandef, &chandef, sizeof(chandef));
+ rdev->radar_chandef = chandef;

/* Propagate this notification to other radios as well */
queue_work(cfg80211_wq, &rdev->propagate_radar_detect_wk);
--
2.20.1