From 963a1852fbac4f75a2d938fa2e734ef1e6d4c044 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 21 Feb 2014 20:34:34 +0100 Subject: mac80211: don't validate unchanged AP bandwidth while tracking The MLME code in mac80211 must track whether or not the AP changed bandwidth, but if there's no change while tracking it shouldn't do anything, otherwise regulatory updates can make it impossible to connect to certain APs if the regulatory database doesn't match the information from the AP. See the precise scenario described in the code. This still leaves some possible problems with CSA or if the AP actually changed bandwidth, but those cases are less common and won't completely prevent using it. This fixes https://bugzilla.kernel.org/show_bug.cgi?id=70881 Cc: stable@vger.kernel.org Reported-and-tested-by: Nate Carlson Signed-off-by: Johannes Berg --- net/mac80211/mlme.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'net') diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 57d5482b10fa..c415f00cd6b6 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -271,6 +271,28 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata, ret = 0; out: + /* + * When tracking the current AP, don't do any further checks if the + * new chandef is identical to the one we're currently using for the + * connection. This keeps us from playing ping-pong with regulatory, + * without it the following can happen (for example): + * - connect to an AP with 80 MHz, world regdom allows 80 MHz + * - AP advertises regdom US + * - CRDA loads regdom US with 80 MHz prohibited (old database) + * - the code below detects an unsupported channel, downgrades, and + * we disconnect from the AP in the caller + * - disconnect causes CRDA to reload world regdomain and the game + * starts anew. + * (see https://bugzilla.kernel.org/show_bug.cgi?id=70881) + * + * It seems possible that there are still scenarios with CSA or real + * bandwidth changes where a this could happen, but those cases are + * less common and wouldn't completely prevent using the AP. + */ + if (tracking && + cfg80211_chandef_identical(chandef, &sdata->vif.bss_conf.chandef)) + return ret; + /* don't print the message below for VHT mismatch if VHT is disabled */ if (ret & IEEE80211_STA_DISABLE_VHT) vht_chandef = *chandef; -- cgit v1.2.3 From 092008abeed1e4168c08826262695ea67657e1aa Mon Sep 17 00:00:00 2001 From: Janusz Dziedzic Date: Fri, 14 Feb 2014 08:54:00 +0100 Subject: cfg80211: regulatory: reset regdomain in case of error Reset regdomain to world regdomain in case of errors in set_regdom() function. This will fix a problem with such scenario: - iw reg set US - iw reg set 00 - iw reg set US The last step always fail and we get deadlock in kernel regulatory code. Next setting new regulatory wasn't possible due to: Pending regulatory request, waiting for it to be processed... Signed-off-by: Janusz Dziedzic Acked-by: Luis R. Rodriguez Signed-off-by: Johannes Berg --- net/wireless/reg.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 4c50c21d6f52..f0541370e68e 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -2373,6 +2373,7 @@ static int reg_set_rd_country_ie(const struct ieee80211_regdomain *rd, int set_regdom(const struct ieee80211_regdomain *rd) { struct regulatory_request *lr; + bool user_reset = false; int r; if (!reg_is_valid_request(rd->alpha2)) { @@ -2389,6 +2390,7 @@ int set_regdom(const struct ieee80211_regdomain *rd) break; case NL80211_REGDOM_SET_BY_USER: r = reg_set_rd_user(rd, lr); + user_reset = true; break; case NL80211_REGDOM_SET_BY_DRIVER: r = reg_set_rd_driver(rd, lr); @@ -2402,8 +2404,14 @@ int set_regdom(const struct ieee80211_regdomain *rd) } if (r) { - if (r == -EALREADY) + switch (r) { + case -EALREADY: reg_set_request_processed(); + break; + default: + /* Back to world regulatory in case of errors */ + restore_regulatory_settings(user_reset); + } kfree(rd); return r; -- cgit v1.2.3 From cb664981607a6b5b3d670ad57bbda893b2528d96 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 27 Feb 2014 20:47:53 +0100 Subject: mac80211: fix association to 20/40 MHz VHT networks When a VHT network uses 20 or 40 MHz as per the HT operation information, the channel center frequency segment 0 field in the VHT operation information is reserved, so ignore it. This fixes association with such networks when the AP puts 0 into the field, previously we'd disconnect due to an invalid channel with the message wlan0: AP VHT information is invalid, disable VHT Cc: stable@vger.kernel.org Fixes: f2d9d270c15ae ("mac80211: support VHT association") Reported-by: Tim Nelson Signed-off-by: Johannes Berg --- net/mac80211/mlme.c | 1 + 1 file changed, 1 insertion(+) (limited to 'net') diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index c415f00cd6b6..245dce969b31 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -222,6 +222,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata, switch (vht_oper->chan_width) { case IEEE80211_VHT_CHANWIDTH_USE_HT: vht_chandef.width = chandef->width; + vht_chandef.center_freq1 = chandef->center_freq1; break; case IEEE80211_VHT_CHANWIDTH_80MHZ: vht_chandef.width = NL80211_CHAN_WIDTH_80; -- cgit v1.2.3