netdev
[Top] [All Lists]

[SECURITY] Overrun in net/ipv6/exthdrs.c

To: netdev@xxxxxxxxxxx
Subject: [SECURITY] Overrun in net/ipv6/exthdrs.c
From: YOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@xxxxxxxxxxxxxxxxx>
Date: Fri, 23 Feb 2001 01:29:55 +0900
Sender: owner-netdev@xxxxxxxxxxx
Hi,

We've found buffer overrun bug while parsing ipv6 extension headers
in linux2{2,4}/net/ipv6/exthdrs.c.

Here's the patch we've applied against our tree.

Index: net/ipv6/exthdrs.c
===================================================================
RCS file: /cvsroot/usagi/usagi/kernel/linux24/net/ipv6/exthdrs.c,v
retrieving revision 1.6
retrieving revision 1.8
diff -u -r1.6 -r1.8
--- net/ipv6/exthdrs.c  2001/01/08 14:42:41     1.6
+++ net/ipv6/exthdrs.c  2001/01/10 23:45:34     1.8
@@ -1,4 +1,4 @@
-/* $USAGI: exthdrs.c,v 1.6 2001/01/08 14:42:41 yoshfuji Exp $ */
+/* $USAGI: exthdrs.c,v 1.8 2001/01/10 23:45:34 yoshfuji Exp $ */
 
 /*
  *     Extension Header handling for IPv6
@@ -106,6 +106,7 @@
        struct tlvtype_proc *curr;
        u8 *ptr = skb->h.raw;
        int len = ((ptr[1]+1)<<3) - 2;
+       int optlen;
 
        ptr += 2;
 
@@ -115,19 +116,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;
@@ -144,6 +157,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>