diff options
-rw-r--r-- | net/ipv6/exthdrs.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 2a1e7e45b890..d88cab7b973f 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c | |||
@@ -489,6 +489,18 @@ int ipv6_parse_hopopts(struct sk_buff *skb, int nhoff) | |||
489 | { | 489 | { |
490 | struct inet6_skb_parm *opt = IP6CB(skb); | 490 | struct inet6_skb_parm *opt = IP6CB(skb); |
491 | 491 | ||
492 | /* | ||
493 | * skb->nh.raw is equal to skb->data, and | ||
494 | * skb->h.raw - skb->nh.raw is always equal to | ||
495 | * sizeof(struct ipv6hdr) by definition of | ||
496 | * hop-by-hop options. | ||
497 | */ | ||
498 | if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + 8) || | ||
499 | !pskb_may_pull(skb, sizeof(struct ipv6hdr) + ((skb->h.raw[1] + 1) << 3))) { | ||
500 | kfree_skb(skb); | ||
501 | return -1; | ||
502 | } | ||
503 | |||
492 | opt->hop = sizeof(struct ipv6hdr); | 504 | opt->hop = sizeof(struct ipv6hdr); |
493 | if (ip6_parse_tlv(tlvprochopopt_lst, skb)) { | 505 | if (ip6_parse_tlv(tlvprochopopt_lst, skb)) { |
494 | skb->h.raw += (skb->h.raw[1]+1)<<3; | 506 | skb->h.raw += (skb->h.raw[1]+1)<<3; |