aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-11-22 04:20:58 -0500
committerJohannes Berg <johannes.berg@intel.com>2012-11-23 02:41:25 -0500
commit605f1a5b5e87cf4005b56b77083ff473c846431a (patch)
tree58e7ba4e8e809d3c8cc6854a13159277c3f5daa0 /net/mac80211/rx.c
parent77d2ece6fde80631193054edc9c9a3edad519565 (diff)
mac80211: fix radiotap vendor area skipping
The radiotap vendor area in the skb head must be skipped and accounted for in a few functions until it is removed. I missed this in my patch, so a few places use this data as though it was the 802.11 header, fix these places. Reported-by: Wojciech Dubowik <Wojciech.Dubowik@neratec.com> Tested-by: Wojciech Dubowik <Wojciech.Dubowik@neratec.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index ec15a4929f7a..ec879029ac43 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -62,13 +62,16 @@ static struct sk_buff *remove_monitor_info(struct ieee80211_local *local,
62static inline int should_drop_frame(struct sk_buff *skb, int present_fcs_len) 62static inline int should_drop_frame(struct sk_buff *skb, int present_fcs_len)
63{ 63{
64 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 64 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
65 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 65 struct ieee80211_hdr *hdr;
66
67 hdr = (void *)(skb->data + status->vendor_radiotap_len);
66 68
67 if (status->flag & (RX_FLAG_FAILED_FCS_CRC | 69 if (status->flag & (RX_FLAG_FAILED_FCS_CRC |
68 RX_FLAG_FAILED_PLCP_CRC | 70 RX_FLAG_FAILED_PLCP_CRC |
69 RX_FLAG_AMPDU_IS_ZEROLEN)) 71 RX_FLAG_AMPDU_IS_ZEROLEN))
70 return 1; 72 return 1;
71 if (unlikely(skb->len < 16 + present_fcs_len)) 73 if (unlikely(skb->len < 16 + present_fcs_len +
74 status->vendor_radiotap_len))
72 return 1; 75 return 1;
73 if (ieee80211_is_ctl(hdr->frame_control) && 76 if (ieee80211_is_ctl(hdr->frame_control) &&
74 !ieee80211_is_pspoll(hdr->frame_control) && 77 !ieee80211_is_pspoll(hdr->frame_control) &&
@@ -341,8 +344,8 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
341 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) 344 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
342 present_fcs_len = FCS_LEN; 345 present_fcs_len = FCS_LEN;
343 346
344 /* make sure hdr->frame_control is on the linear part */ 347 /* ensure hdr->frame_control and vendor radiotap data are in skb head */
345 if (!pskb_may_pull(origskb, 2)) { 348 if (!pskb_may_pull(origskb, 2 + status->vendor_radiotap_len)) {
346 dev_kfree_skb(origskb); 349 dev_kfree_skb(origskb);
347 return NULL; 350 return NULL;
348 } 351 }