diff options
author | Johannes Berg <johannes.berg@intel.com> | 2012-10-25 15:51:59 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2012-10-26 16:52:41 -0400 |
commit | 7dd111e8ee10cc6816669eabcad3334447673236 (patch) | |
tree | 5fa3735180c86601d8f5805e72e0a3752cdb1a43 /net | |
parent | badecb001a310408d3473b1fc2ed5aefd0bc92a9 (diff) |
wireless: drop invalid mesh address extension frames
The mesh header can have address extension by a 4th
or a 5th and 6th address, but never both. Drop such
frames in 802.11 -> 802.3 conversion along with any
frames that have the wrong extension.
Cc: stable@vger.kernel.org
Reviewed-by: Javier Cardona <javier@cozybit.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/wireless/util.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/net/wireless/util.c b/net/wireless/util.c index ef35f4ef2aa6..45a09de1ffe3 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -312,18 +312,15 @@ EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb); | |||
312 | static int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) | 312 | static int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) |
313 | { | 313 | { |
314 | int ae = meshhdr->flags & MESH_FLAGS_AE; | 314 | int ae = meshhdr->flags & MESH_FLAGS_AE; |
315 | /* 7.1.3.5a.2 */ | 315 | /* 802.11-2012, 8.2.4.7.3 */ |
316 | switch (ae) { | 316 | switch (ae) { |
317 | default: | ||
317 | case 0: | 318 | case 0: |
318 | return 6; | 319 | return 6; |
319 | case MESH_FLAGS_AE_A4: | 320 | case MESH_FLAGS_AE_A4: |
320 | return 12; | 321 | return 12; |
321 | case MESH_FLAGS_AE_A5_A6: | 322 | case MESH_FLAGS_AE_A5_A6: |
322 | return 18; | 323 | return 18; |
323 | case (MESH_FLAGS_AE_A4 | MESH_FLAGS_AE_A5_A6): | ||
324 | return 24; | ||
325 | default: | ||
326 | return 6; | ||
327 | } | 324 | } |
328 | } | 325 | } |
329 | 326 | ||
@@ -373,6 +370,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, | |||
373 | /* make sure meshdr->flags is on the linear part */ | 370 | /* make sure meshdr->flags is on the linear part */ |
374 | if (!pskb_may_pull(skb, hdrlen + 1)) | 371 | if (!pskb_may_pull(skb, hdrlen + 1)) |
375 | return -1; | 372 | return -1; |
373 | if (meshdr->flags & MESH_FLAGS_AE_A4) | ||
374 | return -1; | ||
376 | if (meshdr->flags & MESH_FLAGS_AE_A5_A6) { | 375 | if (meshdr->flags & MESH_FLAGS_AE_A5_A6) { |
377 | skb_copy_bits(skb, hdrlen + | 376 | skb_copy_bits(skb, hdrlen + |
378 | offsetof(struct ieee80211s_hdr, eaddr1), | 377 | offsetof(struct ieee80211s_hdr, eaddr1), |
@@ -397,6 +396,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, | |||
397 | /* make sure meshdr->flags is on the linear part */ | 396 | /* make sure meshdr->flags is on the linear part */ |
398 | if (!pskb_may_pull(skb, hdrlen + 1)) | 397 | if (!pskb_may_pull(skb, hdrlen + 1)) |
399 | return -1; | 398 | return -1; |
399 | if (meshdr->flags & MESH_FLAGS_AE_A5_A6) | ||
400 | return -1; | ||
400 | if (meshdr->flags & MESH_FLAGS_AE_A4) | 401 | if (meshdr->flags & MESH_FLAGS_AE_A4) |
401 | skb_copy_bits(skb, hdrlen + | 402 | skb_copy_bits(skb, hdrlen + |
402 | offsetof(struct ieee80211s_hdr, eaddr1), | 403 | offsetof(struct ieee80211s_hdr, eaddr1), |