A few fixes:
* -O3 enablement fallout, thanks to Arnd who ran this * fixes for a few leaks, thanks to Felix * channel 12 regulatory fix for custom regdomains * check for a crash reported by syzbot (NULL function is called on drivers that don't have it) * fix TKIP replay protection after setup with some APs (from Jouni) * restrict obtaining some mesh data to avoid WARN_ONs * fix deadlocks with auto-disconnect (socket owner) * fix radar detection events with multiple devices -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEH1e1rEeCd0AIMq6MB8qZga/fl8QFAl4e4voACgkQB8qZga/f l8RVFg/+Ngjzje8xU6Ymh7VSwvBBz6CmSVwH/nRSsIAszDrQLoDCo7+eWeUHnAKG 2ViFQ4Lf5CP2J9kSgi7pbD0yGQRDGxH1CVSxMB64uZZRErlOCZYLRTIeBn7HGb8w JhqAVXBjskzP9iB5jUZIkOgJ6L2ESM2KYKQVGtgn8p9fFdHKitec8UEKiPU3tcX1 zx94EbKldynuvDNb7VkTm4MdoY8LK5KI8ovVdVKwJ05qCtLvc6xvEBYhm33Fl6Pe 66cWklCrU093jQXUDTk0yBkwlcXGxJc143y1nXuurI8ZLH6q2wdDUAMHUEKdL6mz ktHxABK4JA4Z/ylphR2Tp1TNh8xnz/ZZ5IdAe4P9K0/PerrjH8Yk7zf/48lrHTSv LKb86Oaoq4MY4k5UNyjDUdgPB/q8CgxN2xDQaeQX69u740wrlxYtrwgHmqHrKI69 ppCzL7a3wmJzAz/97TMFhSseCH1WEQfWY+tlzktrvRofSgOGsIUtcPP10NmvGZHj zdF79E9TiUPX4KVWssRb9A2MjBbvKA31hCQbH/OVKSWt/fItoBUbMQKtPxfnHcam /W/gCWrOpw5Qqhc/BdFbYYsgY9J06KzifsV5e2Z6he+6Ex+rtdZNoLXc6/4QH3+9 HzsVYBP+ZUaqrMJi64KDN59C3ni4jDVs9zfYnVkC9LhzHASI5EE= =i20C -----END PGP SIGNATURE----- Merge tag 'mac80211-for-net-2020-01-15' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211 Johannes Berg says: ==================== A few fixes: * -O3 enablement fallout, thanks to Arnd who ran this * fixes for a few leaks, thanks to Felix * channel 12 regulatory fix for custom regdomains * check for a crash reported by syzbot (NULL function is called on drivers that don't have it) * fix TKIP replay protection after setup with some APs (from Jouni) * restrict obtaining some mesh data to avoid WARN_ONs * fix deadlocks with auto-disconnect (socket owner) * fix radar detection events with multiple devices ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
eb507906fe
@ -3548,6 +3548,9 @@ struct cfg80211_update_owe_info {
|
||||
*
|
||||
* @start_radar_detection: Start radar detection in the driver.
|
||||
*
|
||||
* @end_cac: End running CAC, probably because a related CAC
|
||||
* was finished on another phy.
|
||||
*
|
||||
* @update_ft_ies: Provide updated Fast BSS Transition information to the
|
||||
* driver. If the SME is in the driver/firmware, this information can be
|
||||
* used in building Authentication and Reassociation Request frames.
|
||||
@ -3874,6 +3877,8 @@ struct cfg80211_ops {
|
||||
struct net_device *dev,
|
||||
struct cfg80211_chan_def *chandef,
|
||||
u32 cac_time_ms);
|
||||
void (*end_cac)(struct wiphy *wiphy,
|
||||
struct net_device *dev);
|
||||
int (*update_ft_ies)(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct cfg80211_update_ft_ies_params *ftie);
|
||||
int (*crit_proto_start)(struct wiphy *wiphy,
|
||||
|
@ -2954,6 +2954,28 @@ static int ieee80211_start_radar_detection(struct wiphy *wiphy,
|
||||
return err;
|
||||
}
|
||||
|
||||
static void ieee80211_end_cac(struct wiphy *wiphy,
|
||||
struct net_device *dev)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
|
||||
mutex_lock(&local->mtx);
|
||||
list_for_each_entry(sdata, &local->interfaces, list) {
|
||||
/* it might be waiting for the local->mtx, but then
|
||||
* by the time it gets it, sdata->wdev.cac_started
|
||||
* will no longer be true
|
||||
*/
|
||||
cancel_delayed_work(&sdata->dfs_cac_timer_work);
|
||||
|
||||
if (sdata->wdev.cac_started) {
|
||||
ieee80211_vif_release_channel(sdata);
|
||||
sdata->wdev.cac_started = false;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&local->mtx);
|
||||
}
|
||||
|
||||
static struct cfg80211_beacon_data *
|
||||
cfg80211_beacon_dup(struct cfg80211_beacon_data *beacon)
|
||||
{
|
||||
@ -4023,6 +4045,7 @@ const struct cfg80211_ops mac80211_config_ops = {
|
||||
#endif
|
||||
.get_channel = ieee80211_cfg_get_channel,
|
||||
.start_radar_detection = ieee80211_start_radar_detection,
|
||||
.end_cac = ieee80211_end_cac,
|
||||
.channel_switch = ieee80211_channel_switch,
|
||||
.set_qos_map = ieee80211_set_qos_map,
|
||||
.set_ap_chanwidth = ieee80211_set_ap_chanwidth,
|
||||
|
@ -328,6 +328,9 @@ u32 airtime_link_metric_get(struct ieee80211_local *local,
|
||||
unsigned long fail_avg =
|
||||
ewma_mesh_fail_avg_read(&sta->mesh->fail_avg);
|
||||
|
||||
if (sta->mesh->plink_state != NL80211_PLINK_ESTAB)
|
||||
return MAX_METRIC;
|
||||
|
||||
/* Try to get rate based on HW/SW RC algorithm.
|
||||
* Rate is returned in units of Kbps, correct this
|
||||
* to comply with airtime calculation units
|
||||
|
@ -263,9 +263,21 @@ int ieee80211_tkip_decrypt_data(struct arc4_ctx *ctx,
|
||||
if ((keyid >> 6) != key->conf.keyidx)
|
||||
return TKIP_DECRYPT_INVALID_KEYIDX;
|
||||
|
||||
if (rx_ctx->ctx.state != TKIP_STATE_NOT_INIT &&
|
||||
(iv32 < rx_ctx->iv32 ||
|
||||
(iv32 == rx_ctx->iv32 && iv16 <= rx_ctx->iv16)))
|
||||
/* Reject replays if the received TSC is smaller than or equal to the
|
||||
* last received value in a valid message, but with an exception for
|
||||
* the case where a new key has been set and no valid frame using that
|
||||
* key has yet received and the local RSC was initialized to 0. This
|
||||
* exception allows the very first frame sent by the transmitter to be
|
||||
* accepted even if that transmitter were to use TSC 0 (IEEE 802.11
|
||||
* described TSC to be initialized to 1 whenever a new key is taken into
|
||||
* use).
|
||||
*/
|
||||
if (iv32 < rx_ctx->iv32 ||
|
||||
(iv32 == rx_ctx->iv32 &&
|
||||
(iv16 < rx_ctx->iv16 ||
|
||||
(iv16 == rx_ctx->iv16 &&
|
||||
(rx_ctx->iv32 || rx_ctx->iv16 ||
|
||||
rx_ctx->ctx.state != TKIP_STATE_NOT_INIT)))))
|
||||
return TKIP_DECRYPT_REPLAY;
|
||||
|
||||
if (only_iv) {
|
||||
|
@ -10843,6 +10843,7 @@ static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
cfg80211_sinfo_release_content(&sinfo);
|
||||
if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG))
|
||||
wdev->cqm_config->last_rssi_event_value =
|
||||
(s8) sinfo.rx_beacon_signal_avg;
|
||||
@ -13796,6 +13797,8 @@ static int nl80211_probe_mesh_link(struct sk_buff *skb, struct genl_info *info)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
cfg80211_sinfo_release_content(&sinfo);
|
||||
|
||||
return rdev_probe_mesh_link(rdev, dev, dest, buf, len);
|
||||
}
|
||||
|
||||
|
@ -538,6 +538,10 @@ static inline int
|
||||
rdev_set_wiphy_params(struct cfg80211_registered_device *rdev, u32 changed)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!rdev->ops->set_wiphy_params)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
trace_rdev_set_wiphy_params(&rdev->wiphy, changed);
|
||||
ret = rdev->ops->set_wiphy_params(&rdev->wiphy, changed);
|
||||
trace_rdev_return_int(&rdev->wiphy, ret);
|
||||
@ -1167,6 +1171,16 @@ rdev_start_radar_detection(struct cfg80211_registered_device *rdev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void
|
||||
rdev_end_cac(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev)
|
||||
{
|
||||
trace_rdev_end_cac(&rdev->wiphy, dev);
|
||||
if (rdev->ops->end_cac)
|
||||
rdev->ops->end_cac(&rdev->wiphy, dev);
|
||||
trace_rdev_return_void(&rdev->wiphy);
|
||||
}
|
||||
|
||||
static inline int
|
||||
rdev_set_mcast_rate(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev,
|
||||
|
@ -2261,14 +2261,15 @@ static void update_all_wiphy_regulatory(enum nl80211_reg_initiator initiator)
|
||||
|
||||
static void handle_channel_custom(struct wiphy *wiphy,
|
||||
struct ieee80211_channel *chan,
|
||||
const struct ieee80211_regdomain *regd)
|
||||
const struct ieee80211_regdomain *regd,
|
||||
u32 min_bw)
|
||||
{
|
||||
u32 bw_flags = 0;
|
||||
const struct ieee80211_reg_rule *reg_rule = NULL;
|
||||
const struct ieee80211_power_rule *power_rule = NULL;
|
||||
u32 bw;
|
||||
|
||||
for (bw = MHZ_TO_KHZ(20); bw >= MHZ_TO_KHZ(5); bw = bw / 2) {
|
||||
for (bw = MHZ_TO_KHZ(20); bw >= min_bw; bw = bw / 2) {
|
||||
reg_rule = freq_reg_info_regd(MHZ_TO_KHZ(chan->center_freq),
|
||||
regd, bw);
|
||||
if (!IS_ERR(reg_rule))
|
||||
@ -2324,8 +2325,14 @@ static void handle_band_custom(struct wiphy *wiphy,
|
||||
if (!sband)
|
||||
return;
|
||||
|
||||
/*
|
||||
* We currently assume that you always want at least 20 MHz,
|
||||
* otherwise channel 12 might get enabled if this rule is
|
||||
* compatible to US, which permits 2402 - 2472 MHz.
|
||||
*/
|
||||
for (i = 0; i < sband->n_channels; i++)
|
||||
handle_channel_custom(wiphy, &sband->channels[i], regd);
|
||||
handle_channel_custom(wiphy, &sband->channels[i], regd,
|
||||
MHZ_TO_KHZ(20));
|
||||
}
|
||||
|
||||
/* Used by drivers prior to wiphy registration */
|
||||
@ -3885,6 +3892,25 @@ bool regulatory_pre_cac_allowed(struct wiphy *wiphy)
|
||||
}
|
||||
EXPORT_SYMBOL(regulatory_pre_cac_allowed);
|
||||
|
||||
static void cfg80211_check_and_end_cac(struct cfg80211_registered_device *rdev)
|
||||
{
|
||||
struct wireless_dev *wdev;
|
||||
/* If we finished CAC or received radar, we should end any
|
||||
* CAC running on the same channels.
|
||||
* the check !cfg80211_chandef_dfs_usable contain 2 options:
|
||||
* either all channels are available - those the CAC_FINISHED
|
||||
* event has effected another wdev state, or there is a channel
|
||||
* in unavailable state in wdev chandef - those the RADAR_DETECTED
|
||||
* event has effected another wdev state.
|
||||
* In both cases we should end the CAC on the wdev.
|
||||
*/
|
||||
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
|
||||
if (wdev->cac_started &&
|
||||
!cfg80211_chandef_dfs_usable(&rdev->wiphy, &wdev->chandef))
|
||||
rdev_end_cac(rdev, wdev->netdev);
|
||||
}
|
||||
}
|
||||
|
||||
void regulatory_propagate_dfs_state(struct wiphy *wiphy,
|
||||
struct cfg80211_chan_def *chandef,
|
||||
enum nl80211_dfs_state dfs_state,
|
||||
@ -3911,8 +3937,10 @@ void regulatory_propagate_dfs_state(struct wiphy *wiphy,
|
||||
cfg80211_set_dfs_state(&rdev->wiphy, chandef, dfs_state);
|
||||
|
||||
if (event == NL80211_RADAR_DETECTED ||
|
||||
event == NL80211_RADAR_CAC_FINISHED)
|
||||
event == NL80211_RADAR_CAC_FINISHED) {
|
||||
cfg80211_sched_dfs_chan_update(rdev);
|
||||
cfg80211_check_and_end_cac(rdev);
|
||||
}
|
||||
|
||||
nl80211_radar_notify(rdev, chandef, event, NULL, GFP_KERNEL);
|
||||
}
|
||||
|
@ -1307,14 +1307,14 @@ void cfg80211_autodisconnect_wk(struct work_struct *work)
|
||||
if (wdev->conn_owner_nlportid) {
|
||||
switch (wdev->iftype) {
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
cfg80211_leave_ibss(rdev, wdev->netdev, false);
|
||||
__cfg80211_leave_ibss(rdev, wdev->netdev, false);
|
||||
break;
|
||||
case NL80211_IFTYPE_AP:
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
cfg80211_stop_ap(rdev, wdev->netdev, false);
|
||||
__cfg80211_stop_ap(rdev, wdev->netdev, false);
|
||||
break;
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
cfg80211_leave_mesh(rdev, wdev->netdev);
|
||||
__cfg80211_leave_mesh(rdev, wdev->netdev);
|
||||
break;
|
||||
case NL80211_IFTYPE_STATION:
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
|
@ -646,6 +646,11 @@ DEFINE_EVENT(wiphy_netdev_evt, rdev_flush_pmksa,
|
||||
TP_ARGS(wiphy, netdev)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(wiphy_netdev_evt, rdev_end_cac,
|
||||
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev),
|
||||
TP_ARGS(wiphy, netdev)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(station_add_change,
|
||||
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 *mac,
|
||||
struct station_parameters *params),
|
||||
|
@ -564,7 +564,7 @@ __frame_add_frag(struct sk_buff *skb, struct page *page,
|
||||
struct skb_shared_info *sh = skb_shinfo(skb);
|
||||
int page_offset;
|
||||
|
||||
page_ref_inc(page);
|
||||
get_page(page);
|
||||
page_offset = ptr - page_address(page);
|
||||
skb_add_rx_frag(skb, sh->nr_frags, page, page_offset, len, size);
|
||||
}
|
||||
|
@ -657,7 +657,8 @@ struct iw_statistics *get_wireless_stats(struct net_device *dev)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int iw_handler_get_iwstats(struct net_device * dev,
|
||||
/* noinline to avoid a bogus warning with -O3 */
|
||||
static noinline int iw_handler_get_iwstats(struct net_device * dev,
|
||||
struct iw_request_info * info,
|
||||
union iwreq_data * wrqu,
|
||||
char * extra)
|
||||
|
Loading…
Reference in New Issue
Block a user