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), |
