4.20-stable review patch.  If anyone has any objections, please let me know.

------------------

[ Upstream commit 8020919a9b99d6c990dc6a50e8215e291fbbe5a6 ]

The monitor interface Rx handling of SKBs that contain only
radiotap information was buggy as it tried to access the
SKB assuming it contains a frame.

To fix this, check the RX_FLAG_NO_PSDU flag in the Rx status
(indicting that the SKB contains only radiotap information),
and do not perform data path specific processing when the flag
is set.

Signed-off-by: Ilan Peer <ilan.p...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
Signed-off-by: Johannes Berg <johannes.b...@intel.com>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 net/mac80211/rx.c | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 428f7ad5f9b5..77d996a60f12 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -753,6 +753,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct 
sk_buff *origskb,
        struct ieee80211_sub_if_data *monitor_sdata =
                rcu_dereference(local->monitor_sdata);
        bool only_monitor = false;
+       unsigned int min_head_len;
 
        if (status->flag & RX_FLAG_RADIOTAP_HE)
                rtap_space += sizeof(struct ieee80211_radiotap_he);
@@ -766,6 +767,8 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct 
sk_buff *origskb,
                rtap_space += sizeof(*rtap) + rtap->len + rtap->pad;
        }
 
+       min_head_len = rtap_space;
+
        /*
         * First, we may need to make a copy of the skb because
         *  (1) we need to modify it for radiotap (if not present), and
@@ -775,18 +778,23 @@ ieee80211_rx_monitor(struct ieee80211_local *local, 
struct sk_buff *origskb,
         * the SKB because it has a bad FCS/PLCP checksum.
         */
 
-       if (ieee80211_hw_check(&local->hw, RX_INCLUDES_FCS)) {
-               if (unlikely(origskb->len <= FCS_LEN)) {
-                       /* driver bug */
-                       WARN_ON(1);
-                       dev_kfree_skb(origskb);
-                       return NULL;
+       if (!(status->flag & RX_FLAG_NO_PSDU)) {
+               if (ieee80211_hw_check(&local->hw, RX_INCLUDES_FCS)) {
+                       if (unlikely(origskb->len <= FCS_LEN + rtap_space)) {
+                               /* driver bug */
+                               WARN_ON(1);
+                               dev_kfree_skb(origskb);
+                               return NULL;
+                       }
+                       present_fcs_len = FCS_LEN;
                }
-               present_fcs_len = FCS_LEN;
+
+               /* also consider the hdr->frame_control */
+               min_head_len += 2;
        }
 
-       /* ensure hdr->frame_control and vendor radiotap data are in skb head */
-       if (!pskb_may_pull(origskb, 2 + rtap_space)) {
+       /* ensure that the expected data elements are in skb head */
+       if (!pskb_may_pull(origskb, min_head_len)) {
                dev_kfree_skb(origskb);
                return NULL;
        }
-- 
2.19.1



Reply via email to