2013-03-27 13:40:02

by Johannes Berg

[permalink] [raw]
Subject: [PATCH 0/4] mac80211: IE parsing cleanups

Remove some unused but parsed IEs, move length checks to make
the parser struct smaller and use a struct for the TIE.

johannes



2013-03-27 13:40:05

by Johannes Berg

[permalink] [raw]
Subject: [PATCH 3/4] mac80211: check ERP info IE length in parser

From: Johannes Berg <[email protected]>

It's always just one byte, so check for that and
remove the length field from the parser struct.

Signed-off-by: Johannes Berg <[email protected]>
---
net/mac80211/ieee80211_i.h | 1 -
net/mac80211/mlme.c | 2 +-
net/mac80211/scan.c | 5 ++---
net/mac80211/util.c | 6 ++++--
4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index bf020d0..eb364f3 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1192,7 +1192,6 @@ struct ieee802_11_elems {
u8 tim_len;
u8 challenge_len;
u8 rsn_len;
- u8 erp_info_len;
u8 ext_supp_rates_len;
u8 wmm_info_len;
u8 wmm_param_len;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 7208612..c6d87bc4 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3106,7 +3106,7 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
changed |= BSS_CHANGED_DTIM_PERIOD;
}

- if (elems.erp_info && elems.erp_info_len >= 1) {
+ if (elems.erp_info) {
erp_valid = true;
erp_value = elems.erp_info[0];
} else {
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 581764f..33fbf10 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -98,9 +98,8 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
}

/* save the ERP value so that it is available at association time */
- if (elems->erp_info && elems->erp_info_len >= 1 &&
- (!elems->parse_error ||
- !(bss->valid_data & IEEE80211_BSS_VALID_ERP))) {
+ if (elems->erp_info && (!elems->parse_error ||
+ !(bss->valid_data & IEEE80211_BSS_VALID_ERP))) {
bss->erp_value = elems->erp_info[0];
bss->has_erp_value = true;
if (!elems->parse_error)
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 9d7664f..739ae33 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -782,8 +782,10 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
elems->rsn_len = elen;
break;
case WLAN_EID_ERP_INFO:
- elems->erp_info = pos;
- elems->erp_info_len = elen;
+ if (elen >= 1)
+ elems->erp_info = pos;
+ else
+ elem_parse_failed = true;
break;
case WLAN_EID_EXT_SUPP_RATES:
elems->ext_supp_rates = pos;
--
1.8.0


2013-03-28 15:47:32

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 0/4] mac80211: IE parsing cleanups

On Wed, 2013-03-27 at 14:39 +0100, Johannes Berg wrote:
> Remove some unused but parsed IEs, move length checks to make
> the parser struct smaller and use a struct for the TIE.

Applied.

johannes


2013-03-27 13:40:04

by Johannes Berg

[permalink] [raw]
Subject: [PATCH 2/4] mac80211: check DSSS params IE length in parser

From: Johannes Berg <[email protected]>

It's always just one byte, so check for that and
remove the length field from the parser struct.

Signed-off-by: Johannes Berg <[email protected]>
---
net/mac80211/ibss.c | 2 +-
net/mac80211/ieee80211_i.h | 1 -
net/mac80211/mesh.c | 2 +-
net/mac80211/mlme.c | 2 +-
net/mac80211/util.c | 6 ++++--
5 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 5ab32e2..2a0b218 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -463,7 +463,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
bool rates_updated = false;

- if (elems->ds_params && elems->ds_params_len == 1)
+ if (elems->ds_params)
freq = ieee80211_channel_to_frequency(elems->ds_params[0],
band);
else
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 207b4f3..bf020d0 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1189,7 +1189,6 @@ struct ieee802_11_elems {
/* length of them, respectively */
u8 ssid_len;
u8 supp_rates_len;
- u8 ds_params_len;
u8 tim_len;
u8 challenge_len;
u8 rsn_len;
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index aead541..0acc287 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -907,7 +907,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
(!elems.rsn && sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE))
return;

- if (elems.ds_params && elems.ds_params_len == 1)
+ if (elems.ds_params)
freq = ieee80211_channel_to_frequency(elems.ds_params[0], band);
else
freq = rx_status->freq;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index c98a26d..7208612 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2764,7 +2764,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
}
}

- if (elems->ds_params && elems->ds_params_len == 1)
+ if (elems->ds_params)
freq = ieee80211_channel_to_frequency(elems->ds_params[0],
rx_status->band);
else
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 83e213b..9d7664f 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -741,8 +741,10 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
elems->supp_rates_len = elen;
break;
case WLAN_EID_DS_PARAMS:
- elems->ds_params = pos;
- elems->ds_params_len = elen;
+ if (elen >= 1)
+ elems->ds_params = pos;
+ else
+ elem_parse_failed = true;
break;
case WLAN_EID_TIM:
if (elen >= sizeof(struct ieee80211_tim_ie)) {
--
1.8.0


2013-03-27 13:40:04

by Johannes Berg

[permalink] [raw]
Subject: [PATCH 1/4] mac80211: remove unused IE pointers from parser

From: Johannes Berg <[email protected]>

There's no need to parse IEs that aren't used
so just remove them.

Signed-off-by: Johannes Berg <[email protected]>
---
net/mac80211/ieee80211_i.h | 9 ---------
net/mac80211/util.c | 19 -------------------
2 files changed, 28 deletions(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 3cf89f7..207b4f3 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1157,11 +1157,8 @@ struct ieee802_11_elems {
/* pointers to IEs */
const u8 *ssid;
const u8 *supp_rates;
- const u8 *fh_params;
const u8 *ds_params;
- const u8 *cf_params;
const struct ieee80211_tim_ie *tim;
- const u8 *ibss_params;
const u8 *challenge;
const u8 *rsn;
const u8 *erp_info;
@@ -1185,7 +1182,6 @@ struct ieee802_11_elems {
const struct ieee80211_wide_bw_chansw_ie *wide_bw_chansw_ie;
const u8 *country_elem;
const u8 *pwr_constr_elem;
- const u8 *quiet_elem; /* first quite element */
const u8 *timeout_int;
const u8 *opmode_notif;
const struct ieee80211_sec_chan_offs_ie *sec_chan_offs;
@@ -1193,11 +1189,8 @@ struct ieee802_11_elems {
/* length of them, respectively */
u8 ssid_len;
u8 supp_rates_len;
- u8 fh_params_len;
u8 ds_params_len;
- u8 cf_params_len;
u8 tim_len;
- u8 ibss_params_len;
u8 challenge_len;
u8 rsn_len;
u8 erp_info_len;
@@ -1210,8 +1203,6 @@ struct ieee802_11_elems {
u8 prep_len;
u8 perr_len;
u8 country_elem_len;
- u8 quiet_elem_len;
- u8 num_of_quiet_elem; /* can be more the one */
u8 timeout_int_len;

/* whether a parse error occurred while retrieving these elements */
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index d253bf4..83e213b 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -740,18 +740,10 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
elems->supp_rates = pos;
elems->supp_rates_len = elen;
break;
- case WLAN_EID_FH_PARAMS:
- elems->fh_params = pos;
- elems->fh_params_len = elen;
- break;
case WLAN_EID_DS_PARAMS:
elems->ds_params = pos;
elems->ds_params_len = elen;
break;
- case WLAN_EID_CF_PARAMS:
- elems->cf_params = pos;
- elems->cf_params_len = elen;
- break;
case WLAN_EID_TIM:
if (elen >= sizeof(struct ieee80211_tim_ie)) {
elems->tim = (void *)pos;
@@ -759,10 +751,6 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
} else
elem_parse_failed = true;
break;
- case WLAN_EID_IBSS_PARAMS:
- elems->ibss_params = pos;
- elems->ibss_params_len = elen;
- break;
case WLAN_EID_CHALLENGE:
elems->challenge = pos;
elems->challenge_len = elen;
@@ -893,13 +881,6 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
}
elems->wide_bw_chansw_ie = (void *)pos;
break;
- case WLAN_EID_QUIET:
- if (!elems->quiet_elem) {
- elems->quiet_elem = pos;
- elems->quiet_elem_len = elen;
- }
- elems->num_of_quiet_elem++;
- break;
case WLAN_EID_COUNTRY:
elems->country_elem = pos;
elems->country_elem_len = elen;
--
1.8.0


2013-03-27 13:40:07

by Johannes Berg

[permalink] [raw]
Subject: [PATCH 4/4] mac80211: parse Timeout Interval Element using a struct

From: Johannes Berg <[email protected]>

Instead of open-coding the accesses and length check do
the length check in the IE parser and assign a struct
pointer for use in the remaining code.

Signed-off-by: Johannes Berg <[email protected]>
---
include/linux/ieee80211.h | 10 ++++++++++
net/mac80211/ieee80211_i.h | 3 +--
net/mac80211/mlme.c | 6 +++---
net/mac80211/util.c | 6 ++++--
4 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index db1b3a6..b25c987 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1991,6 +1991,16 @@ enum ieee80211_timeout_interval_type {
WLAN_TIMEOUT_ASSOC_COMEBACK = 3 /* 802.11w */,
};

+/**
+ * struct ieee80211_timeout_interval_ie - Timeout Interval element
+ * @type: type, see &enum ieee80211_timeout_interval_type
+ * @value: timeout interval value
+ */
+struct ieee80211_timeout_interval_ie {
+ u8 type;
+ __le32 value;
+} __packed;
+
/* BACK action code */
enum ieee80211_back_actioncode {
WLAN_ACTION_ADDBA_REQ = 0,
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index eb364f3..71fb97d 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1182,7 +1182,7 @@ struct ieee802_11_elems {
const struct ieee80211_wide_bw_chansw_ie *wide_bw_chansw_ie;
const u8 *country_elem;
const u8 *pwr_constr_elem;
- const u8 *timeout_int;
+ const struct ieee80211_timeout_interval_ie *timeout_int;
const u8 *opmode_notif;
const struct ieee80211_sec_chan_offs_ie *sec_chan_offs;

@@ -1201,7 +1201,6 @@ struct ieee802_11_elems {
u8 prep_len;
u8 perr_len;
u8 country_elem_len;
- u8 timeout_int_len;

/* whether a parse error occurred while retrieving these elements */
bool parse_error;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index c6d87bc4..00cee31 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2696,10 +2696,10 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);

if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY &&
- elems.timeout_int && elems.timeout_int_len == 5 &&
- elems.timeout_int[0] == WLAN_TIMEOUT_ASSOC_COMEBACK) {
+ elems.timeout_int &&
+ elems.timeout_int->type == WLAN_TIMEOUT_ASSOC_COMEBACK) {
u32 tu, ms;
- tu = get_unaligned_le32(elems.timeout_int + 1);
+ tu = le32_to_cpu(elems.timeout_int->value);
ms = tu * 1024 / 1000;
sdata_info(sdata,
"%pM rejected association temporarily; comeback duration %u TU (%u ms)\n",
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 739ae33..e9107d9 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -897,8 +897,10 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
elems->pwr_constr_elem = pos;
break;
case WLAN_EID_TIMEOUT_INTERVAL:
- elems->timeout_int = pos;
- elems->timeout_int_len = elen;
+ if (elen >= sizeof(struct ieee80211_timeout_interval_ie))
+ elems->timeout_int = (void *)pos;
+ else
+ elem_parse_failed = true;
break;
default:
break;
--
1.8.0