Source-Changes-HG archive

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

[src/trunk]: src/sys/net CID 1210544: Tainted scalar



details:   https://anonhg.NetBSD.org/src/rev/0b386581fd6e
branches:  trunk
changeset: 344856:0b386581fd6e
user:      christos <christos%NetBSD.org@localhost>
date:      Sun Apr 24 17:56:31 2016 +0000

description:
CID 1210544: Tainted scalar

diffstat:

 sys/net/if_spppsubr.c |  176 +++++++++++++++++++++++++++++--------------------
 1 files changed, 104 insertions(+), 72 deletions(-)

diffs (truncated from 529 to 300 lines):

diff -r 56342ecc1812 -r 0b386581fd6e sys/net/if_spppsubr.c
--- a/sys/net/if_spppsubr.c     Sun Apr 24 17:32:06 2016 +0000
+++ b/sys/net/if_spppsubr.c     Sun Apr 24 17:56:31 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_spppsubr.c,v 1.139 2016/04/24 17:32:06 christos Exp $        */
+/*     $NetBSD: if_spppsubr.c,v 1.140 2016/04/24 17:56:31 christos Exp $        */
 
 /*
  * Synchronous PPP/Cisco link level subroutines.
@@ -41,7 +41,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.139 2016/04/24 17:32:06 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.140 2016/04/24 17:56:31 christos Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_inet.h"
@@ -1259,7 +1259,7 @@
        lh->ident = ident;
        lh->len = htons(LCP_HEADER_LEN + len);
        if (len)
-               bcopy (data, lh + 1, len);
+               memcpy(lh + 1, data, len);
 
        if (debug) {
                log(LOG_DEBUG, "%s: %s output <%s id=0x%x len=%d",
@@ -2067,14 +2067,14 @@
 sppp_lcp_RCR(struct sppp *sp, struct lcp_header *h, int len)
 {
        STDDCL;
-       u_char *buf, *r, *p;
+       u_char *buf, *r, *p, l, blen;
        int origlen, rlen;
        uint32_t nmagic;
        u_short authproto;
 
        len -= 4;
        origlen = len;
-       buf = r = malloc (len, M_TEMP, M_NOWAIT);
+       buf = r = malloc (blen = len, M_TEMP, M_NOWAIT);
        if (! buf)
                return (0);
 
@@ -2084,16 +2084,16 @@
 
        /* 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]) {
+       for (rlen = 0; len > 1 && (l = p[1]) != 0; len -= l, p += l) {
                /* Sanity check option length */
-               if (p[1] > len) {
+               if (l > len) {
                        /*
                         * Malicious option - drop immediately.
                         * 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);
+                           p[0], l, len);
                        goto drop;
                }
                if (debug)
@@ -2104,14 +2104,14 @@
                        /* fall through, both are same length */
                case LCP_OPT_ASYNC_MAP:
                        /* Async control character map. */
-                       if (len >= 6 || p[1] == 6)
+                       if (len >= 6 || l == 6)
                                continue;
                        if (debug)
                                addlog(" [invalid]");
                        break;
                case LCP_OPT_MRU:
                        /* Maximum receive unit. */
-                       if (len >= 4 && p[1] == 4)
+                       if (len >= 4 && l == 4)
                                continue;
                        if (debug)
                                addlog(" [invalid]");
@@ -2123,7 +2123,7 @@
                                break;
                        }
                        authproto = (p[2] << 8) + p[3];
-                       if (authproto == PPP_CHAP && p[1] != 5) {
+                       if (authproto == PPP_CHAP && l != 5) {
                                if (debug)
                                        addlog(" [invalid chap len]");
                                break;
@@ -2147,10 +2147,15 @@
                                addlog(" [rej]");
                        break;
                }
+               if (rlen + l > blen) {
+                       if (debug)
+                               addlog(" [overflow]");
+                       continue;
+               }
                /* Add the option to rejected list. */
-               bcopy (p, r, p[1]);
-               r += p[1];
-               rlen += p[1];
+               memcpy(r, p, l);
+               r += l;
+               rlen += l;
        }
        if (rlen) {
                if (debug)
@@ -2170,7 +2175,7 @@
 
        p = (void *)(h + 1);
        len = origlen;
-       for (rlen=0; len>1 && p[1]; len-=p[1], p+=p[1]) {
+       for (rlen = 0; len > 1 && (l = p[1]) != 0; len -= l, p += l) {
                if (debug)
                        addlog(" %s", sppp_lcp_opt_name(*p));
                switch (*p) {
@@ -2260,10 +2265,15 @@
                        }
                        continue;
                }
+               if (rlen + l > blen) {
+                       if (debug)
+                               addlog(" [overflow]");
+                       continue;
+               }
                /* Add the option to nak'ed list. */
-               bcopy (p, r, p[1]);
-               r += p[1];
-               rlen += p[1];
+               memcpy(r, p, l);
+               r += l;
+               rlen += l;
        }
        if (rlen) {
                if (++sp->fail_counter[IDX_LCP] >= sp->lcp.max_failure) {
@@ -2303,7 +2313,7 @@
 sppp_lcp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len)
 {
        STDDCL;
-       u_char *buf, *p;
+       u_char *buf, *p, l;
 
        len -= 4;
        buf = malloc (len, M_TEMP, M_NOWAIT);
@@ -2315,9 +2325,9 @@
                    ifp->if_xname);
 
        p = (void *)(h + 1);
-       for (; len > 1 && p[1]; len -= p[1], p += p[1]) {
+       for (; len > 1 && (l = p[1]) != 0; len -= l, p += l) {
                /* Sanity check option length */
-               if (p[1] > len) {
+               if (l > len) {
                        /*
                         * Malicious option - drop immediately.
                         * XXX Maybe we should just RXJ it?
@@ -2384,11 +2394,11 @@
 sppp_lcp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len)
 {
        STDDCL;
-       u_char *buf, *p;
+       u_char *buf, *p, l, blen;
        uint32_t magic;
 
        len -= 4;
-       buf = malloc (len, M_TEMP, M_NOWAIT);
+       buf = malloc (blen = len, M_TEMP, M_NOWAIT);
        if (!buf)
                return;
 
@@ -2397,9 +2407,9 @@
                    ifp->if_xname);
 
        p = (void *)(h + 1);
-       for (; len > 1 && p[1]; len -= p[1], p += p[1]) {
+       for (; len > 1 && (l = p[1]) != 0; len -= l, p += l) {
                /* Sanity check option length */
-               if (p[1] > len) {
+               if (l > len) {
                        /*
                         * Malicious option - drop immediately.
                         * XXX Maybe we should just RXJ it?
@@ -2414,7 +2424,7 @@
                case LCP_OPT_MAGIC:
                        /* Magic number -- renegotiate */
                        if ((sp->lcp.opts & (1 << LCP_OPT_MAGIC)) &&
-                           len >= 6 && p[1] == 6) {
+                           len >= 6 && l == 6) {
                                magic = (uint32_t)p[2] << 24 |
                                        (uint32_t)p[3] << 16 | p[4] << 8 | p[5];
                                /*
@@ -2439,7 +2449,7 @@
                         * Agree on it if it's reasonable, or use
                         * default otherwise.
                         */
-                       if (len >= 4 && p[1] == 4) {
+                       if (len >= 4 && l == 4) {
                                u_int mru = p[2] * 256 + p[3];
                                if (debug)
                                        addlog(" %d", mru);
@@ -2791,7 +2801,7 @@
 static int
 sppp_ipcp_RCR(struct sppp *sp, struct lcp_header *h, int len)
 {
-       u_char *buf, *r, *p;
+       u_char *buf, *r, *p, l, blen;
        struct ifnet *ifp = &sp->pp_if;
        int rlen, origlen, debug = ifp->if_flags & IFF_DEBUG;
        uint32_t hisaddr, desiredaddr;
@@ -2802,7 +2812,8 @@
         * Make sure to allocate a buf that can at least hold a
         * conf-nak with an `address' option.  We might need it below.
         */
-       buf = r = malloc ((len < 6? 6: len), M_TEMP, M_NOWAIT);
+       blen = len < 6 ? 6 : len;
+       buf = r = malloc (blen, M_TEMP, M_NOWAIT);
        if (! buf)
                return (0);
 
@@ -2811,9 +2822,9 @@
                log(LOG_DEBUG, "%s: ipcp parse opts:",
                    ifp->if_xname);
        p = (void *)(h + 1);
-       for (rlen=0; len>1 && p[1]; len-=p[1], p+=p[1]) {
+       for (rlen = 0; len > 1 && (l = p[1]) != 0; len -= l, p += l) {
                /* Sanity check option length */
-               if (p[1] > len) {
+               if (l > len) {
                        /* XXX should we just RXJ? */
                        addlog("%s: malicious IPCP option received, dropping\n",
                            ifp->if_xname);
@@ -2824,7 +2835,7 @@
                switch (*p) {
 #ifdef notyet
                case IPCP_OPT_COMPRESSION:
-                       if (len >= 6 && p[1] >= 6) {
+                       if (len >= 6 && l >= 6) {
                                /* correctly formed compress option */
                                continue;
                        }
@@ -2833,7 +2844,7 @@
                        break;
 #endif
                case IPCP_OPT_ADDRESS:
-                       if (len >= 6 && p[1] == 6) {
+                       if (len >= 6 && l == 6) {
                                /* correctly formed address option */
                                continue;
                        }
@@ -2847,9 +2858,14 @@
                        break;
                }
                /* Add the option to rejected list. */
-               bcopy (p, r, p[1]);
-               r += p[1];
-               rlen += p[1];
+               if (rlen + l > blen) {
+                       if (debug)
+                               addlog(" [overflow]");
+                       continue;
+               }
+               memcpy(r, p, l);
+               r += l;
+               rlen += l;
        }
        if (rlen) {
                if (debug)
@@ -2873,7 +2889,7 @@
                       ifp->if_xname);
        p = (void *)(h + 1);
        len = origlen;
-       for (rlen=0; len>1 && p[1]; len-=p[1], p+=p[1]) {
+       for (rlen=0; len > 1 && (l = p[1]) != 0; len -= l, p += l) {
                if (debug)
                        addlog(" %s", sppp_ipcp_opt_name(*p));
                switch (*p) {
@@ -2921,10 +2937,15 @@
                        p[5] = hisaddr;
                        break;
                }
+               if (rlen + l > blen) {
+                       if (debug)
+                               addlog(" [overflow]");
+                       continue;
+               }
                /* Add the option to nak'ed list. */
-               bcopy (p, r, p[1]);
-               r += p[1];
-               rlen += p[1];
+               memcpy(r, p, l);
+               r += l;
+               rlen += l;
        }
 
        /*
@@ -2975,12 +2996,12 @@
 static void
 sppp_ipcp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len)



Home | Main Index | Thread Index | Old Index