diff options
author | Patrick McHardy <kaber@trash.net> | 2010-04-20 10:02:01 -0400 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2010-04-20 10:02:01 -0400 |
commit | 62910554656cdcd6b6f84a5154c4155aae4ca231 (patch) | |
tree | dcf14004f6fd2ef7154362ff948bfeba0f3ea92d /net/wireless/util.c | |
parent | 22265a5c3c103cf8c50be62e6c90d045eb649e6d (diff) | |
parent | ab9304717f7624c41927f442e6b6d418b2d8b3e4 (diff) |
Merge branch 'master' of /repos/git/net-next-2.6
Conflicts:
Documentation/feature-removal-schedule.txt
net/ipv6/netfilter/ip6t_REJECT.c
net/netfilter/xt_limit.c
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/wireless/util.c')
-rw-r--r-- | net/wireless/util.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/net/wireless/util.c b/net/wireless/util.c index be2ab8c59e3a..3416373a9c0c 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -5,6 +5,7 @@ | |||
5 | */ | 5 | */ |
6 | #include <linux/bitops.h> | 6 | #include <linux/bitops.h> |
7 | #include <linux/etherdevice.h> | 7 | #include <linux/etherdevice.h> |
8 | #include <linux/slab.h> | ||
8 | #include <net/cfg80211.h> | 9 | #include <net/cfg80211.h> |
9 | #include <net/ip.h> | 10 | #include <net/ip.h> |
10 | #include "core.h" | 11 | #include "core.h" |
@@ -330,11 +331,18 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, | |||
330 | if (iftype == NL80211_IFTYPE_MESH_POINT) { | 331 | if (iftype == NL80211_IFTYPE_MESH_POINT) { |
331 | struct ieee80211s_hdr *meshdr = | 332 | struct ieee80211s_hdr *meshdr = |
332 | (struct ieee80211s_hdr *) (skb->data + hdrlen); | 333 | (struct ieee80211s_hdr *) (skb->data + hdrlen); |
333 | hdrlen += ieee80211_get_mesh_hdrlen(meshdr); | 334 | /* make sure meshdr->flags is on the linear part */ |
335 | if (!pskb_may_pull(skb, hdrlen + 1)) | ||
336 | return -1; | ||
334 | if (meshdr->flags & MESH_FLAGS_AE_A5_A6) { | 337 | if (meshdr->flags & MESH_FLAGS_AE_A5_A6) { |
335 | memcpy(dst, meshdr->eaddr1, ETH_ALEN); | 338 | skb_copy_bits(skb, hdrlen + |
336 | memcpy(src, meshdr->eaddr2, ETH_ALEN); | 339 | offsetof(struct ieee80211s_hdr, eaddr1), |
340 | dst, ETH_ALEN); | ||
341 | skb_copy_bits(skb, hdrlen + | ||
342 | offsetof(struct ieee80211s_hdr, eaddr2), | ||
343 | src, ETH_ALEN); | ||
337 | } | 344 | } |
345 | hdrlen += ieee80211_get_mesh_hdrlen(meshdr); | ||
338 | } | 346 | } |
339 | break; | 347 | break; |
340 | case cpu_to_le16(IEEE80211_FCTL_FROMDS): | 348 | case cpu_to_le16(IEEE80211_FCTL_FROMDS): |
@@ -346,9 +354,14 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, | |||
346 | if (iftype == NL80211_IFTYPE_MESH_POINT) { | 354 | if (iftype == NL80211_IFTYPE_MESH_POINT) { |
347 | struct ieee80211s_hdr *meshdr = | 355 | struct ieee80211s_hdr *meshdr = |
348 | (struct ieee80211s_hdr *) (skb->data + hdrlen); | 356 | (struct ieee80211s_hdr *) (skb->data + hdrlen); |
349 | hdrlen += ieee80211_get_mesh_hdrlen(meshdr); | 357 | /* make sure meshdr->flags is on the linear part */ |
358 | if (!pskb_may_pull(skb, hdrlen + 1)) | ||
359 | return -1; | ||
350 | if (meshdr->flags & MESH_FLAGS_AE_A4) | 360 | if (meshdr->flags & MESH_FLAGS_AE_A4) |
351 | memcpy(src, meshdr->eaddr1, ETH_ALEN); | 361 | skb_copy_bits(skb, hdrlen + |
362 | offsetof(struct ieee80211s_hdr, eaddr1), | ||
363 | src, ETH_ALEN); | ||
364 | hdrlen += ieee80211_get_mesh_hdrlen(meshdr); | ||
352 | } | 365 | } |
353 | break; | 366 | break; |
354 | case cpu_to_le16(0): | 367 | case cpu_to_le16(0): |
@@ -357,7 +370,7 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, | |||
357 | break; | 370 | break; |
358 | } | 371 | } |
359 | 372 | ||
360 | if (unlikely(skb->len - hdrlen < 8)) | 373 | if (!pskb_may_pull(skb, hdrlen + 8)) |
361 | return -1; | 374 | return -1; |
362 | 375 | ||
363 | payload = skb->data + hdrlen; | 376 | payload = skb->data + hdrlen; |