diff options
author | Stephen Hemminger <shemminger@vyatta.com> | 2009-06-17 12:17:34 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-06-17 18:46:41 -0700 |
commit | 603a8bbe62e54108055fca46ecdd611c10c6cd0a (patch) | |
tree | 5d6c6f449cadf7c956f02c399b26460c7c8a20a0 /net/core | |
parent | 19633e129c65e5bb62b1af545c5479afcdb01fc4 (diff) | |
download | linux-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.c | 9 |
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; |