Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-2-0]: src/sys/net Pull up following revision(s) (requested by adr...



details:   https://anonhg.NetBSD.org/src/rev/93e0fad1c242
branches:  netbsd-2-0
changeset: 564987:93e0fad1c242
user:      tron <tron%NetBSD.org@localhost>
date:      Wed Aug 23 20:19:56 2006 +0000

description:
Pull up following revision(s) (requested by adrianp in ticket #10677):
        sys/net/if_spppsubr.c: revision 1.96
A problem has been identified in the in-kernel PPP code shared by ISDN PPP
interfaces ippp(4) and pppoe(4). Insufficient checking of options presented
by the peer may cause writing of copies of the malicious input beyond the
end of a buffer allocated for that purpose.
Issue found by pavel@
Fix from martin@
This is SA2006-019 (CVE-2006-4304)

diffstat:

 sys/net/if_spppsubr.c |  130 +++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 117 insertions(+), 13 deletions(-)

diffs (truncated from 318 to 300 lines):

diff -r 0d0eadd282d6 -r 93e0fad1c242 sys/net/if_spppsubr.c
--- a/sys/net/if_spppsubr.c     Fri Aug 11 04:54:19 2006 +0000
+++ b/sys/net/if_spppsubr.c     Wed Aug 23 20:19:56 2006 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_spppsubr.c,v 1.75.2.1 2004/04/08 21:16:03 jdc Exp $  */
+/*     $NetBSD: if_spppsubr.c,v 1.75.2.2 2006/08/23 20:19:56 tron Exp $         */
 
 /*
  * Synchronous PPP/Cisco link level subroutines.
@@ -41,7 +41,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.75.2.1 2004/04/08 21:16:03 jdc Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.75.2.2 2006/08/23 20:19:56 tron Exp $");
 
 #include "opt_inet.h"
 #include "opt_ipx.h"
@@ -1374,7 +1374,7 @@
 {
        STDDCL;
        struct lcp_header *h;
-       int len = m->m_pkthdr.len;
+       int printlen, len = m->m_pkthdr.len;
        int rv;
        u_char *p;
        u_int32_t u32;
@@ -1388,13 +1388,16 @@
        }
        h = mtod(m, struct lcp_header *);
        if (debug) {
+               printlen = ntohs(h->len);
                log(LOG_DEBUG,
                    "%s: %s input(%s): <%s id=0x%x len=%d",
                    ifp->if_xname, cp->name,
                    sppp_state_name(sp->state[cp->protoidx]),
-                   sppp_cp_type_name(h->type), h->ident, ntohs(h->len));
-               if (len > 4)
-                       sppp_print_bytes((u_char *)(h + 1), len - 4);
+                   sppp_cp_type_name(h->type), h->ident, printlen);
+               if (len < printlen)
+                       printlen = len;
+               if (printlen > 4)
+                       sppp_print_bytes((u_char *)(h + 1), printlen - 4);
                addlog(">\n");
        }
        if (len > ntohs(h->len))
@@ -1421,6 +1424,12 @@
                        return;
                }
                rv = (cp->RCR)(sp, h, len);
+               if (rv < 0) {
+                       /* fatal error, shut down */
+                       (cp->tld)(sp);
+                       sppp_lcp_tlf(sp);
+                       return;
+               }
                switch (sp->state[cp->protoidx]) {
                case STATE_OPENED:
                        (cp->tld)(sp);
@@ -2153,6 +2162,17 @@
        /* pass 1: check for things that need to be rejected */
        p = (void *)(h + 1);
        for (rlen=0; len>1 && p[1]; len-=p[1], p+=p[1]) {
+               /* Sanity check option length */
+               if (p[1] > len) {
+                       /*
+                        * Malicious option - drop imediately.
+                        * XXX Maybe we should just RXJ it?
+                        */
+                       addlog("%s: received malicious LCP option 0x%02x, "
+                           "length 0x%02x, (len: 0x%02x) dropping.\n", ifp->if_xname,
+                           p[0], p[1], len);
+                       goto drop;
+               }
                if (debug)
                        addlog(" %s", sppp_lcp_opt_name(*p));
                switch (*p) {
@@ -2346,6 +2366,10 @@
  end:
        free(buf, M_TEMP);
        return (rlen == 0);
+
+ drop:
+       free(buf, M_TEMP);
+       return -1;
 }
 
 /*
@@ -2369,6 +2393,16 @@
 
        p = (void *)(h + 1);
        for (; len > 1 && p[1]; len -= p[1], p += p[1]) {
+               /* Sanity check option length */
+               if (p[1] > len) {
+                       /*
+                        * Malicious option - drop imediately.
+                        * XXX Maybe we should just RXJ it?
+                        */
+                       addlog("%s: received malicious LCP option, "
+                           "dropping.\n", ifp->if_xname);
+                       goto drop;
+               }
                if (debug)
                        addlog(" %s", sppp_lcp_opt_name(*p));
                switch (*p) {
@@ -2407,6 +2441,7 @@
        }
        if (debug)
                addlog("\n");
+drop:
        free(buf, M_TEMP);
        return;
 }
@@ -2433,6 +2468,16 @@
 
        p = (void *)(h + 1);
        for (; len > 1 && p[1]; len -= p[1], p += p[1]) {
+               /* Sanity check option length */
+               if (p[1] > len) {
+                       /*
+                        * Malicious option - drop imediately.
+                        * XXX Maybe we should just RXJ it?
+                        */
+                       addlog("%s: received malicious LCP option, "
+                           "dropping.\n", ifp->if_xname);
+                       goto drop;
+               }
                if (debug)
                        addlog(" %s", sppp_lcp_opt_name(*p));
                switch (*p) {
@@ -2487,6 +2532,7 @@
        }
        if (debug)
                addlog("\n");
+drop:
        free(buf, M_TEMP);
        return;
 }
@@ -2830,6 +2876,13 @@
                    ifp->if_xname);
        p = (void *)(h + 1);
        for (rlen=0; len>1 && p[1]; len-=p[1], p+=p[1]) {
+               /* Sanity check option length */
+               if (p[1] > len) {
+                       /* XXX should we just RXJ? */
+                       addlog("%s: malicious IPCP option received, dropping\n",
+                           ifp->if_xname);
+                       goto drop;
+               }
                if (debug)
                        addlog(" %s", sppp_ipcp_opt_name(*p));
                switch (*p) {
@@ -2969,6 +3022,10 @@
  end:
        free(buf, M_TEMP);
        return (rlen == 0);
+
+ drop:
+       free(buf, M_TEMP);
+       return -1;
 }
 
 /*
@@ -2993,6 +3050,13 @@
 
        p = (void *)(h + 1);
        for (; len > 1 && p[1]; len -= p[1], p += p[1]) {
+               /* Sanity check option length */
+               if (p[1] > len) {
+                       /* XXX should we just RXJ? */
+                       addlog("%s: malicious IPCP option received, dropping\n",
+                           ifp->if_xname);
+                       goto drop;
+               }
                if (debug)
                        addlog(" %s", sppp_ipcp_opt_name(*p));
                switch (*p) {
@@ -3012,6 +3076,7 @@
        }
        if (debug)
                addlog("\n");
+drop:
        free(buf, M_TEMP);
        return;
 }
@@ -3036,6 +3101,13 @@
 
        p = (void *)(h + 1);
        for (; len > 1 && p[1]; len -= p[1], p += p[1]) {
+               /* Sanity check option length */
+               if (p[1] > len) {
+                       /* XXX should we just RXJ? */
+                       addlog("%s: malicious IPCP option received, dropping\n",
+                           ifp->if_xname);
+                       return;
+               }
                if (debug)
                        addlog(" %s", sppp_ipcp_opt_name(*p));
                switch (*p) {
@@ -3091,7 +3163,6 @@
        }
        if (debug)
                addlog("\n");
-       return;
 }
 
 static void
@@ -3304,6 +3375,13 @@
        p = (void *)(h + 1);
        ifidcount = 0;
        for (rlen=0; len>1 && p[1]; len-=p[1], p+=p[1]) {
+               /* Sanity check option length */
+               if (p[1] > len) {
+                       /* XXX just RXJ? */
+                       addlog("%s: received malicious IPCPv6 option, "
+                           "dropping\n", ifp->if_xname);
+                       goto drop;
+               }
                if (debug)
                        addlog(" %s", sppp_ipv6cp_opt_name(*p));
                switch (*p) {
@@ -3429,6 +3507,10 @@
  end:
        free(buf, M_TEMP);
        return (rlen == 0);
+
+ drop:
+       free(buf, M_TEMP);
+       return -1;
 }
 
 /*
@@ -3453,6 +3535,12 @@
 
        p = (void *)(h + 1);
        for (; len > 1 && p[1]; len -= p[1], p += p[1]) {
+               if (p[1] > len) {
+                       /* XXX just RXJ? */
+                       addlog("%s: received malicious IPCPv6 option, "
+                           "dropping\n", ifp->if_xname);
+                       goto drop;
+               }
                if (debug)
                        addlog(" %s", sppp_ipv6cp_opt_name(*p));
                switch (*p) {
@@ -3472,6 +3560,7 @@
        }
        if (debug)
                addlog("\n");
+drop:
        free(buf, M_TEMP);
        return;
 }
@@ -3499,6 +3588,12 @@
 
        p = (void *)(h + 1);
        for (; len > 1 && p[1]; len -= p[1], p += p[1]) {
+               if (p[1] > len) {
+                       /* XXX just RXJ? */
+                       addlog("%s: received malicious IPCPv6 option, "
+                           "dropping\n", ifp->if_xname);
+                       goto drop;
+               }
                if (debug)
                        addlog(" %s", sppp_ipv6cp_opt_name(*p));
                switch (*p) {
@@ -3569,6 +3664,7 @@
        }
        if (debug)
                addlog("\n");
+drop:
        free(buf, M_TEMP);
        return;
 }
@@ -4225,6 +4321,12 @@
        char *name, *secret;
        int name_len, secret_len;
 
+       /*
+        * Malicious input might leave this uninitialized, so
+        * init to an impossible value.
+        */
+       secret_len = -1;
+
        len = m->m_pkthdr.len;
        if (len < 5) {
                if (debug)
@@ -4310,10 +4412,11 @@
                if (debug) {
                        log(LOG_DEBUG, "%s: pap success",
                            ifp->if_xname);
-                       name_len = *(char *)h;
-                       if (len > 5 && name_len) {
+                       name = 1 + (u_char *)(h + 1);
+                       name_len = name[-1];
+                       if (len > 5 && name_len < len+4) {
                                addlog(": ");
-                               sppp_print_string((char *)(h + 1), name_len);
+                               sppp_print_string(name, name_len);



Home | Main Index | Thread Index | Old Index