Skip to content

Commit c5549ee

Browse files
committed
Merge tag 'mac80211-for-davem-2017-06-13' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211
Johannes Berg says: ==================== Some fixes: * Avi fixes some fallout from my mac80211 RX flags changes * Emmanuel fixes an issue with adhering to the spec, and an oversight in the SMPS management code * Jason's patch makes mac80211 use constant-time memory comparisons for message authentication, to avoid having potentially observable timing differences * my fix makes mac80211 set the basic rates bitmap before the channel so the next update to the driver has more consistent data - this required another rework patch to remove some useless 5/10 MHz code that can never be hit ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents ace17c3 + b3dd827 commit c5549ee

File tree

5 files changed

+44
-37
lines changed

5 files changed

+44
-37
lines changed

net/mac80211/cfg.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,8 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
902902
default:
903903
return -EINVAL;
904904
}
905+
sdata->u.ap.req_smps = sdata->smps_mode;
906+
905907
sdata->needed_rx_chains = sdata->local->rx_chains;
906908

907909
sdata->vif.bss_conf.beacon_int = params->beacon_interval;

net/mac80211/ieee80211_i.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1531,7 +1531,7 @@ ieee80211_have_rx_timestamp(struct ieee80211_rx_status *status)
15311531
return true;
15321532
/* can't handle non-legacy preamble yet */
15331533
if (status->flag & RX_FLAG_MACTIME_PLCP_START &&
1534-
status->encoding != RX_ENC_LEGACY)
1534+
status->encoding == RX_ENC_LEGACY)
15351535
return true;
15361536
return false;
15371537
}

net/mac80211/mlme.c

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
601601
struct ieee80211_supported_band *sband;
602602
struct ieee80211_chanctx_conf *chanctx_conf;
603603
struct ieee80211_channel *chan;
604-
u32 rate_flags, rates = 0;
604+
u32 rates = 0;
605605

606606
sdata_assert_lock(sdata);
607607

@@ -612,7 +612,6 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
612612
return;
613613
}
614614
chan = chanctx_conf->def.chan;
615-
rate_flags = ieee80211_chandef_rate_flags(&chanctx_conf->def);
616615
rcu_read_unlock();
617616
sband = local->hw.wiphy->bands[chan->band];
618617
shift = ieee80211_vif_get_shift(&sdata->vif);
@@ -636,9 +635,6 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
636635
*/
637636
rates_len = 0;
638637
for (i = 0; i < sband->n_bitrates; i++) {
639-
if ((rate_flags & sband->bitrates[i].flags)
640-
!= rate_flags)
641-
continue;
642638
rates |= BIT(i);
643639
rates_len++;
644640
}
@@ -2818,7 +2814,7 @@ static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
28182814
u32 *rates, u32 *basic_rates,
28192815
bool *have_higher_than_11mbit,
28202816
int *min_rate, int *min_rate_index,
2821-
int shift, u32 rate_flags)
2817+
int shift)
28222818
{
28232819
int i, j;
28242820

@@ -2846,8 +2842,6 @@ static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
28462842
int brate;
28472843

28482844
br = &sband->bitrates[j];
2849-
if ((rate_flags & br->flags) != rate_flags)
2850-
continue;
28512845

28522846
brate = DIV_ROUND_UP(br->bitrate, (1 << shift) * 5);
28532847
if (brate == rate) {
@@ -4398,40 +4392,32 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
43984392
return -ENOMEM;
43994393
}
44004394

4401-
if (new_sta || override) {
4402-
err = ieee80211_prep_channel(sdata, cbss);
4403-
if (err) {
4404-
if (new_sta)
4405-
sta_info_free(local, new_sta);
4406-
return -EINVAL;
4407-
}
4408-
}
4409-
4395+
/*
4396+
* Set up the information for the new channel before setting the
4397+
* new channel. We can't - completely race-free - change the basic
4398+
* rates bitmap and the channel (sband) that it refers to, but if
4399+
* we set it up before we at least avoid calling into the driver's
4400+
* bss_info_changed() method with invalid information (since we do
4401+
* call that from changing the channel - only for IDLE and perhaps
4402+
* some others, but ...).
4403+
*
4404+
* So to avoid that, just set up all the new information before the
4405+
* channel, but tell the driver to apply it only afterwards, since
4406+
* it might need the new channel for that.
4407+
*/
44104408
if (new_sta) {
44114409
u32 rates = 0, basic_rates = 0;
44124410
bool have_higher_than_11mbit;
44134411
int min_rate = INT_MAX, min_rate_index = -1;
4414-
struct ieee80211_chanctx_conf *chanctx_conf;
44154412
const struct cfg80211_bss_ies *ies;
44164413
int shift = ieee80211_vif_get_shift(&sdata->vif);
4417-
u32 rate_flags;
4418-
4419-
rcu_read_lock();
4420-
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
4421-
if (WARN_ON(!chanctx_conf)) {
4422-
rcu_read_unlock();
4423-
sta_info_free(local, new_sta);
4424-
return -EINVAL;
4425-
}
4426-
rate_flags = ieee80211_chandef_rate_flags(&chanctx_conf->def);
4427-
rcu_read_unlock();
44284414

44294415
ieee80211_get_rates(sband, bss->supp_rates,
44304416
bss->supp_rates_len,
44314417
&rates, &basic_rates,
44324418
&have_higher_than_11mbit,
44334419
&min_rate, &min_rate_index,
4434-
shift, rate_flags);
4420+
shift);
44354421

44364422
/*
44374423
* This used to be a workaround for basic rates missing
@@ -4489,8 +4475,22 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
44894475
sdata->vif.bss_conf.sync_dtim_count = 0;
44904476
}
44914477
rcu_read_unlock();
4478+
}
44924479

4493-
/* tell driver about BSSID, basic rates and timing */
4480+
if (new_sta || override) {
4481+
err = ieee80211_prep_channel(sdata, cbss);
4482+
if (err) {
4483+
if (new_sta)
4484+
sta_info_free(local, new_sta);
4485+
return -EINVAL;
4486+
}
4487+
}
4488+
4489+
if (new_sta) {
4490+
/*
4491+
* tell driver about BSSID, basic rates and timing
4492+
* this was set up above, before setting the channel
4493+
*/
44944494
ieee80211_bss_info_change_notify(sdata,
44954495
BSS_CHANGED_BSSID | BSS_CHANGED_BASIC_RATES |
44964496
BSS_CHANGED_BEACON_INT);

net/mac80211/rx.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1613,12 +1613,16 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
16131613
*/
16141614
if (!ieee80211_hw_check(&sta->local->hw, AP_LINK_PS) &&
16151615
!ieee80211_has_morefrags(hdr->frame_control) &&
1616+
!ieee80211_is_back_req(hdr->frame_control) &&
16161617
!(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) &&
16171618
(rx->sdata->vif.type == NL80211_IFTYPE_AP ||
16181619
rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) &&
1619-
/* PM bit is only checked in frames where it isn't reserved,
1620+
/*
1621+
* PM bit is only checked in frames where it isn't reserved,
16201622
* in AP mode it's reserved in non-bufferable management frames
16211623
* (cf. IEEE 802.11-2012 8.2.4.1.7 Power Management field)
1624+
* BAR frames should be ignored as specified in
1625+
* IEEE 802.11-2012 10.2.1.2.
16221626
*/
16231627
(!ieee80211_is_mgmt(hdr->frame_control) ||
16241628
ieee80211_is_bufferable_mmpdu(hdr->frame_control))) {

net/mac80211/wpa.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <asm/unaligned.h>
1818
#include <net/mac80211.h>
1919
#include <crypto/aes.h>
20+
#include <crypto/algapi.h>
2021

2122
#include "ieee80211_i.h"
2223
#include "michael.h"
@@ -153,7 +154,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
153154
data_len = skb->len - hdrlen - MICHAEL_MIC_LEN;
154155
key = &rx->key->conf.key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY];
155156
michael_mic(key, hdr, data, data_len, mic);
156-
if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0)
157+
if (crypto_memneq(mic, data + data_len, MICHAEL_MIC_LEN))
157158
goto mic_fail;
158159

159160
/* remove Michael MIC from payload */
@@ -1048,7 +1049,7 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx)
10481049
bip_aad(skb, aad);
10491050
ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad,
10501051
skb->data + 24, skb->len - 24, mic);
1051-
if (memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) {
1052+
if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) {
10521053
key->u.aes_cmac.icverrors++;
10531054
return RX_DROP_UNUSABLE;
10541055
}
@@ -1098,7 +1099,7 @@ ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx)
10981099
bip_aad(skb, aad);
10991100
ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad,
11001101
skb->data + 24, skb->len - 24, mic);
1101-
if (memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) {
1102+
if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) {
11021103
key->u.aes_cmac.icverrors++;
11031104
return RX_DROP_UNUSABLE;
11041105
}
@@ -1202,7 +1203,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct ieee80211_rx_data *rx)
12021203
if (ieee80211_aes_gmac(key->u.aes_gmac.tfm, aad, nonce,
12031204
skb->data + 24, skb->len - 24,
12041205
mic) < 0 ||
1205-
memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) {
1206+
crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) {
12061207
key->u.aes_gmac.icverrors++;
12071208
return RX_DROP_UNUSABLE;
12081209
}

0 commit comments

Comments
 (0)