Commit 6b36d68c authored by Jakub Kicinski's avatar Jakub Kicinski

Merge tag 'wireless-2023-03-30' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless

Johannes Berg says:

====================
Just a few fixes:

 * fix size calculation for EHT element to put into SKBs
 * remove erroneous pre-RCU calls for drivers not using sta_state calls
 * fix mesh forwarding and non-forwarding RX
 * fix mesh flow dissection
 * fix a potential NULL dereference on A-MSDU RX w/o station
 * make two variable non-static that really shouldn't be static

* tag 'wireless-2023-03-30' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless:
  wifi: mac80211: fix invalid drv_sta_pre_rcu_remove calls for non-uploaded sta
  wifi: mac80211: fix flow dissection for forwarded packets
  wifi: mac80211: fix mesh forwarding
  wifi: mac80211: fix receiving mesh packets in forwarding=0 networks
  wifi: mac80211: fix the size calculation of ieee80211_ie_len_eht_cap()
  wifi: mac80211: fix potential null pointer dereference
  wifi: mac80211: drop bogus static keywords in A-MSDU rx
====================

Link: https://lore.kernel.org/r/20230330203313.919164-1-johannes@sipsolutions.netSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents b2bc47e9 12b220a6
......@@ -2769,14 +2769,6 @@ ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta
if (sdata->crypto_tx_tailroom_needed_cnt)
tailroom = IEEE80211_ENCRYPT_TAILROOM;
if (!--mesh_hdr->ttl) {
if (multicast)
goto rx_accept;
IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl);
return RX_DROP_MONITOR;
}
if (mesh_hdr->flags & MESH_FLAGS_AE) {
struct mesh_path *mppath;
char *proxied_addr;
......@@ -2807,6 +2799,14 @@ ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta
if (ether_addr_equal(sdata->vif.addr, eth->h_dest))
goto rx_accept;
if (!--mesh_hdr->ttl) {
if (multicast)
goto rx_accept;
IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl);
return RX_DROP_MONITOR;
}
if (!ifmsh->mshcfg.dot11MeshForwarding) {
if (is_multicast_ether_addr(eth->h_dest))
goto rx_accept;
......@@ -2833,6 +2833,9 @@ ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta
if (skb_cow_head(fwd_skb, hdrlen - sizeof(struct ethhdr)))
return RX_DROP_UNUSABLE;
if (skb_linearize(fwd_skb))
return RX_DROP_UNUSABLE;
}
fwd_hdr = skb_push(fwd_skb, hdrlen - sizeof(struct ethhdr));
......@@ -2847,7 +2850,7 @@ ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta
hdrlen += ETH_ALEN;
else
fwd_skb->protocol = htons(fwd_skb->len - hdrlen);
skb_set_network_header(fwd_skb, hdrlen);
skb_set_network_header(fwd_skb, hdrlen + 2);
info = IEEE80211_SKB_CB(fwd_skb);
memset(info, 0, sizeof(*info));
......@@ -2896,7 +2899,7 @@ __ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx, u8 data_offset)
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
__le16 fc = hdr->frame_control;
struct sk_buff_head frame_list;
static ieee80211_rx_result res;
ieee80211_rx_result res;
struct ethhdr ethhdr;
const u8 *check_da = ethhdr.h_dest, *check_sa = ethhdr.h_source;
......@@ -2930,7 +2933,7 @@ __ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx, u8 data_offset)
data_offset, true))
return RX_DROP_UNUSABLE;
if (rx->sta && rx->sta->amsdu_mesh_control < 0) {
if (rx->sta->amsdu_mesh_control < 0) {
bool valid_std = ieee80211_is_valid_amsdu(skb, true);
bool valid_nonstd = ieee80211_is_valid_amsdu(skb, false);
......@@ -3006,7 +3009,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
}
}
if (is_multicast_ether_addr(hdr->addr1))
if (is_multicast_ether_addr(hdr->addr1) || !rx->sta)
return RX_DROP_UNUSABLE;
if (rx->key) {
......@@ -3037,7 +3040,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
struct net_device *dev = sdata->dev;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
__le16 fc = hdr->frame_control;
static ieee80211_rx_result res;
ieee80211_rx_result res;
bool port_control;
int err;
......
......@@ -1264,7 +1264,8 @@ static int __must_check __sta_info_destroy_part1(struct sta_info *sta)
list_del_rcu(&sta->list);
sta->removed = true;
drv_sta_pre_rcu_remove(local, sta->sdata, sta);
if (sta->uploaded)
drv_sta_pre_rcu_remove(local, sta->sdata, sta);
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
rcu_access_pointer(sdata->u.vlan.sta) == sta)
......
......@@ -4906,7 +4906,7 @@ u8 ieee80211_ie_len_eht_cap(struct ieee80211_sub_if_data *sdata, u8 iftype)
&eht_cap->eht_cap_elem,
is_ap);
return 2 + 1 +
sizeof(he_cap->he_cap_elem) + n +
sizeof(eht_cap->eht_cap_elem) + n +
ieee80211_eht_ppe_size(eht_cap->eht_ppe_thres[0],
eht_cap->eht_cap_elem.phy_cap_info);
return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment