summaryrefslogtreecommitdiff
path: root/net/core
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@vyatta.com>2009-06-17 12:17:34 +0000
committerDavid S. Miller <davem@davemloft.net>2009-06-17 18:46:41 -0700
commit603a8bbe62e54108055fca46ecdd611c10c6cd0a (patch)
tree5d6c6f449cadf7c956f02c399b26460c7c8a20a0 /net/core
parent19633e129c65e5bb62b1af545c5479afcdb01fc4 (diff)
downloadlinux-3.10-603a8bbe62e54108055fca46ecdd611c10c6cd0a.tar.gz
linux-3.10-603a8bbe62e54108055fca46ecdd611c10c6cd0a.tar.bz2
linux-3.10-603a8bbe62e54108055fca46ecdd611c10c6cd0a.zip
skbuff: don't corrupt mac_header on skb expansion
The skb mac_header field is sometimes NULL (or ~0u) as a sentinel value. The places where skb is expanded add an offset which would change this flag into an invalid pointer (or offset). Signed-off-by: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/skbuff.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 436695d8deb..a4c01f5c658 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -661,7 +661,8 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
/* {transport,network,mac}_header are relative to skb->head */
new->transport_header += offset;
new->network_header += offset;
- new->mac_header += offset;
+ if (skb_mac_header_was_set(new))
+ new->mac_header += offset;
#endif
skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size;
skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs;
@@ -843,7 +844,8 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
skb->tail += off;
skb->transport_header += off;
skb->network_header += off;
- skb->mac_header += off;
+ if (skb_mac_header_was_set(skb))
+ skb->mac_header += off;
skb->csum_start += nhead;
skb->cloned = 0;
skb->hdr_len = 0;
@@ -935,7 +937,8 @@ struct sk_buff *skb_copy_expand(const struct sk_buff *skb,
#ifdef NET_SKBUFF_DATA_USES_OFFSET
n->transport_header += off;
n->network_header += off;
- n->mac_header += off;
+ if (skb_mac_header_was_set(skb))
+ n->mac_header += off;
#endif
return n;