mac80211: Properly handle SKB with radiotap only
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.peer@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Родитель
925b5978cd
Коммит
8020919a9b
|
@ -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;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче