mirror of
https://github.com/torvalds/linux.git
synced 2026-05-13 00:28:54 +02:00
Quite a number of fixes now:
- mac80211
- remove HT NSS validation to work with broken APs
(with a kunit fix now)
- remove 'static' that could cause races
- check station link lookup before further processing
- fix use-after-free due to delete in list iteration
- remove AP station on assoc failures to fix crashes
- ath12k
- fix OF node refcount imbalance
- fix queue flush ("REO update") in MLO
- fix RCU assert
- ath12k:
- fix Kconfig with POWER_SEQUENCING
- fix WMI buffer leaks on error conditions
- don't use uninitialized stack data when processing RSSI events
- fix logic for determining the peer ID in the RX path
- ath5k: fix a potential stack buffer overwrite
- rsi: fix thread lifetime race
- brcmfmac: fix potential UAF
- nl80211:
- stricter permissions/checks for PMK and netns
- fix netlink policy vs. code type confusion
- cw1200: revert a broken locking change
- various fixes to not trust values from firmware
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEpeA8sTs3M8SN2hR410qiO8sPaAAFAmn7Hj8ACgkQ10qiO8sP
aACOiA//QZXrPPCxJmCkThP9DUYv2sxRAbTEEJLRJcXZODWJ7nBDn7tdM/nvOJmm
8Y0v/+DqhqCVJ4Zkvh4u8S6Z7tGt83LKi+j8dAMoZw+Bn2Qq5mFvOK9ENOk4pfmB
isVKTDFxAgbgtkClo3eygK6z9KuClY5JbQ9wmcE450cjuIYQ4z6UmNTeHcnsombX
flvKX8JXINwolX1MrL5t+qMZ14bd+BL0Ui9VkvxxuECvdrQemhf7iBfCELfs8Q2r
PxQcfPq5zIKPTqAcR50HPV/1YDPk66tG3P3NxA/DvAYUXXc7XHr0RYD5IJ/HYafM
APVHA0XU4aoyDLiWSrSDj1WoRs+MYIlUl7BRdrE4ABenwB2lGTkfdUYuq9dQKPtQ
Ku92UATOrXdMEZH7TVnme4RbtotWH+nUCw1os/OyoGNfL3czFJIqntUXVjLuUB4e
Bo3qWtTHVmu3B+OJlNsKiiz8d4L5FxHFnaSKA4MkEfNrZsSuV4N4Sl6PsWMWvJUa
G/EnUJiDKBaFO0lDAZRtYFr8CVxRBBlCKfCQs+mwxLXHjB7BZW3eA5Ps9qWq4krV
VbNwDTBwIPdWz12UfHmSpkoIPCbrTcbvdUM7uNwJKr8nuulve2lkZo73LEhEX8k2
jdXxDndaQyWX9Lmx5b9NpA/xRqxRlgFN7U3ZV8ntH4d9IsQOzZM=
=RBbh
-----END PGP SIGNATURE-----
Merge tag 'wireless-2026-05-06' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless
Johannes Berg says:
====================
Quite a number of fixes now:
- mac80211
- remove HT NSS validation to work with broken APs
(with a kunit fix now)
- remove 'static' that could cause races
- check station link lookup before further processing
- fix use-after-free due to delete in list iteration
- remove AP station on assoc failures to fix crashes
- ath12k
- fix OF node refcount imbalance
- fix queue flush ("REO update") in MLO
- fix RCU assert
- ath12k:
- fix Kconfig with POWER_SEQUENCING
- fix WMI buffer leaks on error conditions
- don't use uninitialized stack data when processing RSSI events
- fix logic for determining the peer ID in the RX path
- ath5k: fix a potential stack buffer overwrite
- rsi: fix thread lifetime race
- brcmfmac: fix potential UAF
- nl80211:
- stricter permissions/checks for PMK and netns
- fix netlink policy vs. code type confusion
- cw1200: revert a broken locking change
- various fixes to not trust values from firmware
* tag 'wireless-2026-05-06' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless: (25 commits)
wifi: nl80211: re-check wiphy netns in nl80211_prepare_wdev_dump() continuation
wifi: nl80211: require CAP_NET_ADMIN over the target netns in SET_WIPHY_NETNS
wifi: nl80211: fix NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST usage
wifi: mac80211: remove station if connection prep fails
wifi: mac80211: use safe list iteration in radar detect work
wifi: libertas: notify firmware load wait on disconnect
wifi: ath5k: do not access array OOB
wifi: ath12k: fix peer_id usage in normal RX path
wifi: ath12k: initialize RSSI dBm conversion event state
wifi: ath12k: fix leak in some ath12k_wmi_xxx() functions
wifi: cw1200: Revert "Fix locking in error paths"
wifi: mac80211: tests: mark HT check strict
wifi: rsi: fix kthread lifetime race between self-exit and external-stop
wifi: mac80211: drop stray 'static' from fast-RX rx_result
wifi: mac80211: check ieee80211_rx_data_set_link return in pubsta MLO path
wifi: nl80211: require admin perm on SET_PMK / DEL_PMK
wifi: libertas: fix integer underflow in process_cmdrequest()
wifi: b43legacy: enforce bounds check on firmware key index in RX path
wifi: b43: enforce bounds check on firmware key index in b43_rx()
wifi: brcmfmac: Fix potential use-after-free issue when stopping watchdog task
...
====================
Link: https://patch.msgid.link/20260506110325.219675-3-johannes@sipsolutions.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
b89e0100a5
|
|
@ -46,6 +46,7 @@ config ATH10K_SNOC
|
|||
depends on ARCH_QCOM || COMPILE_TEST
|
||||
depends on QCOM_SMEM
|
||||
depends on QCOM_RPROC_COMMON || QCOM_RPROC_COMMON=n
|
||||
select POWER_SEQUENCING
|
||||
select QCOM_SCM
|
||||
select QCOM_QMI_HELPERS
|
||||
help
|
||||
|
|
|
|||
|
|
@ -1838,10 +1838,22 @@ static struct ath12k_hw_group *ath12k_core_hw_group_alloc(struct ath12k_base *ab
|
|||
return ag;
|
||||
}
|
||||
|
||||
static void ath12k_core_free_wsi_info(struct ath12k_hw_group *ag)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ag->num_devices; i++) {
|
||||
of_node_put(ag->wsi_node[i]);
|
||||
ag->wsi_node[i] = NULL;
|
||||
}
|
||||
ag->num_devices = 0;
|
||||
}
|
||||
|
||||
static void ath12k_core_hw_group_free(struct ath12k_hw_group *ag)
|
||||
{
|
||||
mutex_lock(&ath12k_hw_group_mutex);
|
||||
|
||||
ath12k_core_free_wsi_info(ag);
|
||||
list_del(&ag->list);
|
||||
kfree(ag);
|
||||
|
||||
|
|
@ -1867,52 +1879,59 @@ static struct ath12k_hw_group *ath12k_core_hw_group_find_by_dt(struct ath12k_bas
|
|||
static int ath12k_core_get_wsi_info(struct ath12k_hw_group *ag,
|
||||
struct ath12k_base *ab)
|
||||
{
|
||||
struct device_node *wsi_dev = ab->dev->of_node, *next_wsi_dev;
|
||||
struct device_node *tx_endpoint, *next_rx_endpoint;
|
||||
int device_count = 0;
|
||||
struct device_node *next_wsi_dev;
|
||||
int device_count = 0, ret = 0;
|
||||
struct device_node *wsi_dev;
|
||||
|
||||
next_wsi_dev = wsi_dev;
|
||||
|
||||
if (!next_wsi_dev)
|
||||
wsi_dev = of_node_get(ab->dev->of_node);
|
||||
if (!wsi_dev)
|
||||
return -ENODEV;
|
||||
|
||||
do {
|
||||
ag->wsi_node[device_count] = next_wsi_dev;
|
||||
if (device_count >= ATH12K_MAX_DEVICES) {
|
||||
ath12k_warn(ab, "device count in DT %d is more than limit %d\n",
|
||||
device_count, ATH12K_MAX_DEVICES);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
tx_endpoint = of_graph_get_endpoint_by_regs(next_wsi_dev, 0, -1);
|
||||
ag->wsi_node[device_count++] = of_node_get(wsi_dev);
|
||||
|
||||
struct device_node *tx_endpoint __free(device_node) =
|
||||
of_graph_get_endpoint_by_regs(wsi_dev, 0, -1);
|
||||
if (!tx_endpoint) {
|
||||
of_node_put(next_wsi_dev);
|
||||
return -ENODEV;
|
||||
ret = -ENODEV;
|
||||
break;
|
||||
}
|
||||
|
||||
next_rx_endpoint = of_graph_get_remote_endpoint(tx_endpoint);
|
||||
struct device_node *next_rx_endpoint __free(device_node) =
|
||||
of_graph_get_remote_endpoint(tx_endpoint);
|
||||
if (!next_rx_endpoint) {
|
||||
of_node_put(next_wsi_dev);
|
||||
of_node_put(tx_endpoint);
|
||||
return -ENODEV;
|
||||
ret = -ENODEV;
|
||||
break;
|
||||
}
|
||||
|
||||
of_node_put(tx_endpoint);
|
||||
of_node_put(next_wsi_dev);
|
||||
|
||||
next_wsi_dev = of_graph_get_port_parent(next_rx_endpoint);
|
||||
if (!next_wsi_dev) {
|
||||
of_node_put(next_rx_endpoint);
|
||||
return -ENODEV;
|
||||
ret = -ENODEV;
|
||||
break;
|
||||
}
|
||||
|
||||
of_node_put(next_rx_endpoint);
|
||||
of_node_put(wsi_dev);
|
||||
wsi_dev = next_wsi_dev;
|
||||
} while (ab->dev->of_node != wsi_dev);
|
||||
|
||||
device_count++;
|
||||
if (device_count > ATH12K_MAX_DEVICES) {
|
||||
ath12k_warn(ab, "device count in DT %d is more than limit %d\n",
|
||||
device_count, ATH12K_MAX_DEVICES);
|
||||
of_node_put(next_wsi_dev);
|
||||
return -EINVAL;
|
||||
if (ret) {
|
||||
while (--device_count >= 0) {
|
||||
of_node_put(ag->wsi_node[device_count]);
|
||||
ag->wsi_node[device_count] = NULL;
|
||||
}
|
||||
} while (wsi_dev != next_wsi_dev);
|
||||
|
||||
of_node_put(next_wsi_dev);
|
||||
of_node_put(wsi_dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
of_node_put(wsi_dev);
|
||||
ag->num_devices = device_count;
|
||||
|
||||
return 0;
|
||||
|
|
@ -1983,9 +2002,9 @@ static struct ath12k_hw_group *ath12k_core_hw_group_assign(struct ath12k_base *a
|
|||
ath12k_core_get_wsi_index(ag, ab)) {
|
||||
ath12k_dbg(ab, ATH12K_DBG_BOOT,
|
||||
"unable to get wsi info from dt, grouping single device");
|
||||
ath12k_core_free_wsi_info(ag);
|
||||
ag->id = ATH12K_INVALID_GROUP_ID;
|
||||
ag->num_devices = 1;
|
||||
memset(ag->wsi_node, 0, sizeof(ag->wsi_node));
|
||||
wsi->index = 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -565,6 +565,9 @@ static int ath12k_dp_prepare_reo_update_elem(struct ath12k_dp *dp,
|
|||
|
||||
lockdep_assert_held(&dp->dp_lock);
|
||||
|
||||
if (!peer->primary_link)
|
||||
return 0;
|
||||
|
||||
elem = kzalloc_obj(*elem, GFP_ATOMIC);
|
||||
if (!elem)
|
||||
return -ENOMEM;
|
||||
|
|
@ -1337,7 +1340,7 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struc
|
|||
bool is_mcbc = rxcb->is_mcbc;
|
||||
bool is_eapol = rxcb->is_eapol;
|
||||
|
||||
peer = ath12k_dp_peer_find_by_peerid(dp_pdev, rx_info->peer_id);
|
||||
peer = ath12k_dp_peer_find_by_peerid(dp_pdev, rxcb->peer_id);
|
||||
|
||||
pubsta = peer ? peer->sta : NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -788,7 +788,7 @@ struct ath12k_link_vif *ath12k_mac_get_arvif(struct ath12k *ar, u32 vdev_id)
|
|||
|
||||
/* To use the arvif returned, caller must have held rcu read lock.
|
||||
*/
|
||||
WARN_ON(!rcu_read_lock_any_held());
|
||||
lockdep_assert_in_rcu_read_lock();
|
||||
arvif_iter.vdev_id = vdev_id;
|
||||
arvif_iter.ar = ar;
|
||||
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ static void ath12k_p2p_noa_update_vdev_iter(void *data, u8 *mac,
|
|||
struct ath12k_p2p_noa_arg *arg = data;
|
||||
struct ath12k_link_vif *arvif;
|
||||
|
||||
WARN_ON(!rcu_read_lock_any_held());
|
||||
lockdep_assert_in_rcu_read_lock();
|
||||
arvif = &ahvif->deflink;
|
||||
if (!arvif->is_created || arvif->ar != arg->ar || arvif->vdev_id != arg->vdev_id)
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -9778,7 +9778,7 @@ static void
|
|||
ath12k_wmi_rssi_dbm_conversion_params_info_event(struct ath12k_base *ab,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct ath12k_wmi_rssi_dbm_conv_info_arg rssi_info;
|
||||
struct ath12k_wmi_rssi_dbm_conv_info_arg rssi_info = {};
|
||||
struct ath12k *ar;
|
||||
s32 noise_floor;
|
||||
u32 pdev_id;
|
||||
|
|
@ -10251,7 +10251,7 @@ int ath12k_wmi_hw_data_filter_cmd(struct ath12k *ar, struct wmi_hw_data_filter_a
|
|||
{
|
||||
struct wmi_hw_data_filter_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
int len;
|
||||
int ret, len;
|
||||
|
||||
len = sizeof(*cmd);
|
||||
skb = ath12k_wmi_alloc_skb(ar->wmi->wmi_ab, len);
|
||||
|
|
@ -10275,7 +10275,13 @@ int ath12k_wmi_hw_data_filter_cmd(struct ath12k *ar, struct wmi_hw_data_filter_a
|
|||
"wmi hw data filter enable %d filter_bitmap 0x%x\n",
|
||||
arg->enable, arg->hw_filter_bitmap);
|
||||
|
||||
return ath12k_wmi_cmd_send(ar->wmi, skb, WMI_HW_DATA_FILTER_CMDID);
|
||||
ret = ath12k_wmi_cmd_send(ar->wmi, skb, WMI_HW_DATA_FILTER_CMDID);
|
||||
if (ret) {
|
||||
ath12k_warn(ar->ab, "failed to send WMI_HW_DATA_FILTER_CMDID\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath12k_wmi_wow_host_wakeup_ind(struct ath12k *ar)
|
||||
|
|
@ -10283,6 +10289,7 @@ int ath12k_wmi_wow_host_wakeup_ind(struct ath12k *ar)
|
|||
struct wmi_wow_host_wakeup_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
size_t len;
|
||||
int ret;
|
||||
|
||||
len = sizeof(*cmd);
|
||||
skb = ath12k_wmi_alloc_skb(ar->wmi->wmi_ab, len);
|
||||
|
|
@ -10295,14 +10302,20 @@ int ath12k_wmi_wow_host_wakeup_ind(struct ath12k *ar)
|
|||
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_WMI, "wmi tlv wow host wakeup ind\n");
|
||||
|
||||
return ath12k_wmi_cmd_send(ar->wmi, skb, WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID);
|
||||
ret = ath12k_wmi_cmd_send(ar->wmi, skb, WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID);
|
||||
if (ret) {
|
||||
ath12k_warn(ar->ab, "failed to send WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath12k_wmi_wow_enable(struct ath12k *ar)
|
||||
{
|
||||
struct wmi_wow_enable_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
int len;
|
||||
int ret, len;
|
||||
|
||||
len = sizeof(*cmd);
|
||||
skb = ath12k_wmi_alloc_skb(ar->wmi->wmi_ab, len);
|
||||
|
|
@ -10317,7 +10330,13 @@ int ath12k_wmi_wow_enable(struct ath12k *ar)
|
|||
cmd->pause_iface_config = cpu_to_le32(WOW_IFACE_PAUSE_ENABLED);
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_WMI, "wmi tlv wow enable\n");
|
||||
|
||||
return ath12k_wmi_cmd_send(ar->wmi, skb, WMI_WOW_ENABLE_CMDID);
|
||||
ret = ath12k_wmi_cmd_send(ar->wmi, skb, WMI_WOW_ENABLE_CMDID);
|
||||
if (ret) {
|
||||
ath12k_warn(ar->ab, "failed to send WMI_WOW_ENABLE_CMDID\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath12k_wmi_wow_add_wakeup_event(struct ath12k *ar, u32 vdev_id,
|
||||
|
|
@ -10327,6 +10346,7 @@ int ath12k_wmi_wow_add_wakeup_event(struct ath12k *ar, u32 vdev_id,
|
|||
struct wmi_wow_add_del_event_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
size_t len;
|
||||
int ret;
|
||||
|
||||
len = sizeof(*cmd);
|
||||
skb = ath12k_wmi_alloc_skb(ar->wmi->wmi_ab, len);
|
||||
|
|
@ -10343,7 +10363,13 @@ int ath12k_wmi_wow_add_wakeup_event(struct ath12k *ar, u32 vdev_id,
|
|||
ath12k_dbg(ar->ab, ATH12K_DBG_WMI, "wmi tlv wow add wakeup event %s enable %d vdev_id %d\n",
|
||||
wow_wakeup_event(event), enable, vdev_id);
|
||||
|
||||
return ath12k_wmi_cmd_send(ar->wmi, skb, WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID);
|
||||
ret = ath12k_wmi_cmd_send(ar->wmi, skb, WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID);
|
||||
if (ret) {
|
||||
ath12k_warn(ar->ab, "failed to send WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath12k_wmi_wow_add_pattern(struct ath12k *ar, u32 vdev_id, u32 pattern_id,
|
||||
|
|
@ -10356,6 +10382,7 @@ int ath12k_wmi_wow_add_pattern(struct ath12k *ar, u32 vdev_id, u32 pattern_id,
|
|||
struct sk_buff *skb;
|
||||
void *ptr;
|
||||
size_t len;
|
||||
int ret;
|
||||
|
||||
len = sizeof(*cmd) +
|
||||
sizeof(*tlv) + /* array struct */
|
||||
|
|
@ -10435,7 +10462,13 @@ int ath12k_wmi_wow_add_pattern(struct ath12k *ar, u32 vdev_id, u32 pattern_id,
|
|||
ath12k_dbg_dump(ar->ab, ATH12K_DBG_WMI, NULL, "wow bitmask: ",
|
||||
bitmap->bitmaskbuf, pattern_len);
|
||||
|
||||
return ath12k_wmi_cmd_send(ar->wmi, skb, WMI_WOW_ADD_WAKE_PATTERN_CMDID);
|
||||
ret = ath12k_wmi_cmd_send(ar->wmi, skb, WMI_WOW_ADD_WAKE_PATTERN_CMDID);
|
||||
if (ret) {
|
||||
ath12k_warn(ar->ab, "failed to send WMI_WOW_ADD_WAKE_PATTERN_CMDID\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath12k_wmi_wow_del_pattern(struct ath12k *ar, u32 vdev_id, u32 pattern_id)
|
||||
|
|
@ -10443,6 +10476,7 @@ int ath12k_wmi_wow_del_pattern(struct ath12k *ar, u32 vdev_id, u32 pattern_id)
|
|||
struct wmi_wow_del_pattern_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
size_t len;
|
||||
int ret;
|
||||
|
||||
len = sizeof(*cmd);
|
||||
skb = ath12k_wmi_alloc_skb(ar->wmi->wmi_ab, len);
|
||||
|
|
@ -10459,7 +10493,13 @@ int ath12k_wmi_wow_del_pattern(struct ath12k *ar, u32 vdev_id, u32 pattern_id)
|
|||
ath12k_dbg(ar->ab, ATH12K_DBG_WMI, "wmi tlv wow del pattern vdev_id %d pattern_id %d\n",
|
||||
vdev_id, pattern_id);
|
||||
|
||||
return ath12k_wmi_cmd_send(ar->wmi, skb, WMI_WOW_DEL_WAKE_PATTERN_CMDID);
|
||||
ret = ath12k_wmi_cmd_send(ar->wmi, skb, WMI_WOW_DEL_WAKE_PATTERN_CMDID);
|
||||
if (ret) {
|
||||
ath12k_warn(ar->ab, "failed to send WMI_WOW_DEL_WAKE_PATTERN_CMDID\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct sk_buff *
|
||||
|
|
@ -10595,6 +10635,7 @@ int ath12k_wmi_wow_config_pno(struct ath12k *ar, u32 vdev_id,
|
|||
struct wmi_pno_scan_req_arg *pno_scan)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
if (pno_scan->enable)
|
||||
skb = ath12k_wmi_op_gen_config_pno_start(ar, vdev_id, pno_scan);
|
||||
|
|
@ -10604,7 +10645,13 @@ int ath12k_wmi_wow_config_pno(struct ath12k *ar, u32 vdev_id,
|
|||
if (IS_ERR_OR_NULL(skb))
|
||||
return -ENOMEM;
|
||||
|
||||
return ath12k_wmi_cmd_send(ar->wmi, skb, WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID);
|
||||
ret = ath12k_wmi_cmd_send(ar->wmi, skb, WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID);
|
||||
if (ret) {
|
||||
ath12k_warn(ar->ab, "failed to send WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ath12k_wmi_fill_ns_offload(struct ath12k *ar,
|
||||
|
|
@ -10717,6 +10764,7 @@ int ath12k_wmi_arp_ns_offload(struct ath12k *ar,
|
|||
void *buf_ptr;
|
||||
size_t len;
|
||||
u8 ns_cnt, ns_ext_tuples = 0;
|
||||
int ret;
|
||||
|
||||
ns_cnt = offload->ipv6_count;
|
||||
|
||||
|
|
@ -10752,7 +10800,13 @@ int ath12k_wmi_arp_ns_offload(struct ath12k *ar,
|
|||
if (ns_ext_tuples)
|
||||
ath12k_wmi_fill_ns_offload(ar, offload, &buf_ptr, enable, 1);
|
||||
|
||||
return ath12k_wmi_cmd_send(ar->wmi, skb, WMI_SET_ARP_NS_OFFLOAD_CMDID);
|
||||
ret = ath12k_wmi_cmd_send(ar->wmi, skb, WMI_SET_ARP_NS_OFFLOAD_CMDID);
|
||||
if (ret) {
|
||||
ath12k_warn(ar->ab, "failed to send WMI_SET_ARP_NS_OFFLOAD_CMDID\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath12k_wmi_gtk_rekey_offload(struct ath12k *ar,
|
||||
|
|
@ -10762,7 +10816,7 @@ int ath12k_wmi_gtk_rekey_offload(struct ath12k *ar,
|
|||
struct wmi_gtk_rekey_offload_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
__le64 replay_ctr;
|
||||
int len;
|
||||
int ret, len;
|
||||
|
||||
len = sizeof(*cmd);
|
||||
skb = ath12k_wmi_alloc_skb(ar->wmi->wmi_ab, len);
|
||||
|
|
@ -10789,7 +10843,13 @@ int ath12k_wmi_gtk_rekey_offload(struct ath12k *ar,
|
|||
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_WMI, "offload gtk rekey vdev: %d %d\n",
|
||||
arvif->vdev_id, enable);
|
||||
return ath12k_wmi_cmd_send(ar->wmi, skb, WMI_GTK_OFFLOAD_CMDID);
|
||||
ret = ath12k_wmi_cmd_send(ar->wmi, skb, WMI_GTK_OFFLOAD_CMDID);
|
||||
if (ret) {
|
||||
ath12k_warn(ar->ab, "failed to send WMI_GTK_OFFLOAD_CMDID offload\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath12k_wmi_gtk_rekey_getinfo(struct ath12k *ar,
|
||||
|
|
@ -10797,7 +10857,7 @@ int ath12k_wmi_gtk_rekey_getinfo(struct ath12k *ar,
|
|||
{
|
||||
struct wmi_gtk_rekey_offload_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
int len;
|
||||
int ret, len;
|
||||
|
||||
len = sizeof(*cmd);
|
||||
skb = ath12k_wmi_alloc_skb(ar->wmi->wmi_ab, len);
|
||||
|
|
@ -10811,7 +10871,13 @@ int ath12k_wmi_gtk_rekey_getinfo(struct ath12k *ar,
|
|||
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_WMI, "get gtk rekey vdev_id: %d\n",
|
||||
arvif->vdev_id);
|
||||
return ath12k_wmi_cmd_send(ar->wmi, skb, WMI_GTK_OFFLOAD_CMDID);
|
||||
ret = ath12k_wmi_cmd_send(ar->wmi, skb, WMI_GTK_OFFLOAD_CMDID);
|
||||
if (ret) {
|
||||
ath12k_warn(ar->ab, "failed to send WMI_GTK_OFFLOAD_CMDID getinfo\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath12k_wmi_sta_keepalive(struct ath12k *ar,
|
||||
|
|
@ -10822,6 +10888,7 @@ int ath12k_wmi_sta_keepalive(struct ath12k *ar,
|
|||
struct wmi_sta_keepalive_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
size_t len;
|
||||
int ret;
|
||||
|
||||
len = sizeof(*cmd) + sizeof(*arp);
|
||||
skb = ath12k_wmi_alloc_skb(wmi->wmi_ab, len);
|
||||
|
|
@ -10849,7 +10916,13 @@ int ath12k_wmi_sta_keepalive(struct ath12k *ar,
|
|||
"wmi sta keepalive vdev %d enabled %d method %d interval %d\n",
|
||||
arg->vdev_id, arg->enabled, arg->method, arg->interval);
|
||||
|
||||
return ath12k_wmi_cmd_send(wmi, skb, WMI_STA_KEEPALIVE_CMDID);
|
||||
ret = ath12k_wmi_cmd_send(wmi, skb, WMI_STA_KEEPALIVE_CMDID);
|
||||
if (ret) {
|
||||
ath12k_warn(ar->ab, "failed to send WMI_STA_KEEPALIVE_CMDID\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath12k_wmi_mlo_setup(struct ath12k *ar, struct wmi_mlo_setup_arg *mlo_params)
|
||||
|
|
|
|||
|
|
@ -1738,7 +1738,8 @@ ath5k_tx_frame_completed(struct ath5k_hw *ah, struct sk_buff *skb,
|
|||
}
|
||||
|
||||
info->status.rates[ts->ts_final_idx].count = ts->ts_final_retry;
|
||||
info->status.rates[ts->ts_final_idx + 1].idx = -1;
|
||||
if (ts->ts_final_idx + 1 < IEEE80211_TX_MAX_RATES)
|
||||
info->status.rates[ts->ts_final_idx + 1].idx = -1;
|
||||
|
||||
if (unlikely(ts->ts_status)) {
|
||||
ah->stats.ack_fail++;
|
||||
|
|
|
|||
|
|
@ -702,7 +702,8 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
|
|||
* key index, but the ucode passed it slightly different.
|
||||
*/
|
||||
keyidx = b43_kidx_to_raw(dev, keyidx);
|
||||
B43_WARN_ON(keyidx >= ARRAY_SIZE(dev->key));
|
||||
if (B43_WARN_ON(keyidx >= ARRAY_SIZE(dev->key)))
|
||||
goto drop;
|
||||
|
||||
if (dev->key[keyidx].algorithm != B43_SEC_ALGO_NONE) {
|
||||
wlhdr_len = ieee80211_hdrlen(fctl);
|
||||
|
|
|
|||
|
|
@ -476,7 +476,8 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
|
|||
* key index, but the ucode passed it slightly different.
|
||||
*/
|
||||
keyidx = b43legacy_kidx_to_raw(dev, keyidx);
|
||||
B43legacy_WARN_ON(keyidx >= dev->max_nr_keys);
|
||||
if (B43legacy_WARN_ON(keyidx >= dev->max_nr_keys))
|
||||
goto drop;
|
||||
|
||||
if (dev->key[keyidx].algorithm != B43legacy_SEC_ALGO_NONE) {
|
||||
/* Remove PROTECTED flag to mark it as decrypted. */
|
||||
|
|
|
|||
|
|
@ -2476,8 +2476,9 @@ static void brcmf_sdio_bus_stop(struct device *dev)
|
|||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
if (bus->watchdog_tsk) {
|
||||
get_task_struct(bus->watchdog_tsk);
|
||||
send_sig(SIGTERM, bus->watchdog_tsk, 1);
|
||||
kthread_stop(bus->watchdog_tsk);
|
||||
kthread_stop_put(bus->watchdog_tsk);
|
||||
bus->watchdog_tsk = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -4567,8 +4568,9 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus)
|
|||
if (bus) {
|
||||
/* Stop watchdog task */
|
||||
if (bus->watchdog_tsk) {
|
||||
get_task_struct(bus->watchdog_tsk);
|
||||
send_sig(SIGTERM, bus->watchdog_tsk, 1);
|
||||
kthread_stop(bus->watchdog_tsk);
|
||||
kthread_stop_put(bus->watchdog_tsk);
|
||||
bus->watchdog_tsk = NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -310,6 +310,7 @@ static void if_usb_disconnect(struct usb_interface *intf)
|
|||
struct lbs_private *priv = cardp->priv;
|
||||
|
||||
cardp->surprise_removed = 1;
|
||||
wake_up(&cardp->fw_wq);
|
||||
|
||||
if (priv) {
|
||||
lbs_stop_card(priv);
|
||||
|
|
@ -633,9 +634,10 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
|
|||
unsigned long flags;
|
||||
u8 i;
|
||||
|
||||
if (recvlength > LBS_CMD_BUFFER_SIZE) {
|
||||
if (recvlength < MESSAGE_HEADER_LEN ||
|
||||
recvlength > LBS_CMD_BUFFER_SIZE) {
|
||||
lbs_deb_usbd(&cardp->udev->dev,
|
||||
"The receive buffer is too large\n");
|
||||
"The receive buffer is invalid: %d\n", recvlength);
|
||||
kfree_skb(skb);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,12 +70,11 @@ static inline int rsi_create_kthread(struct rsi_common *common,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int rsi_kill_thread(struct rsi_thread *handle)
|
||||
static inline void rsi_kill_thread(struct rsi_thread *handle)
|
||||
{
|
||||
atomic_inc(&handle->thread_done);
|
||||
rsi_set_event(&handle->event);
|
||||
|
||||
return kthread_stop(handle->task);
|
||||
wait_for_completion(&handle->completion);
|
||||
}
|
||||
|
||||
void rsi_mac80211_detach(struct rsi_hw *hw);
|
||||
|
|
|
|||
|
|
@ -264,14 +264,12 @@ int cw1200_wow_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
|
|||
wiphy_err(priv->hw->wiphy,
|
||||
"PM request failed: %d. WoW is disabled.\n", ret);
|
||||
cw1200_wow_resume(hw);
|
||||
mutex_unlock(&priv->conf_mutex);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* Force resume if event is coming from the device. */
|
||||
if (atomic_read(&priv->bh_rx)) {
|
||||
cw1200_wow_resume(hw);
|
||||
mutex_unlock(&priv->conf_mutex);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -437,6 +437,15 @@ ieee80211_verify_sta_ht_mcs_support(struct ieee80211_sub_if_data *sdata,
|
|||
memcpy(&sta_ht_cap, &sband->ht_cap, sizeof(sta_ht_cap));
|
||||
ieee80211_apply_htcap_overrides(sdata, &sta_ht_cap);
|
||||
|
||||
/*
|
||||
* Some Xfinity XB8 firmware advertises >1 spatial stream MCS indexes in
|
||||
* their basic HT-MCS set. On cards with lower spatial streams, the check
|
||||
* would fail, and we'd be stuck with no HT when it in fact work fine with
|
||||
* its own supported rate. So check it only in strict mode.
|
||||
*/
|
||||
if (!ieee80211_hw_check(&sdata->local->hw, STRICT))
|
||||
return true;
|
||||
|
||||
/*
|
||||
* P802.11REVme/D7.0 - 6.5.4.2.4
|
||||
* ...
|
||||
|
|
@ -9140,7 +9149,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
|
|||
struct ieee80211_bss *bss = (void *)cbss->priv;
|
||||
struct sta_info *new_sta = NULL;
|
||||
struct ieee80211_link_data *link;
|
||||
bool have_sta = false;
|
||||
struct sta_info *have_sta = NULL;
|
||||
bool mlo;
|
||||
int err;
|
||||
u16 new_links;
|
||||
|
|
@ -9159,11 +9168,8 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
|
|||
mlo = false;
|
||||
}
|
||||
|
||||
if (assoc) {
|
||||
rcu_read_lock();
|
||||
if (assoc)
|
||||
have_sta = sta_info_get(sdata, ap_mld_addr);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
if (mlo && !have_sta &&
|
||||
WARN_ON(sdata->vif.valid_links || sdata->vif.active_links))
|
||||
|
|
@ -9327,6 +9333,8 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
|
|||
out_release_chan:
|
||||
ieee80211_link_release_channel(link);
|
||||
out_err:
|
||||
if (mlo && have_sta)
|
||||
WARN_ON(__sta_info_destroy(have_sta));
|
||||
ieee80211_vif_set_links(sdata, 0, 0);
|
||||
return err;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4971,7 +4971,7 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
|
|||
struct sk_buff *skb = rx->skb;
|
||||
struct ieee80211_hdr *hdr = (void *)skb->data;
|
||||
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
|
||||
static ieee80211_rx_result res;
|
||||
ieee80211_rx_result res;
|
||||
int orig_len = skb->len;
|
||||
int hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
||||
int snap_offs = hdrlen;
|
||||
|
|
@ -5380,7 +5380,9 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
|
|||
if (!link_sta)
|
||||
goto out;
|
||||
|
||||
ieee80211_rx_data_set_link(&rx, link_sta->link_id);
|
||||
if (!ieee80211_rx_data_set_link(&rx,
|
||||
link_sta->link_id))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ static const struct determine_chan_mode_case {
|
|||
.ht_capa_mask = {
|
||||
.mcs.rx_mask[0] = 0xf7,
|
||||
},
|
||||
.strict = true,
|
||||
}, {
|
||||
.desc = "Masking out a RX rate in VHT capabilities",
|
||||
.conn_mode = IEEE80211_CONN_MODE_EHT,
|
||||
|
|
|
|||
|
|
@ -3700,11 +3700,11 @@ void ieee80211_dfs_radar_detected_work(struct wiphy *wiphy,
|
|||
struct ieee80211_local *local =
|
||||
container_of(work, struct ieee80211_local, radar_detected_work);
|
||||
struct cfg80211_chan_def chandef;
|
||||
struct ieee80211_chanctx *ctx;
|
||||
struct ieee80211_chanctx *ctx, *tmp;
|
||||
|
||||
lockdep_assert_wiphy(local->hw.wiphy);
|
||||
|
||||
list_for_each_entry(ctx, &local->chanctx_list, list) {
|
||||
list_for_each_entry_safe(ctx, tmp, &local->chanctx_list, list) {
|
||||
if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER)
|
||||
continue;
|
||||
|
||||
|
|
|
|||
|
|
@ -1276,6 +1276,18 @@ static int nl80211_prepare_wdev_dump(struct netlink_callback *cb,
|
|||
rtnl_unlock();
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*
|
||||
* The first invocation validated the wdev's netns against
|
||||
* the caller via __cfg80211_wdev_from_attrs(). The wiphy
|
||||
* may have moved netns between dumpit invocations (via
|
||||
* NL80211_CMD_SET_WIPHY_NETNS), so re-check here.
|
||||
*/
|
||||
if (!net_eq(wiphy_net(wiphy), sock_net(cb->skb->sk))) {
|
||||
rtnl_unlock();
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
*rdev = wiphy_to_rdev(wiphy);
|
||||
*wdev = NULL;
|
||||
|
||||
|
|
@ -13867,6 +13879,19 @@ static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
|
|||
if (IS_ERR(net))
|
||||
return PTR_ERR(net);
|
||||
|
||||
/*
|
||||
* The caller already has CAP_NET_ADMIN over the source netns
|
||||
* (enforced by GENL_UNS_ADMIN_PERM on the genl op). Mirror the
|
||||
* convention used by net/core/rtnetlink.c::rtnl_get_net_ns_capable()
|
||||
* and require CAP_NET_ADMIN over the target netns as well, so that
|
||||
* a caller that is privileged in their own user namespace cannot
|
||||
* push a wiphy into a netns where they have no privilege.
|
||||
*/
|
||||
if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) {
|
||||
put_net(net);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
err = 0;
|
||||
|
||||
/* check if anything to do */
|
||||
|
|
@ -19828,6 +19853,7 @@ static const struct genl_small_ops nl80211_small_ops[] = {
|
|||
.cmd = NL80211_CMD_SET_PMK,
|
||||
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||
.doit = nl80211_set_pmk,
|
||||
.flags = GENL_UNS_ADMIN_PERM,
|
||||
.internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
|
||||
NL80211_FLAG_CLEAR_SKB),
|
||||
},
|
||||
|
|
@ -19835,6 +19861,7 @@ static const struct genl_small_ops nl80211_small_ops[] = {
|
|||
.cmd = NL80211_CMD_DEL_PMK,
|
||||
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||
.doit = nl80211_del_pmk,
|
||||
.flags = GENL_UNS_ADMIN_PERM,
|
||||
.internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,
|
|||
out->ftm.ftms_per_burst = 0;
|
||||
if (tb[NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST])
|
||||
out->ftm.ftms_per_burst =
|
||||
nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST]);
|
||||
nla_get_u8(tb[NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST]);
|
||||
|
||||
if (capa->ftm.max_ftms_per_burst &&
|
||||
(out->ftm.ftms_per_burst > capa->ftm.max_ftms_per_burst ||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user