Various fixes across the tree, the shortlog basically says it all:

cfg80211: fix cfg80211_beacon_dup
   -> old bug in this code
 
   cfg80211: clear wep keys after disconnection
   -> certain ways of disconnecting left the keys
 
   mac80211: round IEEE80211_TX_STATUS_HEADROOM up to multiple of 4
   -> alignment issues with using 14 bytes
 
   mac80211: Do not disconnect on invalid operating class
   -> if the AP has a bogus operating class, let it be
 
   mac80211: Fix sending ADDBA response for an ongoing session
   -> don't send the same frame twice
 
   cfg80211: use only 1Mbps for basic rates in mesh
   -> interop issue with old versions of our code
 
   mac80211_hwsim: don't use WQ_MEM_RECLAIM
   -> it causes splats because it flushes work on a non-reclaim WQ
 
   regulatory: add NUL to request alpha2
   -> nla_put_string() issue from Kees
 
   mac80211: mesh: fix wrong mesh TTL offset calculation
   -> protocol issue
 
   mac80211: fix a possible leak of station stats
   -> error path might leak memory
 
   mac80211: fix calling sleeping function in atomic context
   -> percpu allocations need to be made with gfp flags
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEH1e1rEeCd0AIMq6MB8qZga/fl8QFAlqPIu8ACgkQB8qZga/f
 l8R6ww/+NWuu2T3rXSqfp0hDI/CYCwpMV12wsD/4BGC+6idZBicwLVwNyey7Frzh
 IUb8vpuUR0+gvacY9ogSsBGBlU/IjydJWGpXiXIlruB/WNdMTHor9LZHr8dH2jDn
 m8rYwzOdpnp73IvME3krtvLv24NrJmOjBlkGTZ236403yRtYqX5k/bn/AriYSqMm
 bGbXTM9acs3WTygvR8KwCpOPjuosw3VL/54nu52MIegkORAHKA7SOm6O8PCjaG2Q
 4pRopztpvGAIQOe+VzYt8n47uW2a8g6FGQnRZOusAzf98xZLgfTBric5y5Vtf4j4
 WiSFnECCugoC0se8op5C5OgPmPEK7cN0j22PrJ0wJzd8cFuZSnw+MoHQuvvaH3WF
 4DtLNOs9uWyNqN3PJES6hhQJi1WXMKAV2GNOLsp/P2jmZya/TrHFiBH8nIAGqJhj
 3rARKmamI1qMUBs62fQfpXl+iOzLzKNIy6RzDr81Rh3Jhavx/xR7uJKIyy4xwQc0
 NfvBABT21WwI6+KC7EEyOqbti+Ldee3hd0fKift4Uww9j+P7c8UXTrWeGlq31M+v
 QSX8YstmBcDAk/llAwK/nM+9t1gXLBS9ZDv2M+ag7be0wZIORDlehsMBE987T3AB
 UrPgpxCM8Yrk10yHbpaq3sstZo9xWLGzrwhAUFIw2WzbWFDrd8A=
 =kwiY
 -----END PGP SIGNATURE-----

Merge tag 'mac80211-for-davem-2018-02-22' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211

Johannes Berg says:

====================
Various fixes across the tree, the shortlog basically says it all:

  cfg80211: fix cfg80211_beacon_dup
  -> old bug in this code

  cfg80211: clear wep keys after disconnection
  -> certain ways of disconnecting left the keys

  mac80211: round IEEE80211_TX_STATUS_HEADROOM up to multiple of 4
  -> alignment issues with using 14 bytes

  mac80211: Do not disconnect on invalid operating class
  -> if the AP has a bogus operating class, let it be

  mac80211: Fix sending ADDBA response for an ongoing session
  -> don't send the same frame twice

  cfg80211: use only 1Mbps for basic rates in mesh
  -> interop issue with old versions of our code

  mac80211_hwsim: don't use WQ_MEM_RECLAIM
  -> it causes splats because it flushes work on a non-reclaim WQ

  regulatory: add NUL to request alpha2
  -> nla_put_string() issue from Kees

  mac80211: mesh: fix wrong mesh TTL offset calculation
  -> protocol issue

  mac80211: fix a possible leak of station stats
  -> error path might leak memory

  mac80211: fix calling sleeping function in atomic context
  -> percpu allocations need to be made with gfp flags
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2018-02-22 15:17:01 -05:00
commit ed04c46d4e
11 changed files with 41 additions and 27 deletions

View File

@ -3516,7 +3516,7 @@ static int __init init_mac80211_hwsim(void)
spin_lock_init(&hwsim_radio_lock); spin_lock_init(&hwsim_radio_lock);
hwsim_wq = alloc_workqueue("hwsim_wq",WQ_MEM_RECLAIM,0); hwsim_wq = alloc_workqueue("hwsim_wq", 0, 0);
if (!hwsim_wq) if (!hwsim_wq)
return -ENOMEM; return -ENOMEM;
rhashtable_init(&hwsim_radios_rht, &hwsim_rht_params); rhashtable_init(&hwsim_radios_rht, &hwsim_rht_params);

View File

@ -4149,7 +4149,7 @@ void ieee80211_sta_uapsd_trigger(struct ieee80211_sta *sta, u8 tid);
* The TX headroom reserved by mac80211 for its own tx_status functions. * The TX headroom reserved by mac80211 for its own tx_status functions.
* This is enough for the radiotap header. * This is enough for the radiotap header.
*/ */
#define IEEE80211_TX_STATUS_HEADROOM 14 #define IEEE80211_TX_STATUS_HEADROOM ALIGN(14, 4)
/** /**
* ieee80211_sta_set_buffered - inform mac80211 about driver-buffered frames * ieee80211_sta_set_buffered - inform mac80211 about driver-buffered frames

View File

@ -78,7 +78,7 @@ struct regulatory_request {
int wiphy_idx; int wiphy_idx;
enum nl80211_reg_initiator initiator; enum nl80211_reg_initiator initiator;
enum nl80211_user_reg_hint_type user_reg_hint_type; enum nl80211_user_reg_hint_type user_reg_hint_type;
char alpha2[2]; char alpha2[3];
enum nl80211_dfs_regions dfs_region; enum nl80211_dfs_regions dfs_region;
bool intersect; bool intersect;
bool processed; bool processed;

View File

@ -8,6 +8,7 @@
* Copyright 2007, Michael Wu <flamingice@sourmilk.net> * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
* Copyright 2007-2010, Intel Corporation * Copyright 2007-2010, Intel Corporation
* Copyright(c) 2015-2017 Intel Deutschland GmbH * Copyright(c) 2015-2017 Intel Deutschland GmbH
* Copyright (C) 2018 Intel Corporation
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
@ -304,9 +305,6 @@ void ___ieee80211_start_rx_ba_session(struct sta_info *sta,
* driver so reject the timeout update. * driver so reject the timeout update.
*/ */
status = WLAN_STATUS_REQUEST_DECLINED; status = WLAN_STATUS_REQUEST_DECLINED;
ieee80211_send_addba_resp(sta->sdata, sta->sta.addr,
tid, dialog_token, status,
1, buf_size, timeout);
goto end; goto end;
} }

View File

@ -2892,7 +2892,7 @@ cfg80211_beacon_dup(struct cfg80211_beacon_data *beacon)
} }
if (beacon->probe_resp_len) { if (beacon->probe_resp_len) {
new_beacon->probe_resp_len = beacon->probe_resp_len; new_beacon->probe_resp_len = beacon->probe_resp_len;
beacon->probe_resp = pos; new_beacon->probe_resp = pos;
memcpy(pos, beacon->probe_resp, beacon->probe_resp_len); memcpy(pos, beacon->probe_resp, beacon->probe_resp_len);
pos += beacon->probe_resp_len; pos += beacon->probe_resp_len;
} }

View File

@ -1467,7 +1467,7 @@ struct ieee802_11_elems {
const struct ieee80211_timeout_interval_ie *timeout_int; const struct ieee80211_timeout_interval_ie *timeout_int;
const u8 *opmode_notif; const u8 *opmode_notif;
const struct ieee80211_sec_chan_offs_ie *sec_chan_offs; const struct ieee80211_sec_chan_offs_ie *sec_chan_offs;
const struct ieee80211_mesh_chansw_params_ie *mesh_chansw_params_ie; struct ieee80211_mesh_chansw_params_ie *mesh_chansw_params_ie;
const struct ieee80211_bss_max_idle_period_ie *max_idle_period_ie; const struct ieee80211_bss_max_idle_period_ie *max_idle_period_ie;
/* length of them, respectively */ /* length of them, respectively */

View File

@ -1255,13 +1255,12 @@ int ieee80211_mesh_csa_beacon(struct ieee80211_sub_if_data *sdata,
} }
static int mesh_fwd_csa_frame(struct ieee80211_sub_if_data *sdata, static int mesh_fwd_csa_frame(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt, size_t len) struct ieee80211_mgmt *mgmt, size_t len,
struct ieee802_11_elems *elems)
{ {
struct ieee80211_mgmt *mgmt_fwd; struct ieee80211_mgmt *mgmt_fwd;
struct sk_buff *skb; struct sk_buff *skb;
struct ieee80211_local *local = sdata->local; struct ieee80211_local *local = sdata->local;
u8 *pos = mgmt->u.action.u.chan_switch.variable;
size_t offset_ttl;
skb = dev_alloc_skb(local->tx_headroom + len); skb = dev_alloc_skb(local->tx_headroom + len);
if (!skb) if (!skb)
@ -1269,13 +1268,9 @@ static int mesh_fwd_csa_frame(struct ieee80211_sub_if_data *sdata,
skb_reserve(skb, local->tx_headroom); skb_reserve(skb, local->tx_headroom);
mgmt_fwd = skb_put(skb, len); mgmt_fwd = skb_put(skb, len);
/* offset_ttl is based on whether the secondary channel elems->mesh_chansw_params_ie->mesh_ttl--;
* offset is available or not. Subtract 1 from the mesh TTL elems->mesh_chansw_params_ie->mesh_flags &=
* and disable the initiator flag before forwarding. ~WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR;
*/
offset_ttl = (len < 42) ? 7 : 10;
*(pos + offset_ttl) -= 1;
*(pos + offset_ttl + 1) &= ~WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR;
memcpy(mgmt_fwd, mgmt, len); memcpy(mgmt_fwd, mgmt, len);
eth_broadcast_addr(mgmt_fwd->da); eth_broadcast_addr(mgmt_fwd->da);
@ -1323,7 +1318,7 @@ static void mesh_rx_csa_frame(struct ieee80211_sub_if_data *sdata,
/* forward or re-broadcast the CSA frame */ /* forward or re-broadcast the CSA frame */
if (fwd_csa) { if (fwd_csa) {
if (mesh_fwd_csa_frame(sdata, mgmt, len) < 0) if (mesh_fwd_csa_frame(sdata, mgmt, len, &elems) < 0)
mcsa_dbg(sdata, "Failed to forward the CSA frame"); mcsa_dbg(sdata, "Failed to forward the CSA frame");
} }
} }

View File

@ -8,6 +8,7 @@
* Copyright 2007, Michael Wu <flamingice@sourmilk.net> * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
* Copyright 2007-2008, Intel Corporation * Copyright 2007-2008, Intel Corporation
* Copyright 2008, Johannes Berg <johannes@sipsolutions.net> * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
* Copyright (C) 2018 Intel Corporation
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
@ -27,7 +28,7 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
u32 sta_flags, u8 *bssid, u32 sta_flags, u8 *bssid,
struct ieee80211_csa_ie *csa_ie) struct ieee80211_csa_ie *csa_ie)
{ {
enum nl80211_band new_band; enum nl80211_band new_band = current_band;
int new_freq; int new_freq;
u8 new_chan_no; u8 new_chan_no;
struct ieee80211_channel *new_chan; struct ieee80211_channel *new_chan;
@ -55,15 +56,13 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
elems->ext_chansw_ie->new_operating_class, elems->ext_chansw_ie->new_operating_class,
&new_band)) { &new_band)) {
sdata_info(sdata, sdata_info(sdata,
"cannot understand ECSA IE operating class %d, disconnecting\n", "cannot understand ECSA IE operating class, %d, ignoring\n",
elems->ext_chansw_ie->new_operating_class); elems->ext_chansw_ie->new_operating_class);
return -EINVAL;
} }
new_chan_no = elems->ext_chansw_ie->new_ch_num; new_chan_no = elems->ext_chansw_ie->new_ch_num;
csa_ie->count = elems->ext_chansw_ie->count; csa_ie->count = elems->ext_chansw_ie->count;
csa_ie->mode = elems->ext_chansw_ie->mode; csa_ie->mode = elems->ext_chansw_ie->mode;
} else if (elems->ch_switch_ie) { } else if (elems->ch_switch_ie) {
new_band = current_band;
new_chan_no = elems->ch_switch_ie->new_ch_num; new_chan_no = elems->ch_switch_ie->new_ch_num;
csa_ie->count = elems->ch_switch_ie->count; csa_ie->count = elems->ch_switch_ie->count;
csa_ie->mode = elems->ch_switch_ie->mode; csa_ie->mode = elems->ch_switch_ie->mode;

View File

@ -314,7 +314,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
if (ieee80211_hw_check(hw, USES_RSS)) { if (ieee80211_hw_check(hw, USES_RSS)) {
sta->pcpu_rx_stats = sta->pcpu_rx_stats =
alloc_percpu(struct ieee80211_sta_rx_stats); alloc_percpu_gfp(struct ieee80211_sta_rx_stats, gfp);
if (!sta->pcpu_rx_stats) if (!sta->pcpu_rx_stats)
goto free; goto free;
} }
@ -433,6 +433,7 @@ free_txq:
if (sta->sta.txq[0]) if (sta->sta.txq[0])
kfree(to_txq_info(sta->sta.txq[0])); kfree(to_txq_info(sta->sta.txq[0]));
free: free:
free_percpu(sta->pcpu_rx_stats);
#ifdef CONFIG_MAC80211_MESH #ifdef CONFIG_MAC80211_MESH
kfree(sta->mesh); kfree(sta->mesh);
#endif #endif

View File

@ -170,9 +170,28 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
enum nl80211_bss_scan_width scan_width; enum nl80211_bss_scan_width scan_width;
struct ieee80211_supported_band *sband = struct ieee80211_supported_band *sband =
rdev->wiphy.bands[setup->chandef.chan->band]; rdev->wiphy.bands[setup->chandef.chan->band];
scan_width = cfg80211_chandef_to_scan_width(&setup->chandef);
setup->basic_rates = ieee80211_mandatory_rates(sband, if (setup->chandef.chan->band == NL80211_BAND_2GHZ) {
scan_width); int i;
/*
* Older versions selected the mandatory rates for
* 2.4 GHz as well, but were broken in that only
* 1 Mbps was regarded as a mandatory rate. Keep
* using just 1 Mbps as the default basic rate for
* mesh to be interoperable with older versions.
*/
for (i = 0; i < sband->n_bitrates; i++) {
if (sband->bitrates[i].bitrate == 10) {
setup->basic_rates = BIT(i);
break;
}
}
} else {
scan_width = cfg80211_chandef_to_scan_width(&setup->chandef);
setup->basic_rates = ieee80211_mandatory_rates(sband,
scan_width);
}
} }
err = cfg80211_chandef_dfs_required(&rdev->wiphy, err = cfg80211_chandef_dfs_required(&rdev->wiphy,

View File

@ -1032,6 +1032,8 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
wdev->current_bss = NULL; wdev->current_bss = NULL;
wdev->ssid_len = 0; wdev->ssid_len = 0;
wdev->conn_owner_nlportid = 0; wdev->conn_owner_nlportid = 0;
kzfree(wdev->connect_keys);
wdev->connect_keys = NULL;
nl80211_send_disconnected(rdev, dev, reason, ie, ie_len, from_ap); nl80211_send_disconnected(rdev, dev, reason, ie, ie_len, from_ap);