A couple of fixes:

* FTM responder policy netlink validation fix
    (but the only user validates again later)
  * kernel-doc fixes
  * a fix for a race in mac80211 radio registration vs. userspace
  * a mesh channel switch fix
  * a fix for a syzbot reported kasprintf() issue
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEH1e1rEeCd0AIMq6MB8qZga/fl8QFAl6WyIAACgkQB8qZga/f
 l8TqyBAAnR+HrstmY0g8pIfsN925axUP4blRuS4U55olmEvS4xFOKhIQ5ksMceD0
 ndvTxXOjJ3EA6Zc5icGG+hcPihhcO/V6UzE83KHqVEa0LP7o6Nmjyh5kiyl1HS6y
 naB6/g3AQcUGqD1zsT8EZ6HeePXDVMxnT0CORC2JtXJCPmBeLpfAROEhKmLuuonp
 WugB8monGfWQuNJTNILTg4Ya8/LR4GW7ABTNrHOnAqCpexBhrGcxdbiiqTm8ionF
 sLcXkfzGd7KudTxS0qTJZnR3Bja7o96FjPxy1If5eQFUiDbgVYr0C8I69X6fTzyP
 l4O5b1DRcLLX/1N8H5DmUsRMk4froUtVY9hqTIVE956d1HWqOSfXXMx4yxpvqCp+
 dzOM6mHzfWp29aKSNqtbkrDjGJB7EviR8Fan6Sngh2EgvUVhpdwpAaKepdcZHUkW
 th7ukrh/KTTaied8zu8CS5RVJPn/m4afsxl05yGSDh7kJ+VN9We+0fytOb+zvyUi
 HO9ru0w++zqdXU82l4qaQvLJXISpEyf53IqM2PnHIS5Zvo/3HnGC2vogHGiwAccY
 yNbD3IYueGIgzRrSN2CaAmoFY1CzC5rK73y9Qh1JIJqWOKv66MhBBPjm3kBraiqM
 hj5BH3Qz9PYnaNk1uDwHZN9dLPYQr0GPHPJEMx3QsRUVau95F0Q=
 =1yy8
 -----END PGP SIGNATURE-----

Merge tag 'mac80211-for-net-2020-04-15' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211

Johannes Berg says:

====================
A couple of fixes:
 * FTM responder policy netlink validation fix
   (but the only user validates again later)
 * kernel-doc fixes
 * a fix for a race in mac80211 radio registration vs. userspace
 * a mesh channel switch fix
 * a fix for a syzbot reported kasprintf() issue
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2020-04-15 11:27:23 -07:00
commit 6058ee09ec
5 changed files with 38 additions and 25 deletions

View File

@ -3669,9 +3669,9 @@ static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info)
} }
if (info->attrs[HWSIM_ATTR_RADIO_NAME]) { if (info->attrs[HWSIM_ATTR_RADIO_NAME]) {
hwname = kasprintf(GFP_KERNEL, "%.*s", hwname = kstrndup((char *)nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME]),
nla_len(info->attrs[HWSIM_ATTR_RADIO_NAME]), nla_len(info->attrs[HWSIM_ATTR_RADIO_NAME]),
(char *)nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME])); GFP_KERNEL);
if (!hwname) if (!hwname)
return -ENOMEM; return -ENOMEM;
param.hwname = hwname; param.hwname = hwname;
@ -3691,9 +3691,9 @@ static int hwsim_del_radio_nl(struct sk_buff *msg, struct genl_info *info)
if (info->attrs[HWSIM_ATTR_RADIO_ID]) { if (info->attrs[HWSIM_ATTR_RADIO_ID]) {
idx = nla_get_u32(info->attrs[HWSIM_ATTR_RADIO_ID]); idx = nla_get_u32(info->attrs[HWSIM_ATTR_RADIO_ID]);
} else if (info->attrs[HWSIM_ATTR_RADIO_NAME]) { } else if (info->attrs[HWSIM_ATTR_RADIO_NAME]) {
hwname = kasprintf(GFP_KERNEL, "%.*s", hwname = kstrndup((char *)nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME]),
nla_len(info->attrs[HWSIM_ATTR_RADIO_NAME]), nla_len(info->attrs[HWSIM_ATTR_RADIO_NAME]),
(char *)nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME])); GFP_KERNEL);
if (!hwname) if (!hwname)
return -ENOMEM; return -ENOMEM;
} else } else

View File

@ -905,6 +905,8 @@ struct survey_info {
* protocol frames. * protocol frames.
* @control_port_over_nl80211: TRUE if userspace expects to exchange control * @control_port_over_nl80211: TRUE if userspace expects to exchange control
* port frames over NL80211 instead of the network interface. * port frames over NL80211 instead of the network interface.
* @control_port_no_preauth: disables pre-auth rx over the nl80211 control
* port for mac80211
* @wep_keys: static WEP keys, if not NULL points to an array of * @wep_keys: static WEP keys, if not NULL points to an array of
* CFG80211_MAX_WEP_KEYS WEP keys * CFG80211_MAX_WEP_KEYS WEP keys
* @wep_tx_key: key index (0..3) of the default TX static WEP key * @wep_tx_key: key index (0..3) of the default TX static WEP key
@ -1222,6 +1224,7 @@ struct sta_txpwr {
* @he_capa: HE capabilities of station * @he_capa: HE capabilities of station
* @he_capa_len: the length of the HE capabilities * @he_capa_len: the length of the HE capabilities
* @airtime_weight: airtime scheduler weight for this station * @airtime_weight: airtime scheduler weight for this station
* @txpwr: transmit power for an associated station
*/ */
struct station_parameters { struct station_parameters {
const u8 *supported_rates; const u8 *supported_rates;
@ -4666,6 +4669,9 @@ struct wiphy_iftype_akm_suites {
* @txq_memory_limit: configuration internal TX queue memory limit * @txq_memory_limit: configuration internal TX queue memory limit
* @txq_quantum: configuration of internal TX queue scheduler quantum * @txq_quantum: configuration of internal TX queue scheduler quantum
* *
* @tx_queue_len: allow setting transmit queue len for drivers not using
* wake_tx_queue
*
* @support_mbssid: can HW support association with nontransmitted AP * @support_mbssid: can HW support association with nontransmitted AP
* @support_only_he_mbssid: don't parse MBSSID elements if it is not * @support_only_he_mbssid: don't parse MBSSID elements if it is not
* HE AP, in order to avoid compatibility issues. * HE AP, in order to avoid compatibility issues.
@ -4681,6 +4687,10 @@ struct wiphy_iftype_akm_suites {
* supported by the driver for each peer * supported by the driver for each peer
* @tid_config_support.max_retry: maximum supported retry count for * @tid_config_support.max_retry: maximum supported retry count for
* long/short retry configuration * long/short retry configuration
*
* @max_data_retry_count: maximum supported per TID retry count for
* configuration through the %NL80211_TID_CONFIG_ATTR_RETRY_SHORT and
* %NL80211_TID_CONFIG_ATTR_RETRY_LONG attributes
*/ */
struct wiphy { struct wiphy {
/* assign these fields before you register the wiphy */ /* assign these fields before you register the wiphy */

View File

@ -1069,7 +1069,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC; local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC;
if (hw->max_signal <= 0) { if (hw->max_signal <= 0) {
result = -EINVAL; result = -EINVAL;
goto fail_wiphy_register; goto fail_workqueue;
} }
} }
@ -1135,7 +1135,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
result = ieee80211_init_cipher_suites(local); result = ieee80211_init_cipher_suites(local);
if (result < 0) if (result < 0)
goto fail_wiphy_register; goto fail_workqueue;
if (!local->ops->remain_on_channel) if (!local->ops->remain_on_channel)
local->hw.wiphy->max_remain_on_channel_duration = 5000; local->hw.wiphy->max_remain_on_channel_duration = 5000;
@ -1161,10 +1161,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
local->hw.wiphy->max_num_csa_counters = IEEE80211_MAX_CSA_COUNTERS_NUM; local->hw.wiphy->max_num_csa_counters = IEEE80211_MAX_CSA_COUNTERS_NUM;
result = wiphy_register(local->hw.wiphy);
if (result < 0)
goto fail_wiphy_register;
/* /*
* We use the number of queues for feature tests (QoS, HT) internally * We use the number of queues for feature tests (QoS, HT) internally
* so restrict them appropriately. * so restrict them appropriately.
@ -1217,9 +1213,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
goto fail_flows; goto fail_flows;
rtnl_lock(); rtnl_lock();
result = ieee80211_init_rate_ctrl_alg(local, result = ieee80211_init_rate_ctrl_alg(local,
hw->rate_control_algorithm); hw->rate_control_algorithm);
rtnl_unlock();
if (result < 0) { if (result < 0) {
wiphy_debug(local->hw.wiphy, wiphy_debug(local->hw.wiphy,
"Failed to initialize rate control algorithm\n"); "Failed to initialize rate control algorithm\n");
@ -1273,6 +1269,12 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
local->sband_allocated |= BIT(band); local->sband_allocated |= BIT(band);
} }
result = wiphy_register(local->hw.wiphy);
if (result < 0)
goto fail_wiphy_register;
rtnl_lock();
/* add one default STA interface if supported */ /* add one default STA interface if supported */
if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION) && if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION) &&
!ieee80211_hw_check(hw, NO_AUTO_VIF)) { !ieee80211_hw_check(hw, NO_AUTO_VIF)) {
@ -1312,17 +1314,17 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
#if defined(CONFIG_INET) || defined(CONFIG_IPV6) #if defined(CONFIG_INET) || defined(CONFIG_IPV6)
fail_ifa: fail_ifa:
#endif #endif
wiphy_unregister(local->hw.wiphy);
fail_wiphy_register:
rtnl_lock(); rtnl_lock();
rate_control_deinitialize(local); rate_control_deinitialize(local);
ieee80211_remove_interfaces(local); ieee80211_remove_interfaces(local);
fail_rate:
rtnl_unlock(); rtnl_unlock();
fail_rate:
fail_flows: fail_flows:
ieee80211_led_exit(local); ieee80211_led_exit(local);
destroy_workqueue(local->workqueue); destroy_workqueue(local->workqueue);
fail_workqueue: fail_workqueue:
wiphy_unregister(local->hw.wiphy);
fail_wiphy_register:
if (local->wiphy_ciphers_allocated) if (local->wiphy_ciphers_allocated)
kfree(local->hw.wiphy->cipher_suites); kfree(local->hw.wiphy->cipher_suites);
kfree(local->int_scan_req); kfree(local->int_scan_req);
@ -1372,8 +1374,8 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
skb_queue_purge(&local->skb_queue_unreliable); skb_queue_purge(&local->skb_queue_unreliable);
skb_queue_purge(&local->skb_queue_tdls_chsw); skb_queue_purge(&local->skb_queue_tdls_chsw);
destroy_workqueue(local->workqueue);
wiphy_unregister(local->hw.wiphy); wiphy_unregister(local->hw.wiphy);
destroy_workqueue(local->workqueue);
ieee80211_led_exit(local); ieee80211_led_exit(local);
kfree(local->int_scan_req); kfree(local->int_scan_req);
} }

View File

@ -1257,15 +1257,15 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
sdata->u.mesh.mshcfg.rssi_threshold < rx_status->signal) sdata->u.mesh.mshcfg.rssi_threshold < rx_status->signal)
mesh_neighbour_update(sdata, mgmt->sa, &elems, mesh_neighbour_update(sdata, mgmt->sa, &elems,
rx_status); rx_status);
if (ifmsh->csa_role != IEEE80211_MESH_CSA_ROLE_INIT &&
!sdata->vif.csa_active)
ieee80211_mesh_process_chnswitch(sdata, &elems, true);
} }
if (ifmsh->sync_ops) if (ifmsh->sync_ops)
ifmsh->sync_ops->rx_bcn_presp(sdata, ifmsh->sync_ops->rx_bcn_presp(sdata,
stype, mgmt, &elems, rx_status); stype, mgmt, &elems, rx_status);
if (ifmsh->csa_role != IEEE80211_MESH_CSA_ROLE_INIT &&
!sdata->vif.csa_active)
ieee80211_mesh_process_chnswitch(sdata, &elems, true);
} }
int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata) int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata)
@ -1373,6 +1373,9 @@ static void mesh_rx_csa_frame(struct ieee80211_sub_if_data *sdata,
ieee802_11_parse_elems(pos, len - baselen, true, &elems, ieee802_11_parse_elems(pos, len - baselen, true, &elems,
mgmt->bssid, NULL); mgmt->bssid, NULL);
if (!mesh_matches_local(sdata, &elems))
return;
ifmsh->chsw_ttl = elems.mesh_chansw_params_ie->mesh_ttl; ifmsh->chsw_ttl = elems.mesh_chansw_params_ie->mesh_ttl;
if (!--ifmsh->chsw_ttl) if (!--ifmsh->chsw_ttl)
fwd_csa = false; fwd_csa = false;

View File

@ -644,10 +644,8 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_HE_CAPABILITY] = { .type = NLA_BINARY, [NL80211_ATTR_HE_CAPABILITY] = { .type = NLA_BINARY,
.len = NL80211_HE_MAX_CAPABILITY_LEN }, .len = NL80211_HE_MAX_CAPABILITY_LEN },
[NL80211_ATTR_FTM_RESPONDER] = { [NL80211_ATTR_FTM_RESPONDER] =
.type = NLA_NESTED, NLA_POLICY_NESTED(nl80211_ftm_responder_policy),
.validation_data = nl80211_ftm_responder_policy,
},
[NL80211_ATTR_TIMEOUT] = NLA_POLICY_MIN(NLA_U32, 1), [NL80211_ATTR_TIMEOUT] = NLA_POLICY_MIN(NLA_U32, 1),
[NL80211_ATTR_PEER_MEASUREMENTS] = [NL80211_ATTR_PEER_MEASUREMENTS] =
NLA_POLICY_NESTED(nl80211_pmsr_attr_policy), NLA_POLICY_NESTED(nl80211_pmsr_attr_policy),