Commit 6b36d68c authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
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.net


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents b2bc47e9 12b220a6
Loading
Loading
Loading
Loading
+16 −13
Original line number Diff line number Diff line
@@ -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;

+2 −1
Original line number Diff line number Diff line
@@ -1264,6 +1264,7 @@ static int __must_check __sta_info_destroy_part1(struct sta_info *sta)
	list_del_rcu(&sta->list);
	sta->removed = true;

	if (sta->uploaded)
		drv_sta_pre_rcu_remove(local, sta->sdata, sta);

	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
+1 −1
Original line number Diff line number Diff line
@@ -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;