diff --git a/include/net/mac80211.h b/include/net/mac80211.h index f147bc019e7b..7bb4618065b6 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -7630,11 +7630,12 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw, * * @skb: packet injected by userspace * @dev: the &struct device of this 802.11 device + * @trim_fcs: trim the FCS trailer when present; validate it otherwise * * Return: %true if the radiotap header was parsed, %false otherwise */ bool ieee80211_parse_tx_radiotap(struct sk_buff *skb, - struct net_device *dev); + struct net_device *dev, bool trim_fcs); /** * struct ieee80211_noa_data - holds temporary data for tracking P2P NoA state diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 43460a705a6b..fdac729ca580 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -964,7 +964,7 @@ static u16 ieee80211_monitor_select_queue(struct net_device *dev, /* reset flags and info before parsing radiotap header */ memset(info, 0, sizeof(*info)); - if (!ieee80211_parse_tx_radiotap(skb, dev)) + if (!ieee80211_parse_tx_radiotap(skb, dev, false)) return 0; /* doesn't matter, frame will be dropped */ len_rthdr = ieee80211_get_radiotap_len(skb->data); diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 7d34b160fddd..c33092960df2 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -2138,7 +2138,7 @@ static bool ieee80211_validate_radiotap_len(struct sk_buff *skb) } bool ieee80211_parse_tx_radiotap(struct sk_buff *skb, - struct net_device *dev) + struct net_device *dev, bool trim_fcs) { struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_radiotap_iterator iterator; @@ -2195,7 +2195,8 @@ bool ieee80211_parse_tx_radiotap(struct sk_buff *skb, if (skb->len < (iterator._max_length + FCS_LEN)) return false; - skb_trim(skb, skb->len - FCS_LEN); + if (trim_fcs) + skb_trim(skb, skb->len - FCS_LEN); } if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP) info->flags &= ~IEEE80211_TX_INTFL_DONT_ENCRYPT; @@ -2511,7 +2512,7 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, * selected chandef above to accurately set injection rates and * retransmissions. */ - if (!ieee80211_parse_tx_radiotap(skb, dev)) + if (!ieee80211_parse_tx_radiotap(skb, dev, true)) goto fail_rcu; /* remove the injection radiotap header */