Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=c382bb9d32a55029fb13b118858e25908fab4617
Commit:     c382bb9d32a55029fb13b118858e25908fab4617
Parent:     c9726d6890f7f3a892c879e067c3ed839f61e745
Author:     YOSHIFUJI Hideaki <[EMAIL PROTECTED]>
AuthorDate: Tue Jul 10 22:47:58 2007 -0700
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Tue Jul 10 22:47:58 2007 -0700

    [IPV6]: Restore semantics of Routing Header processing.
    
    The "fix" for emerging security threat was overkill and it broke
    basic semantic of IPv6 routing header processing.  We should assume
    RT0 (or even RT2, depends on configuration) as "unknown" RH type so
    that we
    - silently ignore the routing header if segleft == 0
    - send ICMPv6 Parameter Problem message back to the sender,
      otherwise.
    
    Signed-off-by: YOSHIFUJI Hideaki <[EMAIL PROTECTED]>
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
---
 net/ipv6/exthdrs.c |   47 ++++++++++++++++-------------------------------
 1 files changed, 16 insertions(+), 31 deletions(-)

diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 173a4bb..fc3a961 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -372,22 +372,13 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp)
        struct rt0_hdr *rthdr;
        int accept_source_route = ipv6_devconf.accept_source_route;
 
-       if (accept_source_route < 0 ||
-           ((idev = in6_dev_get(skb->dev)) == NULL)) {
-               kfree_skb(skb);
-               return -1;
-       }
-       if (idev->cnf.accept_source_route < 0) {
+       idev = in6_dev_get(skb->dev);
+       if (idev) {
+               if (accept_source_route > idev->cnf.accept_source_route)
+                       accept_source_route = idev->cnf.accept_source_route;
                in6_dev_put(idev);
-               kfree_skb(skb);
-               return -1;
        }
 
-       if (accept_source_route > idev->cnf.accept_source_route)
-               accept_source_route = idev->cnf.accept_source_route;
-
-       in6_dev_put(idev);
-
        if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) ||
            !pskb_may_pull(skb, (skb_transport_offset(skb) +
                                 ((skb_transport_header(skb)[1] + 1) << 3)))) {
@@ -399,24 +390,6 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp)
 
        hdr = (struct ipv6_rt_hdr *)skb_transport_header(skb);
 
-       switch (hdr->type) {
-#ifdef CONFIG_IPV6_MIP6
-       case IPV6_SRCRT_TYPE_2:
-               break;
-#endif
-       case IPV6_SRCRT_TYPE_0:
-               if (accept_source_route > 0)
-                       break;
-               kfree_skb(skb);
-               return -1;
-       default:
-               IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
-                                IPSTATS_MIB_INHDRERRORS);
-               icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
-                                 (&hdr->type) - skb_network_header(skb));
-               return -1;
-       }
-
        if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) ||
            skb->pkt_type != PACKET_HOST) {
                IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
@@ -455,6 +428,8 @@ looped_back:
 
        switch (hdr->type) {
        case IPV6_SRCRT_TYPE_0:
+               if (accept_source_route <= 0)
+                       goto unknown_rh;
                if (hdr->hdrlen & 0x01) {
                        IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
                                         IPSTATS_MIB_INHDRERRORS);
@@ -466,6 +441,8 @@ looped_back:
                break;
 #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
        case IPV6_SRCRT_TYPE_2:
+               if (accept_source_route < 0)
+                       goto unknown_rh;
                /* Silently discard invalid RTH type 2 */
                if (hdr->hdrlen != 2 || hdr->segments_left != 1) {
                        IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
@@ -475,6 +452,8 @@ looped_back:
                }
                break;
 #endif
+       default:
+               goto unknown_rh;
        }
 
        /*
@@ -578,6 +557,12 @@ looped_back:
        skb_push(skb, skb->data - skb_network_header(skb));
        dst_input(skb);
        return -1;
+
+unknown_rh:
+       IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
+       icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
+                         (&hdr->type) - skb_network_header(skb));
+       return -1;
 }
 
 static struct inet6_protocol rthdr_protocol = {
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to