On 11/04/16 at 11:29am, David Lebrun wrote: > +/* insert an SRH within an IPv6 packet, just after the IPv6 header */ > +static int seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh) > +{ > + struct ipv6hdr *hdr, *oldhdr; > + struct ipv6_sr_hdr *isrh; > + int hdrlen, err; > + > + hdrlen = (osrh->hdrlen + 1) << 3; > + > + err = pskb_expand_head(skb, hdrlen, 0, GFP_ATOMIC); > + if (unlikely(err)) > + return err; > + > + oldhdr = ipv6_hdr(skb); > + > + skb_pull(skb, sizeof(struct ipv6hdr)); > + skb_postpull_rcsum(skb, skb_network_header(skb), > + sizeof(struct ipv6hdr)); > + > + skb_push(skb, sizeof(struct ipv6hdr) + hdrlen); > + skb_reset_network_header(skb); > + skb_mac_header_rebuild(skb); > + > + hdr = ipv6_hdr(skb); > + > + memmove(hdr, oldhdr, sizeof(*hdr)); > + > + isrh = (void *)hdr + sizeof(*hdr); > + memcpy(isrh, osrh, hdrlen); > + > + isrh->nexthdr = hdr->nexthdr; > + hdr->nexthdr = NEXTHDR_ROUTING; > + > + isrh->segments[0] = hdr->daddr; > + hdr->daddr = isrh->segments[isrh->first_segment];
Where do you verify that isrh->first_segment is not out of bounds? > + skb_postpush_rcsum(skb, hdr, sizeof(struct ipv6hdr) + hdrlen); > + > + return 0; > +} > + > + > +static int seg6_build_state(struct net_device *dev, struct nlattr *nla, > + unsigned int family, const void *cfg, > + struct lwtunnel_state **ts) > +{ > + struct nlattr *tb[SEG6_IPTUNNEL_MAX + 1]; > + struct seg6_iptunnel_encap *tuninfo; > + struct lwtunnel_state *newts; > + struct seg6_lwt *slwt; > + int tuninfo_len; > + int err; > + > + err = nla_parse_nested(tb, SEG6_IPTUNNEL_MAX, nla, > + seg6_iptunnel_policy); > + > + if (err < 0) > + return err; > + > + if (!tb[SEG6_IPTUNNEL_SRH]) > + return -EINVAL; > + > + tuninfo = nla_data(tb[SEG6_IPTUNNEL_SRH]); > + tuninfo_len = SEG6_IPTUN_ENCAP_SIZE(tuninfo); Nothing guarantees the size of the Netlink attribute right now. You need to add a minimal size requirement to seg6_iptunnel_policy and then check that the additional len provided in the struct itself does not exceed the Netlink attribute length.