diff options
| author | Patrick McHardy <kaber@trash.net> | 2010-04-20 16:02:01 +0200 | 
|---|---|---|
| committer | Patrick McHardy <kaber@trash.net> | 2010-04-20 16:02:01 +0200 | 
| commit | 62910554656cdcd6b6f84a5154c4155aae4ca231 (patch) | |
| tree | dcf14004f6fd2ef7154362ff948bfeba0f3ea92d /net/wireless/util.c | |
| parent | 22265a5c3c103cf8c50be62e6c90d045eb649e6d (diff) | |
| parent | ab9304717f7624c41927f442e6b6d418b2d8b3e4 (diff) | |
| download | olio-linux-3.10-62910554656cdcd6b6f84a5154c4155aae4ca231.tar.xz olio-linux-3.10-62910554656cdcd6b6f84a5154c4155aae4ca231.zip  | |
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 be2ab8c59e3..3416373a9c0 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -5,6 +5,7 @@   */  #include <linux/bitops.h>  #include <linux/etherdevice.h> +#include <linux/slab.h>  #include <net/cfg80211.h>  #include <net/ip.h>  #include "core.h" @@ -330,11 +331,18 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,  		if (iftype == NL80211_IFTYPE_MESH_POINT) {  			struct ieee80211s_hdr *meshdr =  				(struct ieee80211s_hdr *) (skb->data + hdrlen); -			hdrlen += ieee80211_get_mesh_hdrlen(meshdr); +			/* make sure meshdr->flags is on the linear part */ +			if (!pskb_may_pull(skb, hdrlen + 1)) +				return -1;  			if (meshdr->flags & MESH_FLAGS_AE_A5_A6) { -				memcpy(dst, meshdr->eaddr1, ETH_ALEN); -				memcpy(src, meshdr->eaddr2, ETH_ALEN); +				skb_copy_bits(skb, hdrlen + +					offsetof(struct ieee80211s_hdr, eaddr1), +				       	dst, ETH_ALEN); +				skb_copy_bits(skb, hdrlen + +					offsetof(struct ieee80211s_hdr, eaddr2), +				        src, ETH_ALEN);  			} +			hdrlen += ieee80211_get_mesh_hdrlen(meshdr);  		}  		break;  	case cpu_to_le16(IEEE80211_FCTL_FROMDS): @@ -346,9 +354,14 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,  		if (iftype == NL80211_IFTYPE_MESH_POINT) {  			struct ieee80211s_hdr *meshdr =  				(struct ieee80211s_hdr *) (skb->data + hdrlen); -			hdrlen += ieee80211_get_mesh_hdrlen(meshdr); +			/* make sure meshdr->flags is on the linear part */ +			if (!pskb_may_pull(skb, hdrlen + 1)) +				return -1;  			if (meshdr->flags & MESH_FLAGS_AE_A4) -				memcpy(src, meshdr->eaddr1, ETH_ALEN); +				skb_copy_bits(skb, hdrlen + +					offsetof(struct ieee80211s_hdr, eaddr1), +					src, ETH_ALEN); +			hdrlen += ieee80211_get_mesh_hdrlen(meshdr);  		}  		break;  	case cpu_to_le16(0): @@ -357,7 +370,7 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,  		break;  	} -	if (unlikely(skb->len - hdrlen < 8)) +	if (!pskb_may_pull(skb, hdrlen + 8))  		return -1;  	payload = skb->data + hdrlen;  |