Source-Changes-HG archive

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

[src/netbsd-1-5]: src/sys/netinet Pull up UDP, ICMP fixes:



details:   https://anonhg.NetBSD.org/src/rev/d5e00fb651b3
branches:  netbsd-1-5
changeset: 488792:d5e00fb651b3
user:      sommerfeld <sommerfeld%NetBSD.org@localhost>
date:      Fri Jul 28 16:58:09 2000 +0000

description:
Pull up UDP, ICMP fixes:

 - Drop packet, increment udps_badlen if the udp header length field
   reports a size smaller than the udp header; defends against bogus
   packets seen by by Assar Westerlund.

 - allow icmp_error() to work when icmpreturndatabytes is sufficiently
   large that the icmp error message doesn't fit in a header mbuf.

 - defend against mbuf chains shorter than their contained ip->ip_len.

Joint work of myself, itojun, and assar
Approved by thorpej

revisions pulled up:
        sys/netinet/ip_icmp.c           1.52
        sys/netinet/udp_usrreq.c        1.70

diffstat:

 sys/netinet/ip_icmp.c    |  38 ++++++++++++++++++++++++++++++++++----
 sys/netinet/udp_usrreq.c |   6 +++---
 2 files changed, 37 insertions(+), 7 deletions(-)

diffs (90 lines):

diff -r e394746ef113 -r d5e00fb651b3 sys/netinet/ip_icmp.c
--- a/sys/netinet/ip_icmp.c     Fri Jul 28 14:08:15 2000 +0000
+++ b/sys/netinet/ip_icmp.c     Fri Jul 28 16:58:09 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ip_icmp.c,v 1.47.2.1 2000/07/02 14:25:59 sommerfeld Exp $      */
+/*     $NetBSD: ip_icmp.c,v 1.47.2.2 2000/07/28 16:58:09 sommerfeld Exp $      */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -176,7 +176,7 @@
        unsigned oiplen = oip->ip_hl << 2;
        struct icmp *icp;
        struct mbuf *m;
-       unsigned icmplen;
+       unsigned icmplen, mblen;
 
 #ifdef ICMPPRINTFS
        if (icmpprintfs)
@@ -215,12 +215,42 @@
        /*
         * Now, formulate icmp message
         */
+       icmplen = oiplen + min(icmpreturndatabytes, oip->ip_len - oiplen);
+       /*
+        * Defend against mbuf chains shorter than oip->ip_len:
+        */
+       mblen = 0;
+       for (m = n; m && (mblen < icmplen); m = m->m_next)
+               mblen += m->m_len;
+       icmplen = min(mblen, icmplen);
+
+       /*
+        * As we are not required to return everything we have,
+        * we return whatever we can return at ease.
+        *
+        * Note that ICMP datagrams longer than 576 octets are out of spec
+        * according to RFC1812; the limit on icmpreturndatabytes below in
+        * icmp_sysctl will keep things below that limit.
+        */
+
+       KASSERT(ICMP_MINLEN <= MCLBYTES);
+
+       if (icmplen + ICMP_MINLEN > MCLBYTES)
+               icmplen = MCLBYTES - ICMP_MINLEN;
+
        m = m_gethdr(M_DONTWAIT, MT_HEADER);
+       if (m && (icmplen + ICMP_MINLEN > MHLEN)) {
+               MCLGET(m, M_DONTWAIT);
+               if ((m->m_flags & M_EXT) == 0) {
+                       m_freem(m);
+                       m = NULL;
+               }
+       }
        if (m == NULL)
                goto freeit;
-       icmplen = oiplen + min(icmpreturndatabytes, oip->ip_len - oiplen);
        m->m_len = icmplen + ICMP_MINLEN;
-       MH_ALIGN(m, m->m_len);
+       if ((m->m_flags & M_EXT) == 0)
+               MH_ALIGN(m, m->m_len);
        icp = mtod(m, struct icmp *);
        if ((u_int)type > ICMP_MAXTYPE)
                panic("icmp_error");
diff -r e394746ef113 -r d5e00fb651b3 sys/netinet/udp_usrreq.c
--- a/sys/netinet/udp_usrreq.c  Fri Jul 28 14:08:15 2000 +0000
+++ b/sys/netinet/udp_usrreq.c  Fri Jul 28 16:58:09 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: udp_usrreq.c,v 1.66 2000/03/30 13:25:11 augustss Exp $ */
+/*     $NetBSD: udp_usrreq.c,v 1.66.4.1 2000/07/28 16:58:10 sommerfeld Exp $   */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -232,7 +232,7 @@
         */
        len = ntohs((u_int16_t)uh->uh_ulen);
        if (ip->ip_len != iphlen + len) {
-               if (ip->ip_len < iphlen + len) {
+               if (ip->ip_len < iphlen + len || len < sizeof(struct udphdr)) {
                        udpstat.udps_badlen++;
                        goto bad;
                }
@@ -925,7 +925,7 @@
         */
        len = ntohs((u_int16_t)uh->uh_ulen);
        if (ip->ip_len != iphlen + len) {
-               if (ip->ip_len < iphlen + len) {
+               if (ip->ip_len < iphlen + len || len < sizeof(struct udphdr)) {
                        udpstat.udps_badlen++;
                        goto bad;
                }



Home | Main Index | Thread Index | Old Index