Commit e76b2b2567b83448c2ee85a896433b96150c92e6

Authored by YOSHIFUJI Hideaki
Committed by David S. Miller
1 parent 5bb1ab09e4

[IPV6]: Do no rely on skb->dst before it is assigned.

Because skb->dst is assigned in ip6_route_input(), it is really
bad to use it in hop-by-hop option handler(s).

Closes: Bug #8450 (Eric Sesterhenn <snakebyte@gmx.de>)
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 1 changed file with 12 additions and 4 deletions Side-by-side Diff

... ... @@ -660,6 +660,14 @@
660 660 Hop-by-hop options.
661 661 **********************************/
662 662  
  663 +/*
  664 + * Note: we cannot rely on skb->dst before we assign it in ip6_route_input().
  665 + */
  666 +static inline struct inet6_dev *ipv6_skb_idev(struct sk_buff *skb)
  667 +{
  668 + return skb->dst ? ip6_dst_idev(skb->dst) : __in6_dev_get(skb->dev);
  669 +}
  670 +
663 671 /* Router Alert as of RFC 2711 */
664 672  
665 673 static int ipv6_hop_ra(struct sk_buff **skbp, int optoff)
666 674  
667 675  
668 676  
... ... @@ -688,25 +696,25 @@
688 696 if (nh[optoff + 1] != 4 || (optoff & 3) != 2) {
689 697 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n",
690 698 nh[optoff+1]);
691   - IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
  699 + IP6_INC_STATS_BH(ipv6_skb_idev(skb),
692 700 IPSTATS_MIB_INHDRERRORS);
693 701 goto drop;
694 702 }
695 703  
696 704 pkt_len = ntohl(*(__be32 *)(nh + optoff + 2));
697 705 if (pkt_len <= IPV6_MAXPLEN) {
698   - IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
  706 + IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INHDRERRORS);
699 707 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
700 708 return 0;
701 709 }
702 710 if (ipv6_hdr(skb)->payload_len) {
703   - IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
  711 + IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INHDRERRORS);
704 712 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff);
705 713 return 0;
706 714 }
707 715  
708 716 if (pkt_len > skb->len - sizeof(struct ipv6hdr)) {
709   - IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INTRUNCATEDPKTS);
  717 + IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INTRUNCATEDPKTS);
710 718 goto drop;
711 719 }
712 720