netdev
[Top] [All Lists]

[PATCH] fragment, MLD6, and router-alert option

To: netdev@xxxxxxxxxxx
Subject: [PATCH] fragment, MLD6, and router-alert option
From: YOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@xxxxxxxxxxxxxxxxx>
Date: Thu, 11 Jan 2001 09:53:16 +0900
Cc: usagi-core@xxxxxxxxxxxxxx
Sender: owner-netdev@xxxxxxxxxxx
Hi, this is feed back from USAGI Project.

1. Ensure to send paramter problem for fragment.
2. Fix router-alert option format.
3. Do not overrun while parsing tlv options.

[MEMO] bFIX_2_4_0-20010111 -> tFIX_2_4_0-20010111_20010111

Index: net/ipv6/icmp.c
===================================================================
RCS file: /cvsroot/usagi/kernel/linux24/net/ipv6/icmp.c,v
retrieving revision 1.1.1.2
retrieving revision 1.1.1.2.2.2
diff -u -r1.1.1.2 -r1.1.1.2.2.2
--- net/ipv6/icmp.c     2001/01/05 05:39:31     1.1.1.2
+++ net/ipv6/icmp.c     2001/01/11 00:17:49     1.1.1.2.2.2
@@ -23,6 +23,8 @@
  *     Andi Kleen              :       exception handling
  *     Andi Kleen                      add rate limits. never reply to a icmp.
  *                                     add more length checks and other fixes.
+ *     yoshfuji                :       ensure to sent parameter problem for
+ *                                     fragments.
  */
 
 #define __NO_VERSION__
@@ -191,9 +193,14 @@
  *       for sender.
  *
  *     --ANK (980726)
+ *
+ * Note: We MUST send Parameter Problem even if it is not for the first
+ *       fragment.  See RFC2460.
+ *
+ *      --yoshfuji (2001/01/05)
  */
 
-static int is_ineligible(struct ipv6hdr *hdr, int len)
+static int is_ineligible(int type, struct ipv6hdr *hdr, int len)
 {
        u8 *ptr;
        __u8 nexthdr = hdr->nexthdr;
@@ -208,7 +215,7 @@
                struct icmp6hdr *ihdr = (struct icmp6hdr *)ptr;
                return (ptr - (u8*)hdr) > len || !(ihdr->icmp6_type & 0x80); 
        }
-       return nexthdr == NEXTHDR_FRAGMENT;
+       return nexthdr == NEXTHDR_FRAGMENT && type != ICMPV6_PARAMPROB;
 }
 
 int sysctl_icmpv6_time = 1*HZ; 
@@ -341,7 +348,7 @@
        /* 
         *      Never answer to a ICMP packet.
         */
-       if (is_ineligible(hdr, (u8*)skb->tail - (u8*)hdr)) {
+       if (is_ineligible(type, hdr, (u8*)skb->tail - (u8*)hdr)) {
                if (net_ratelimit())
                        printk(KERN_DEBUG "icmpv6_send: no reply to icmp 
error/fragment\n"); 
                return;
Index: net/ipv6/mcast.c
===================================================================
RCS file: /cvsroot/usagi/kernel/linux24/net/ipv6/mcast.c,v
retrieving revision 1.1.1.5
retrieving revision 1.1.1.5.2.2
diff -u -r1.1.1.5 -r1.1.1.5.2.2
--- net/ipv6/mcast.c    2000/10/05 13:40:35     1.1.1.5
+++ net/ipv6/mcast.c    2001/01/11 00:17:49     1.1.1.5.2.2
@@ -15,6 +15,11 @@
  *      2 of the License, or (at your option) any later version.
  */
 
+/* Changes:
+ *
+ *     yoshfuji        : fix format of router-alert option
+ */
+
 #define __NO_VERSION__
 #include <linux/config.h>
 #include <linux/module.h>
@@ -491,7 +496,7 @@
        struct in6_addr all_routers;
        int err, len, payload_len, full_len;
        u8 ra[8] = { IPPROTO_ICMPV6, 0,
-                    IPV6_TLV_ROUTERALERT, 0, 0, 0,
+                    IPV6_TLV_ROUTERALERT, 2, 0, 0,
                     IPV6_TLV_PADN, 0 };
 
        snd_addr = addr;
Index: net/ipv6/exthdrs.c
===================================================================
RCS file: /cvsroot/usagi/kernel/linux24/net/ipv6/exthdrs.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.10.1
diff -u -r1.1.1.1 -r1.1.1.1.10.1
--- net/ipv6/exthdrs.c  2000/08/25 02:29:26     1.1.1.1
+++ net/ipv6/exthdrs.c  2001/01/11 00:33:05     1.1.1.1.10.1
@@ -15,6 +15,11 @@
  *      2 of the License, or (at your option) any later version.
  */
 
+/* Changes:
+ *     yoshfuji                : ensure not to overrun while parsing 
+ *                               tlv options.
+ */
+
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/socket.h>
@@ -104,6 +109,7 @@
        struct tlvtype_proc *curr;
        u8 *ptr = skb->h.raw;
        int len = ((ptr[1]+1)<<3) - 2;
+       int optlen;
 
        ptr += 2;
 
@@ -113,19 +119,31 @@
        }
 
        while (len > 0) {
-               int optlen = ptr[1]+2;
-
                switch (ptr[0]) {
                case IPV6_TLV_PAD0:
                        optlen = 1;
                        break;
 
                case IPV6_TLV_PADN:
+                       if (len < 2)
+                               goto bad;
+                       optlen = ptr[1]+2;
+                       if (len < optlen)
+                               goto bad;
                        break;
 
-               default: /* Other TLV code so scan list */
+               default:
+                       /* Other TLV code so scan list */
+                       if (len < 2)
+                               goto bad;
+                       optlen = ptr[1]+2;
+                       if (len < optlen)
+                               goto bad;
                        for (curr=procs; curr->type >= 0; curr++) {
                                if (curr->type == ptr[0]) {
+                                       /* type specific length/alignment 
+                                          checks will be perfomed in the 
+                                          func(). */
                                        if (curr->func(skb, ptr) == 0)
                                                return 0;
                                        break;
@@ -142,6 +160,7 @@
        }
        if (len == 0)
                return 1;
+bad:
        kfree_skb(skb);
        return 0;
 }

-- 
Hideaki YOSHIFUJI @ USAGI Project  <yoshfuji@xxxxxxxxxxxxxx>
PGP5i FP: F731 6599 5EB2 BBA7 1515  1323 1806 A96F 5700 6B25 

<Prev in Thread] Current Thread [Next in Thread>