Source-Changes-HG archive

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

[src/trunk]: src/sys Enforce alignment requirements that are violated in some...



details:   https://anonhg.NetBSD.org/src/rev/51df67a559b0
branches:  trunk
changeset: 348917:51df67a559b0
user:      mlelstv <mlelstv%NetBSD.org@localhost>
date:      Tue Nov 15 20:50:28 2016 +0000

description:
Enforce alignment requirements that are violated in some cases.
For machines that don't need strict alignment (i386,amd64,vax,m68k) this
is a no-op.

Fixes PR kern/50766 but should be improved.

diffstat:

 sys/netinet/tcp_input.c    |  19 ++++++++++++++++---
 sys/netinet/udp_usrreq.c   |  17 +++++++++++++++--
 sys/netinet6/icmp6.c       |  18 ++++++++++++++++--
 sys/netinet6/udp6_usrreq.c |  17 +++++++++++++++--
 4 files changed, 62 insertions(+), 9 deletions(-)

diffs (155 lines):

diff -r b204283cc031 -r 51df67a559b0 sys/netinet/tcp_input.c
--- a/sys/netinet/tcp_input.c   Tue Nov 15 19:30:28 2016 +0000
+++ b/sys/netinet/tcp_input.c   Tue Nov 15 20:50:28 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tcp_input.c,v 1.347 2016/06/10 13:31:44 ozaki-r Exp $  */
+/*     $NetBSD: tcp_input.c,v 1.348 2016/11/15 20:50:28 mlelstv Exp $  */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -148,7 +148,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tcp_input.c,v 1.347 2016/06/10 13:31:44 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tcp_input.c,v 1.348 2016/11/15 20:50:28 mlelstv Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -1346,7 +1346,20 @@
                m_freem(m);
                return;
        }
-
+       /*
+         * Enforce alignment requirements that are violated in
+        * some cases, see kern/50766 for details.
+        */
+       if (TCP_HDR_ALIGNED_P(th) == 0) {
+               m = m_copyup(m, toff + sizeof(struct tcphdr), 0);
+               if (m == NULL) {
+                       TCP_STATINC(TCP_STAT_RCVSHORT);
+                       return;
+               }
+               ip = mtod(m, struct ip *);
+               ip6 = mtod(m, struct ip6_hdr *);
+               th = (struct tcphdr *)(mtod(m, char *) + toff);
+       }
        KASSERT(TCP_HDR_ALIGNED_P(th));
 
        /*
diff -r b204283cc031 -r 51df67a559b0 sys/netinet/udp_usrreq.c
--- a/sys/netinet/udp_usrreq.c  Tue Nov 15 19:30:28 2016 +0000
+++ b/sys/netinet/udp_usrreq.c  Tue Nov 15 20:50:28 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: udp_usrreq.c,v 1.227 2016/10/19 01:13:01 ozaki-r Exp $ */
+/*     $NetBSD: udp_usrreq.c,v 1.228 2016/11/15 20:50:28 mlelstv Exp $ */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.227 2016/10/19 01:13:01 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.228 2016/11/15 20:50:28 mlelstv Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -355,6 +355,19 @@
                UDP_STATINC(UDP_STAT_HDROPS);
                return;
        }
+       /*
+        * Enforce alignment requirements that are violated in
+        * some cases, see kern/50766 for details.
+        */
+       if (UDP_HDR_ALIGNED_P(uh) == 0) {
+               m = m_copyup(m, iphlen + sizeof(struct udphdr), 0);
+               if (m == NULL) {
+                       UDP_STATINC(UDP_STAT_HDROPS);
+                       return;
+               }
+               ip = mtod(m, struct ip *);
+               uh = (struct udphdr *)(mtod(m, char *) + iphlen);
+       }
        KASSERT(UDP_HDR_ALIGNED_P(uh));
 
        /* destination port of 0 is illegal, based on RFC768. */
diff -r b204283cc031 -r 51df67a559b0 sys/netinet6/icmp6.c
--- a/sys/netinet6/icmp6.c      Tue Nov 15 19:30:28 2016 +0000
+++ b/sys/netinet6/icmp6.c      Tue Nov 15 20:50:28 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: icmp6.c,v 1.200 2016/10/31 04:16:25 ozaki-r Exp $      */
+/*     $NetBSD: icmp6.c,v 1.201 2016/11/15 20:50:28 mlelstv Exp $      */
 /*     $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: icmp6.c,v 1.200 2016/10/31 04:16:25 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: icmp6.c,v 1.201 2016/11/15 20:50:28 mlelstv Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -482,6 +482,20 @@
                icmp6_ifstat_inc(rcvif, ifs6_in_error);
                goto freeit;
        }
+       /*
+        * Enforce alignment requirements that are violated in
+        * some cases, see kern/50766 for details.
+        */
+       if (IP6_HDR_ALIGNED_P(icmp6) == 0) {
+               m = m_copyup(m, off + sizeof(struct icmp6_hdr), 0);
+               if (m == NULL) {
+                       ICMP6_STATINC(ICMP6_STAT_TOOSHORT);
+                       icmp6_ifstat_inc(rcvif, ifs6_in_error);
+                       goto freeit;
+               }
+               ip6 = mtod(m, struct ip6_hdr *);
+               icmp6 = (struct icmp6_hdr *)(ip6 + 1);
+       }
        KASSERT(IP6_HDR_ALIGNED_P(icmp6));
 
        /*
diff -r b204283cc031 -r 51df67a559b0 sys/netinet6/udp6_usrreq.c
--- a/sys/netinet6/udp6_usrreq.c        Tue Nov 15 19:30:28 2016 +0000
+++ b/sys/netinet6/udp6_usrreq.c        Tue Nov 15 20:50:28 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: udp6_usrreq.c,v 1.124 2016/07/15 07:40:09 ozaki-r Exp $        */
+/*     $NetBSD: udp6_usrreq.c,v 1.125 2016/11/15 20:50:28 mlelstv Exp $        */
 /*     $KAME: udp6_usrreq.c,v 1.86 2001/05/27 17:33:00 itojun Exp $    */
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: udp6_usrreq.c,v 1.124 2016/07/15 07:40:09 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udp6_usrreq.c,v 1.125 2016/11/15 20:50:28 mlelstv Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -581,6 +581,19 @@
                IP6_STATINC(IP6_STAT_TOOSHORT);
                return IPPROTO_DONE;
        }
+       /*
+        * Enforce alignment requirements that are violated in
+        * some cases, see kern/50766 for details.
+        */
+        if (UDP_HDR_ALIGNED_P(uh) == 0) {
+                m = m_copyup(m, off + sizeof(struct udphdr), 0); 
+                if (m == NULL) {
+                        IP6_STATINC(IP6_STAT_TOOSHORT);
+                        return IPPROTO_DONE;
+                }
+               ip6 = mtod(m, struct ip6_hdr *);
+                uh = (struct udphdr *)(mtod(m, char *) + off);
+        }
        KASSERT(UDP_HDR_ALIGNED_P(uh));
        ulen = ntohs((u_short)uh->uh_ulen);
        /*



Home | Main Index | Thread Index | Old Index