diff options
author | Denis Kenzior <denkenz@gmail.com> | 2018-07-03 15:05:48 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2018-07-06 14:34:42 +0200 |
commit | a948f713842ad5c23f125efc61dee6951893219c (patch) | |
tree | e00954fd546b1415958c866e374861a0bfd90496 /net/mac80211 | |
parent | 19103a4bfb42f320395daa5616ece3e89e759d63 (diff) |
nl80211/mac80211: allow non-linear skb in rx_control_port
The current implementation of cfg80211_rx_control_port assumed that the
caller could provide a contiguous region of memory for the control port
frame to be sent up to userspace. Unfortunately, many drivers produce
non-linear skbs, especially for data frames. This resulted in userspace
getting notified of control port frames with correct metadata (from
address, port, etc) yet garbage / nonsense contents, resulting in bad
handshakes, disconnections, etc.
mac80211 linearizes skbs containing management frames. But it didn't
seem worthwhile to do this for control port frames. Thus the signature
of cfg80211_rx_control_port was changed to take the skb directly.
nl80211 then takes care of obtaining control port frame data directly
from the (linear | non-linear) skb.
The caller is still responsible for freeing the skb,
cfg80211_rx_control_port does not take ownership of it.
Fixes: 6a671a50f819 ("nl80211: Add CMD_CONTROL_PORT_FRAME API")
Signed-off-by: Denis Kenzior <denkenz@gmail.com>
[fix some kernel-doc formatting, add fixes tag]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/rx.c | 5 |
1 files changed, 1 insertions, 4 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 0a38cc1cbebc..932985ca4e66 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2254,11 +2254,8 @@ static void ieee80211_deliver_skb_to_local_stack(struct sk_buff *skb, sdata->control_port_over_nl80211)) { struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); bool noencrypt = status->flag & RX_FLAG_DECRYPTED; - struct ethhdr *ehdr = eth_hdr(skb); - cfg80211_rx_control_port(dev, skb->data, skb->len, - ehdr->h_source, - be16_to_cpu(skb->protocol), noencrypt); + cfg80211_rx_control_port(dev, skb, noencrypt); dev_kfree_skb(skb); } else { /* deliver to local stack */ |