|
@@ -489,6 +489,18 @@ int ipv6_parse_hopopts(struct sk_buff *skb, int nhoff)
|
|
{
|
|
{
|
|
struct inet6_skb_parm *opt = IP6CB(skb);
|
|
struct inet6_skb_parm *opt = IP6CB(skb);
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * skb->nh.raw is equal to skb->data, and
|
|
|
|
+ * skb->h.raw - skb->nh.raw is always equal to
|
|
|
|
+ * sizeof(struct ipv6hdr) by definition of
|
|
|
|
+ * hop-by-hop options.
|
|
|
|
+ */
|
|
|
|
+ if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + 8) ||
|
|
|
|
+ !pskb_may_pull(skb, sizeof(struct ipv6hdr) + ((skb->h.raw[1] + 1) << 3))) {
|
|
|
|
+ kfree_skb(skb);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
opt->hop = sizeof(struct ipv6hdr);
|
|
opt->hop = sizeof(struct ipv6hdr);
|
|
if (ip6_parse_tlv(tlvprochopopt_lst, skb)) {
|
|
if (ip6_parse_tlv(tlvprochopopt_lst, skb)) {
|
|
skb->h.raw += (skb->h.raw[1]+1)<<3;
|
|
skb->h.raw += (skb->h.raw[1]+1)<<3;
|