aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-08-01 10:13:02 -0400
committerJohannes Berg <johannes.berg@intel.com>2012-08-20 07:57:50 -0400
commit5bc1420b11903e9f8c470d3b33061b8de0c5c005 (patch)
tree5fa942edea59ad047aa58f9d84c6259cd3b4f314 /net
parent3049000b97bbfc90aa9ba413eadc4007e5bce2e0 (diff)
mac80211: check size of channel switch IE when parsing
The channel switch IE has a fixed size, so we can discard it in parsing if it's not the right size and use the right struct pointer. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/ieee80211_i.h3
-rw-r--r--net/mac80211/mlme.c10
-rw-r--r--net/mac80211/util.c7
3 files changed, 9 insertions, 11 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index e22aee83ba53..793f03e15191 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1136,7 +1136,7 @@ struct ieee802_11_elems {
1136 u8 *prep; 1136 u8 *prep;
1137 u8 *perr; 1137 u8 *perr;
1138 struct ieee80211_rann_ie *rann; 1138 struct ieee80211_rann_ie *rann;
1139 u8 *ch_switch_elem; 1139 struct ieee80211_channel_sw_ie *ch_switch_ie;
1140 u8 *country_elem; 1140 u8 *country_elem;
1141 u8 *pwr_constr_elem; 1141 u8 *pwr_constr_elem;
1142 u8 *quiet_elem; /* first quite element */ 1142 u8 *quiet_elem; /* first quite element */
@@ -1162,7 +1162,6 @@ struct ieee802_11_elems {
1162 u8 preq_len; 1162 u8 preq_len;
1163 u8 prep_len; 1163 u8 prep_len;
1164 u8 perr_len; 1164 u8 perr_len;
1165 u8 ch_switch_elem_len;
1166 u8 country_elem_len; 1165 u8 country_elem_len;
1167 u8 pwr_constr_elem_len; 1166 u8 pwr_constr_elem_len;
1168 u8 quiet_elem_len; 1167 u8 quiet_elem_len;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 9e61fe127a33..b9cb8dbe34d9 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2267,14 +2267,10 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2267 mutex_unlock(&local->iflist_mtx); 2267 mutex_unlock(&local->iflist_mtx);
2268 } 2268 }
2269 2269
2270 if (elems->ch_switch_elem && (elems->ch_switch_elem_len == 3) && 2270 if (elems->ch_switch_ie &&
2271 (memcmp(mgmt->bssid, sdata->u.mgd.associated->bssid, 2271 memcmp(mgmt->bssid, sdata->u.mgd.associated->bssid, ETH_ALEN) == 0)
2272 ETH_ALEN) == 0)) { 2272 ieee80211_sta_process_chanswitch(sdata, elems->ch_switch_ie,
2273 struct ieee80211_channel_sw_ie *sw_elem =
2274 (struct ieee80211_channel_sw_ie *)elems->ch_switch_elem;
2275 ieee80211_sta_process_chanswitch(sdata, sw_elem,
2276 bss, rx_status->mactime); 2273 bss, rx_status->mactime);
2277 }
2278} 2274}
2279 2275
2280 2276
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 99e4258bdb26..7dff94e43a0c 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -768,8 +768,11 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
768 elem_parse_failed = true; 768 elem_parse_failed = true;
769 break; 769 break;
770 case WLAN_EID_CHANNEL_SWITCH: 770 case WLAN_EID_CHANNEL_SWITCH:
771 elems->ch_switch_elem = pos; 771 if (elen != sizeof(struct ieee80211_channel_sw_ie)) {
772 elems->ch_switch_elem_len = elen; 772 elem_parse_failed = true;
773 break;
774 }
775 elems->ch_switch_ie = (void *)pos;
773 break; 776 break;
774 case WLAN_EID_QUIET: 777 case WLAN_EID_QUIET:
775 if (!elems->quiet_elem) { 778 if (!elems->quiet_elem) {