| From 6dbda2d00d466225f9db1dc695ff852443f28832 Mon Sep 17 00:00:00 2001 |
| From: Johannes Berg <johannes.berg@intel.com> |
| Date: Fri, 26 Oct 2012 00:41:23 +0200 |
| Subject: mac80211: make sure data is accessible in EAPOL check |
| |
| From: Johannes Berg <johannes.berg@intel.com> |
| |
| commit 6dbda2d00d466225f9db1dc695ff852443f28832 upstream. |
| |
| The code to allow EAPOL frames even when the station |
| isn't yet marked associated needs to check that the |
| incoming frame is long enough and due to paged RX it |
| also can't assume skb->data contains the right data, |
| it must use skb_copy_bits(). Fix this to avoid using |
| data that doesn't really exist. |
| |
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| net/mac80211/rx.c | 16 +++++++++------- |
| 1 file changed, 9 insertions(+), 7 deletions(-) |
| |
| --- a/net/mac80211/rx.c |
| +++ b/net/mac80211/rx.c |
| @@ -848,14 +848,16 @@ ieee80211_rx_h_check(struct ieee80211_rx |
| */ |
| if (rx->sta && rx->sdata->vif.type == NL80211_IFTYPE_STATION && |
| ieee80211_is_data_present(hdr->frame_control)) { |
| - u16 ethertype; |
| - u8 *payload; |
| + unsigned int hdrlen; |
| + __be16 ethertype; |
| |
| - payload = rx->skb->data + |
| - ieee80211_hdrlen(hdr->frame_control); |
| - ethertype = (payload[6] << 8) | payload[7]; |
| - if (cpu_to_be16(ethertype) == |
| - rx->sdata->control_port_protocol) |
| + hdrlen = ieee80211_hdrlen(hdr->frame_control); |
| + |
| + if (rx->skb->len < hdrlen + 8) |
| + return RX_DROP_MONITOR; |
| + |
| + skb_copy_bits(rx->skb, hdrlen + 6, ðertype, 2); |
| + if (ethertype == rx->sdata->control_port_protocol) |
| return RX_CONTINUE; |
| } |
| |