Module Name:    src
Committed By:   mlelstv
Date:           Tue Nov 15 20:50:29 UTC 2016

Modified Files:
        src/sys/netinet: tcp_input.c udp_usrreq.c
        src/sys/netinet6: icmp6.c udp6_usrreq.c

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.347 -r1.348 src/sys/netinet/tcp_input.c
cvs rdiff -u -r1.227 -r1.228 src/sys/netinet/udp_usrreq.c
cvs rdiff -u -r1.200 -r1.201 src/sys/netinet6/icmp6.c
cvs rdiff -u -r1.124 -r1.125 src/sys/netinet6/udp6_usrreq.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/netinet/tcp_input.c
diff -u src/sys/netinet/tcp_input.c:1.347 src/sys/netinet/tcp_input.c:1.348
--- src/sys/netinet/tcp_input.c:1.347	Fri Jun 10 13:31:44 2016
+++ src/sys/netinet/tcp_input.c	Tue Nov 15 20:50:28 2016
@@ -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 @@ tcp_input(struct mbuf *m, ...)
 		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));
 
 	/*

Index: src/sys/netinet/udp_usrreq.c
diff -u src/sys/netinet/udp_usrreq.c:1.227 src/sys/netinet/udp_usrreq.c:1.228
--- src/sys/netinet/udp_usrreq.c:1.227	Wed Oct 19 01:13:01 2016
+++ src/sys/netinet/udp_usrreq.c	Tue Nov 15 20:50:28 2016
@@ -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_input(struct mbuf *m, ...)
 		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. */

Index: src/sys/netinet6/icmp6.c
diff -u src/sys/netinet6/icmp6.c:1.200 src/sys/netinet6/icmp6.c:1.201
--- src/sys/netinet6/icmp6.c:1.200	Mon Oct 31 04:16:25 2016
+++ src/sys/netinet6/icmp6.c	Tue Nov 15 20:50:28 2016
@@ -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_input(struct mbuf **mp, int *offp,
 		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));
 
 	/*

Index: src/sys/netinet6/udp6_usrreq.c
diff -u src/sys/netinet6/udp6_usrreq.c:1.124 src/sys/netinet6/udp6_usrreq.c:1.125
--- src/sys/netinet6/udp6_usrreq.c:1.124	Fri Jul 15 07:40:09 2016
+++ src/sys/netinet6/udp6_usrreq.c	Tue Nov 15 20:50:28 2016
@@ -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 @@ udp6_input(struct mbuf **mp, int *offp, 
 		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);
 	/*

Reply via email to