diff options
author | Stephen Hemminger <shemminger@vyatta.com> | 2009-06-17 08:17:34 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-06-17 21:46:41 -0400 |
commit | 603a8bbe62e54108055fca46ecdd611c10c6cd0a (patch) | |
tree | 5d6c6f449cadf7c956f02c399b26460c7c8a20a0 /net | |
parent | 19633e129c65e5bb62b1af545c5479afcdb01fc4 (diff) |
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')
-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 436695d8deb8..a4c01f5c6585 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) | |||
661 | /* {transport,network,mac}_header are relative to skb->head */ | 661 | /* {transport,network,mac}_header are relative to skb->head */ |
662 | new->transport_header += offset; | 662 | new->transport_header += offset; |
663 | new->network_header += offset; | 663 | new->network_header += offset; |
664 | new->mac_header += offset; | 664 | if (skb_mac_header_was_set(new)) |
665 | new->mac_header += offset; | ||
665 | #endif | 666 | #endif |
666 | skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size; | 667 | skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size; |
667 | skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs; | 668 | 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, | |||
843 | skb->tail += off; | 844 | skb->tail += off; |
844 | skb->transport_header += off; | 845 | skb->transport_header += off; |
845 | skb->network_header += off; | 846 | skb->network_header += off; |
846 | skb->mac_header += off; | 847 | if (skb_mac_header_was_set(skb)) |
848 | skb->mac_header += off; | ||
847 | skb->csum_start += nhead; | 849 | skb->csum_start += nhead; |
848 | skb->cloned = 0; | 850 | skb->cloned = 0; |
849 | skb->hdr_len = 0; | 851 | skb->hdr_len = 0; |
@@ -935,7 +937,8 @@ struct sk_buff *skb_copy_expand(const struct sk_buff *skb, | |||
935 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | 937 | #ifdef NET_SKBUFF_DATA_USES_OFFSET |
936 | n->transport_header += off; | 938 | n->transport_header += off; |
937 | n->network_header += off; | 939 | n->network_header += off; |
938 | n->mac_header += off; | 940 | if (skb_mac_header_was_set(skb)) |
941 | n->mac_header += off; | ||
939 | #endif | 942 | #endif |
940 | 943 | ||
941 | return n; | 944 | return n; |