Source-Changes-HG archive

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

[src/trunk]: src/sys/netinet6 add more sanity check against mbuf length.



details:   https://anonhg.NetBSD.org/src/rev/ac2d771332ed
branches:  trunk
changeset: 481819:ac2d771332ed
user:      itojun <itojun%NetBSD.org@localhost>
date:      Mon Feb 07 05:42:28 2000 +0000

description:
add more sanity check against mbuf length.
use log() for DAD related kernel message.

diffstat:

 sys/netinet6/nd6_nbr.c |  83 +++++++++++++++++++++++++++++++++++++------------
 1 files changed, 62 insertions(+), 21 deletions(-)

diffs (197 lines):

diff -r 2c41d10c2221 -r ac2d771332ed sys/netinet6/nd6_nbr.c
--- a/sys/netinet6/nd6_nbr.c    Mon Feb 07 03:51:59 2000 +0000
+++ b/sys/netinet6/nd6_nbr.c    Mon Feb 07 05:42:28 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nd6_nbr.c,v 1.14 2000/02/06 12:49:48 itojun Exp $      */
+/*     $NetBSD: nd6_nbr.c,v 1.15 2000/02/07 05:42:28 itojun Exp $      */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -310,13 +310,33 @@
        struct in6_ifaddr *ia = NULL;
        struct ip6_moptions im6o;
        int icmp6len;
+       int maxlen;
        caddr_t mac;
        struct ifnet *outif = NULL;
        
        if (IN6_IS_ADDR_MULTICAST(taddr6))
                return;
 
-       if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
+       /* estimate the size of message */
+       maxlen = sizeof(*ip6) + sizeof(*nd_ns);
+       maxlen += (sizeof(struct nd_opt_hdr) + ifp->if_addrlen + 7) & ~7;
+       if (max_linkhdr + maxlen >= MCLBYTES) {
+#ifdef DIAGNOSTIC
+               printf("nd6_ns_output: max_linkhdr + maxlen >= MCLBYTES "
+                   "(%d + %d > %d)\n", max_linkhdr, maxlen, MCLBYTES);
+#endif
+               return;
+       }
+
+       MGETHDR(m, M_DONTWAIT, MT_DATA);
+       if (m && max_linkhdr + maxlen >= MHLEN) {
+               MCLGET(m, M_DONTWAIT);
+               if ((m->m_flags & M_EXT) == 0) {
+                       m_free(m);
+                       m = NULL;
+               }
+       }
+       if (m == NULL)
                return;
 
        if (daddr6 == NULL || IN6_IS_ADDR_MULTICAST(daddr6)) {
@@ -328,7 +348,7 @@
 
        icmp6len = sizeof(*nd_ns);
        m->m_pkthdr.len = m->m_len = sizeof(*ip6) + icmp6len;
-       MH_ALIGN(m, m->m_len + 16); /* 1+1+6 is enought. but just in case */
+       m->m_data += max_linkhdr;       /*or MH_ALIGN() equivalent?*/
 
        /* fill neighbor solicitation packet */
        ip6 = mtod(m, struct ip6_hdr *);
@@ -725,10 +745,30 @@
        struct in6_ifaddr *ia = NULL;
        struct ip6_moptions im6o;
        int icmp6len;
+       int maxlen;
        caddr_t mac;
        struct ifnet *outif = NULL;
-       
-       if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
+
+       /* estimate the size of message */
+       maxlen = sizeof(*ip6) + sizeof(*nd_na);
+       maxlen += (sizeof(struct nd_opt_hdr) + ifp->if_addrlen + 7) & ~7;
+       if (max_linkhdr + maxlen >= MCLBYTES) {
+#ifdef DIAGNOSTIC
+               printf("nd6_na_output: max_linkhdr + maxlen >= MCLBYTES "
+                   "(%d + %d > %d)\n", max_linkhdr, maxlen, MCLBYTES);
+#endif
+               return;
+       }
+
+       MGETHDR(m, M_DONTWAIT, MT_DATA);
+       if (m && max_linkhdr + maxlen >= MHLEN) {
+               MCLGET(m, M_DONTWAIT);
+               if ((m->m_flags & M_EXT) == 0) {
+                       m_free(m);
+                       m = NULL;
+               }
+       }
+       if (m == NULL)
                return;
 
        if (IN6_IS_ADDR_MULTICAST(daddr6)) {
@@ -740,7 +780,7 @@
 
        icmp6len = sizeof(*nd_na);
        m->m_pkthdr.len = m->m_len = sizeof(struct ip6_hdr) + icmp6len;
-       MH_ALIGN(m, m->m_len + 16); /* 1+1+6 is enough. but just in case */
+       m->m_data += max_linkhdr;       /*or MH_ALIGN() equivalent?*/
 
        /* fill neighbor advertisement packet */
        ip6 = mtod(m, struct ip6_hdr *);
@@ -881,7 +921,8 @@
         * - the interface address is anycast
         */
        if (!(ia->ia6_flags & IN6_IFF_TENTATIVE)) {
-               printf("nd6_dad_start: called with non-tentative address "
+               log(LOG_DEBUG,
+                       "nd6_dad_start: called with non-tentative address "
                        "%s(%s)\n",
                        ip6_sprintf(&ia->ia_addr.sin6_addr),
                        ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
@@ -906,7 +947,7 @@
 
        dp = malloc(sizeof(*dp), M_IP6NDP, M_NOWAIT);
        if (dp == NULL) {
-               printf("nd6_dad_start: memory allocation failed for "
+               log(LOG_ERR, "nd6_dad_start: memory allocation failed for "
                        "%s(%s)\n",
                        ip6_sprintf(&ia->ia_addr.sin6_addr),
                        ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
@@ -915,10 +956,8 @@
        bzero(dp, sizeof(*dp));
        TAILQ_INSERT_TAIL(&dadq, (struct dadq *)dp, dad_list);
 
-#ifdef DIAGNOSTIC
-       printf("%s: starting DAD for %s\n", if_name(ifa->ifa_ifp),
+       log(LOG_DEBUG, "%s: starting DAD for %s\n", if_name(ifa->ifa_ifp),
            ip6_sprintf(&ia->ia_addr.sin6_addr));
-#endif
 
        /*
         * Send NS packet for DAD, ip6_dad_count times.
@@ -960,23 +999,23 @@
 
        /* Sanity check */
        if (ia == NULL) {
-               printf("nd6_dad_timer: called with null parameter\n");
+               log(LOG_ERR, "nd6_dad_timer: called with null parameter\n");
                goto done;
        }
        dp = nd6_dad_find(ifa);
        if (dp == NULL) {
-               printf("nd6_dad_timer: DAD structure not found\n");
+               log(LOG_ERR, "nd6_dad_timer: DAD structure not found\n");
                goto done;
        }
        if (ia->ia6_flags & IN6_IFF_DUPLICATED) {
-               printf("nd6_dad_timer: called with duplicated address "
+               log(LOG_ERR, "nd6_dad_timer: called with duplicated address "
                        "%s(%s)\n",
                        ip6_sprintf(&ia->ia_addr.sin6_addr),
                        ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
                goto done;
        }
        if ((ia->ia6_flags & IN6_IFF_TENTATIVE) == 0) {
-               printf("nd6_dad_timer: called with non-tentative address "
+               log(LOG_ERR, "nd6_dad_timer: called with non-tentative address "
                        "%s(%s)\n",
                        ip6_sprintf(&ia->ia_addr.sin6_addr),
                        ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
@@ -985,7 +1024,7 @@
 
        /* timeouted with IFF_{RUNNING,UP} check */
        if (dp->dad_ns_tcount > dad_maxtry) {
-               printf("%s: could not run DAD, driver problem?\n",
+               log(LOG_ERR, "%s: could not run DAD, driver problem?\n",
                    if_name(ifa->ifa_ifp));
 
                TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list);
@@ -1061,8 +1100,9 @@
                         */
                        ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
 
-                       printf("%s: DAD complete for %s - no duplicates "
-                           "found\n", if_name(ifa->ifa_ifp),
+                       log(LOG_INFO,
+                           "%s: DAD complete for %s - no duplicates found\n",
+                           if_name(ifa->ifa_ifp),
                            ip6_sprintf(&ia->ia_addr.sin6_addr));
 
                        TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list);
@@ -1085,7 +1125,7 @@
 
        dp = nd6_dad_find(ifa);
        if (dp == NULL) {
-               printf("nd6_dad_duplicated: DAD structure not found\n");
+               log(LOG_ERR, "nd6_dad_duplicated: DAD structure not found\n");
                return;
        }
 
@@ -1100,9 +1140,10 @@
        /* We are done with DAD, with duplicated address found. (failure) */
        untimeout((void (*) __P((void *)))nd6_dad_timer, (void *)ifa);
 
-       printf("%s: DAD complete for %s - duplicate found\n",
+       log(LOG_ERR, "%s: DAD complete for %s - duplicate found\n",
            if_name(ifa->ifa_ifp), ip6_sprintf(&ia->ia_addr.sin6_addr));
-       printf("%s: manual intervention required\n", if_name(ifa->ifa_ifp));
+       log(LOG_ERR, "%s: manual intervention required\n",
+           if_name(ifa->ifa_ifp));
 
        TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list);
        free(dp, M_IP6NDP);



Home | Main Index | Thread Index | Old Index