CVS commit: [netbsd-6-0] src/sys/netipsec

2018-05-03 Thread Martin Husemann
Module Name:src
Committed By:   martin
Date:   Thu May  3 14:37:25 UTC 2018

Modified Files:
src/sys/netipsec [netbsd-6-0]: ipsec_output.c

Log Message:
Pull up following revision(s) (requested by maxv in ticket #1546):

sys/netipsec/ipsec_output.c: revision 1.67,1.75 (via patch)

Strengthen this check, to make sure there is room for an ip6_ext structure.
Seems possible to crash m_copydata here (but I didn't test more than that).

Fix the checks in compute_ipsec_pos, otherwise m_copydata could crash. I
already fixed half of the problem two months ago in rev1.67, back then I
thought it was not triggerable because each packet we emit is guaranteed
to have correctly formed IPv6 options; but it is actually triggerable via
IPv6 forwarding, we emit a packet we just received, and we don't sanitize
its options before invoking IPsec.

Since it would be wrong to just stop the iteration and continue the IPsec
processing, allow compute_ipsec_pos to fail, and when it does, drop the
packet entirely.


To generate a diff of this commit:
cvs rdiff -u -r1.38 -r1.38.8.1 src/sys/netipsec/ipsec_output.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/netipsec/ipsec_output.c
diff -u src/sys/netipsec/ipsec_output.c:1.38 src/sys/netipsec/ipsec_output.c:1.38.8.1
--- src/sys/netipsec/ipsec_output.c:1.38	Tue Jan 10 20:01:57 2012
+++ src/sys/netipsec/ipsec_output.c	Thu May  3 14:37:25 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ipsec_output.c,v 1.38 2012/01/10 20:01:57 drochner Exp $	*/
+/*	$NetBSD: ipsec_output.c,v 1.38.8.1 2018/05/03 14:37:25 martin Exp $	*/
 
 /*-
  * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
@@ -29,7 +29,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ipsec_output.c,v 1.38 2012/01/10 20:01:57 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipsec_output.c,v 1.38.8.1 2018/05/03 14:37:25 martin Exp $");
 
 /*
  * IPsec output processing.
@@ -632,7 +632,7 @@ bad:
 #endif
 
 #ifdef INET6
-static void
+static int
 compute_ipsec_pos(struct mbuf *m, int *i, int *off)
 {
 	int nxt;
@@ -649,7 +649,11 @@ compute_ipsec_pos(struct mbuf *m, int *i
 	 * put AH/ESP/IPcomp header.
 	 *  IPv6 hbh dest1 rthdr ah* [esp* dest2 payload]
 	 */
-	do {
+	while (1) {
+		if (*i + sizeof(ip6e) > m->m_pkthdr.len) {
+			return EINVAL;
+		}
+
 		switch (nxt) {
 		case IPPROTO_AH:
 		case IPPROTO_ESP:
@@ -658,7 +662,7 @@ compute_ipsec_pos(struct mbuf *m, int *i
 		 * we should not skip security header added
 		 * beforehand.
 		 */
-			return;
+			return 0;
 
 		case IPPROTO_HOPOPTS:
 		case IPPROTO_DSTOPTS:
@@ -668,7 +672,7 @@ compute_ipsec_pos(struct mbuf *m, int *i
 		 * we should stop there.
 		 */
 			if (nxt == IPPROTO_DSTOPTS && dstopt)
-return;
+return 0;
 
 			if (nxt == IPPROTO_DSTOPTS) {
 /*
@@ -688,16 +692,14 @@ compute_ipsec_pos(struct mbuf *m, int *i
 			m_copydata(m, *i, sizeof(ip6e), );
 			nxt = ip6e.ip6e_nxt;
 			*off = *i + offsetof(struct ip6_ext, ip6e_nxt);
-			/*
-			 * we will never see nxt == IPPROTO_AH
-			 * so it is safe to omit AH case.
-			 */
 			*i += (ip6e.ip6e_len + 1) << 3;
 			break;
 		default:
-			return;
+			return 0;
 		}
-	} while (*i < m->m_pkthdr.len);
+	}
+
+	return 0;
 }
 
 static int
@@ -799,7 +801,9 @@ ipsec6_process_packet(
 		i = ip->ip_hl << 2;
 		off = offsetof(struct ip, ip_p);
 	} else {	
-		compute_ipsec_pos(m, , );
+		error = compute_ipsec_pos(m, , );
+		if (error)
+			goto bad;
 	}
 	error = (*sav->tdb_xform->xf_output)(m, isr, NULL, i, off);
 	splx(s);



CVS commit: [netbsd-6-0] src/sys/netipsec

2018-04-18 Thread SAITOH Masanobu
Module Name:src
Committed By:   msaitoh
Date:   Wed Apr 18 07:17:48 UTC 2018

Modified Files:
src/sys/netipsec [netbsd-6-0]: ipsec_mbuf.c

Log Message:
Pull up following revision(s) (requested by maxv in ticket #1545):
sys/netipsec/ipsec_mbuf.c: revision 1.23
sys/netipsec/ipsec_mbuf.c: revision 1.24
Don't assume M_PKTHDR is set only on the first mbuf of the chain. It
should, but it looks like there are several places that can put M_PKTHDR
on secondary mbufs (PR/53189), so drop this assumption right now to
prevent further bugs.
The check is replaced by (m1 != m), which is equivalent to the previous
code: we want to modify m->m_pkthdr.len only when 'm' was not passed in
m_adj().
Fix a pretty bad mistake, that has always been there.
 m_adj(m1, -(m1->m_len - roff));
 if (m1 != m)
 m->m_pkthdr.len -= (m1->m_len - roff);
This is wrong: m_adj will modify m1->m_len, so we're using a wrong value
when manually adjusting m->m_pkthdr.len.
Because of that, it is possible to exploit the attack I described in
uipc_mbuf.c::rev1.182. The exploit is more complicated, but works 100%
reliably.


To generate a diff of this commit:
cvs rdiff -u -r1.12 -r1.12.16.1 src/sys/netipsec/ipsec_mbuf.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/netipsec/ipsec_mbuf.c
diff -u src/sys/netipsec/ipsec_mbuf.c:1.12 src/sys/netipsec/ipsec_mbuf.c:1.12.16.1
--- src/sys/netipsec/ipsec_mbuf.c:1.12	Mon May 16 10:05:23 2011
+++ src/sys/netipsec/ipsec_mbuf.c	Wed Apr 18 07:17:48 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ipsec_mbuf.c,v 1.12 2011/05/16 10:05:23 drochner Exp $	*/
+/*	$NetBSD: ipsec_mbuf.c,v 1.12.16.1 2018/04/18 07:17:48 msaitoh Exp $	*/
 /*-
  * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
  * All rights reserved.
@@ -28,7 +28,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ipsec_mbuf.c,v 1.12 2011/05/16 10:05:23 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipsec_mbuf.c,v 1.12.16.1 2018/04/18 07:17:48 msaitoh Exp $");
 
 /*
  * IPsec-specific mbuf routines.
@@ -407,10 +407,11 @@ m_striphdr(struct mbuf *m, int skip, int
 		/* The header was at the beginning of the mbuf */
 		IPSEC_STATINC(IPSEC_STAT_INPUT_FRONT);
 		m_adj(m1, hlen);
-		if ((m1->m_flags & M_PKTHDR) == 0)
+		if (m1 != m)
 			m->m_pkthdr.len -= hlen;
 	} else if (roff + hlen >= m1->m_len) {
 		struct mbuf *mo;
+		int adjlen;
 
 		/*
 		 * Part or all of the header is at the end of this mbuf,
@@ -419,11 +420,13 @@ m_striphdr(struct mbuf *m, int skip, int
 		 */
 		IPSEC_STATINC(IPSEC_STAT_INPUT_END);
 		if (roff + hlen > m1->m_len) {
+			adjlen = roff + hlen - m1->m_len;
+
 			/* Adjust the next mbuf by the remainder */
-			m_adj(m1->m_next, roff + hlen - m1->m_len);
+			m_adj(m1->m_next, adjlen);
 
 			/* The second mbuf is guaranteed not to have a pkthdr... */
-			m->m_pkthdr.len -= (roff + hlen - m1->m_len);
+			m->m_pkthdr.len -= adjlen;
 		}
 
 		/* Now, let's unlink the mbuf chain for a second...*/
@@ -431,9 +434,10 @@ m_striphdr(struct mbuf *m, int skip, int
 		m1->m_next = NULL;
 
 		/* ...and trim the end of the first part of the chain...sick */
-		m_adj(m1, -(m1->m_len - roff));
-		if ((m1->m_flags & M_PKTHDR) == 0)
-			m->m_pkthdr.len -= (m1->m_len - roff);
+		adjlen = m1->m_len - roff;
+		m_adj(m1, -adjlen);
+		if (m1 != m)
+			m->m_pkthdr.len -= adjlen;
 
 		/* Finally, let's relink */
 		m1->m_next = mo;



CVS commit: [netbsd-6-0] src/sys/netipsec

2018-03-13 Thread Soren Jacobsen
Module Name:src
Committed By:   snj
Date:   Tue Mar 13 17:47:11 UTC 2018

Modified Files:
src/sys/netipsec [netbsd-6-0]: ipsec_input.c

Log Message:
Pull up following revision(s) (requested by maxv in ticket #1536):
sys/netipsec/ipsec_input.c: 1.57-1.58
Extend these #ifdef notyet. The m_copydata's in these branches are wrong,
we are not guaranteed to have enough room for another struct ip, and we
may crash here. Triggerable remotely, but after authentication, by sending
an AH packet that has a one-byte-sized IPIP payload.
--
Argh, in my previous commit in this file I forgot to fix the IPv6
entry point; apply the same fix there.


To generate a diff of this commit:
cvs rdiff -u -r1.29 -r1.29.8.1 src/sys/netipsec/ipsec_input.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/netipsec/ipsec_input.c
diff -u src/sys/netipsec/ipsec_input.c:1.29 src/sys/netipsec/ipsec_input.c:1.29.8.1
--- src/sys/netipsec/ipsec_input.c:1.29	Wed Jan 25 21:58:10 2012
+++ src/sys/netipsec/ipsec_input.c	Tue Mar 13 17:47:11 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ipsec_input.c,v 1.29 2012/01/25 21:58:10 drochner Exp $	*/
+/*	$NetBSD: ipsec_input.c,v 1.29.8.1 2018/03/13 17:47:11 snj Exp $	*/
 /*	$FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/netipsec/ipsec_input.c,v 1.2.4.2 2003/03/28 20:32:53 sam Exp $	*/
 /*	$OpenBSD: ipsec_input.c,v 1.63 2003/02/20 18:35:43 deraadt Exp $	*/
 
@@ -39,7 +39,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ipsec_input.c,v 1.29 2012/01/25 21:58:10 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipsec_input.c,v 1.29.8.1 2018/03/13 17:47:11 snj Exp $");
 
 /*
  * IPsec input processing.
@@ -332,14 +332,15 @@ ipsec4_common_input_cb(struct mbuf *m, s
 	ip->ip_len = htons(m->m_pkthdr.len);
 	prot = ip->ip_p;
 
+#ifdef notyet
 	/* IP-in-IP encapsulation */
 	if (prot == IPPROTO_IPIP) {
 		struct ip ipn;
 
 		/* ipn will now contain the inner IPv4 header */
+		/* XXX: check m_pkthdr.len */
 		m_copydata(m, ip->ip_hl << 2, sizeof(struct ip), );
 
-#ifdef notyet
 		/* XXX PROXY address isn't recorded in SAH */
 		/*
 		 * Check that the inner source address is the same as
@@ -367,7 +368,6 @@ ipsec4_common_input_cb(struct mbuf *m, s
 			error = EACCES;
 			goto bad;
 		}
-#endif /*XXX*/
 	}
 #if INET6
 	/* IPv6-in-IP encapsulation. */
@@ -375,9 +375,9 @@ ipsec4_common_input_cb(struct mbuf *m, s
 		struct ip6_hdr ip6n;
 
 		/* ip6n will now contain the inner IPv6 header. */
+		/* XXX: check m_pkthdr.len */
 		m_copydata(m, ip->ip_hl << 2, sizeof(struct ip6_hdr), );
 
-#ifdef notyet
 		/*
 		 * Check that the inner source address is the same as
 		 * the proxy address, if available.
@@ -403,9 +403,9 @@ ipsec4_common_input_cb(struct mbuf *m, s
 			error = EACCES;
 			goto bad;
 		}
-#endif /*XXX*/
 	}
 #endif /* INET6 */
+#endif /* notyet */
 
 	/*
 	 * Record what we've done to the packet (under what SA it was
@@ -651,15 +651,16 @@ ipsec6_common_input_cb(struct mbuf *m, s
 	/* Save protocol */
 	m_copydata(m, protoff, 1, );
 
+#ifdef notyet
 #ifdef INET
 	/* IP-in-IP encapsulation */
 	if (prot == IPPROTO_IPIP) {
 		struct ip ipn;
 
 		/* ipn will now contain the inner IPv4 header */
+		/* XXX: check m_pkthdr.len */
 		m_copydata(m, skip, sizeof(struct ip), );
 
-#ifdef notyet
 		/*
 		 * Check that the inner source address is the same as
 		 * the proxy address, if available.
@@ -683,18 +684,16 @@ ipsec6_common_input_cb(struct mbuf *m, s
 			error = EACCES;
 			goto bad;
 		}
-#endif /*XXX*/
 	}
 #endif /* INET */
-
 	/* IPv6-in-IP encapsulation */
 	if (prot == IPPROTO_IPV6) {
 		struct ip6_hdr ip6n;
 
 		/* ip6n will now contain the inner IPv6 header. */
+		/* XXX: check m_pkthdr.len */
 		m_copydata(m, skip, sizeof(struct ip6_hdr), );
 
-#ifdef notyet
 		/*
 		 * Check that the inner source address is the same as
 		 * the proxy address, if available.
@@ -719,8 +718,8 @@ ipsec6_common_input_cb(struct mbuf *m, s
 			error = EACCES;
 			goto bad;
 		}
-#endif /*XXX*/
 	}
+#endif /* notyet */
 
 	/*
 	 * Record what we've done to the packet (under what SA it was



CVS commit: [netbsd-6-0] src/sys/netipsec

2018-03-13 Thread Soren Jacobsen
Module Name:src
Committed By:   snj
Date:   Tue Mar 13 17:18:12 UTC 2018

Modified Files:
src/sys/netipsec [netbsd-6-0]: xform_ah.c xform_esp.c xform_ipip.c

Log Message:
Pull up following revision(s) (requested by maxv in ticket #1532):
sys/netipsec/xform_ah.c: 1.77 via patch
sys/netipsec/xform_esp.c: 1.73 via patch
sys/netipsec/xform_ipip.c: 1.56-1.57 via patch
Reinforce and clarify.
--
Add missing NULL check. Normally that's not triggerable remotely, since we
are guaranteed that 8 bytes are valid at mbuf+skip.
--
Fix use-after-free. There is a path where the mbuf gets pulled up without
a proper mtod afterwards:
218 ipo = mtod(m, struct ip *);
281 m = m_pullup(m, hlen);
232 ipo->ip_src.s_addr
Found by Mootja.
Meanwhile it seems to me that 'ipo' should be set to NULL if the inner
packet is IPv6, but I'll revisit that later.
--
As I said in my last commit in this file, ipo should be set to NULL;
otherwise the 'local address spoofing' check below is always wrong on
IPv6.


To generate a diff of this commit:
cvs rdiff -u -r1.37.6.3 -r1.37.6.4 src/sys/netipsec/xform_ah.c
cvs rdiff -u -r1.40 -r1.40.6.1 src/sys/netipsec/xform_esp.c
cvs rdiff -u -r1.28.14.1 -r1.28.14.2 src/sys/netipsec/xform_ipip.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/netipsec/xform_ah.c
diff -u src/sys/netipsec/xform_ah.c:1.37.6.3 src/sys/netipsec/xform_ah.c:1.37.6.4
--- src/sys/netipsec/xform_ah.c:1.37.6.3	Thu Feb 15 16:50:01 2018
+++ src/sys/netipsec/xform_ah.c	Tue Mar 13 17:18:12 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: xform_ah.c,v 1.37.6.3 2018/02/15 16:50:01 martin Exp $	*/
+/*	$NetBSD: xform_ah.c,v 1.37.6.4 2018/03/13 17:18:12 snj Exp $	*/
 /*	$FreeBSD: src/sys/netipsec/xform_ah.c,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $	*/
 /*	$OpenBSD: ip_ah.c,v 1.63 2001/06/26 06:18:58 angelos Exp $ */
 /*
@@ -39,7 +39,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: xform_ah.c,v 1.37.6.3 2018/02/15 16:50:01 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xform_ah.c,v 1.37.6.4 2018/03/13 17:18:12 snj Exp $");
 
 #include "opt_inet.h"
 #ifdef __FreeBSD__
@@ -498,54 +498,45 @@ ah_massage_headers(struct mbuf **m0, int
 
 		nxt = ip6.ip6_nxt & 0xff; /* Next header type. */
 
-		for (off = 0; off < skip - sizeof(struct ip6_hdr);)
+		for (off = 0; off < skip - sizeof(struct ip6_hdr);) {
+			int noff;
+
 			switch (nxt) {
 			case IPPROTO_HOPOPTS:
 			case IPPROTO_DSTOPTS:
-ip6e = (struct ip6_ext *) (ptr + off);
+ip6e = (struct ip6_ext *)(ptr + off);
+noff = off + ((ip6e->ip6e_len + 1) << 3);
+
+/* Sanity check. */
+if (noff > skip - sizeof(struct ip6_hdr)) {
+	goto error6;
+}
 
 /*
- * Process the mutable/immutable
- * options -- borrows heavily from the
- * KAME code.
+ * Zero out mutable options.
  */
 for (count = off + sizeof(struct ip6_ext);
- count < off + ((ip6e->ip6e_len + 1) << 3);) {
+ count < noff;) {
 	if (ptr[count] == IP6OPT_PAD1) {
 		count++;
-		continue; /* Skip padding. */
-	}
-
-	/* Sanity check. */
-	if (count > off +
-	((ip6e->ip6e_len + 1) << 3)) {
-		m_freem(m);
-
-		/* Free, if we allocated. */
-		if (alloc)
-			free(ptr, M_XDATA);
-		return EINVAL;
+		continue;
 	}
 
 	ad = ptr[count + 1] + 2;
 
-	/* If mutable option, zeroize. */
-	if (ptr[count] & IP6OPT_MUTABLE)
-		memcpy(ptr + count, ipseczeroes,
-		ad);
+	if (count + ad > noff) {
+		goto error6;
+	}
+
+	if (ptr[count] & IP6OPT_MUTABLE) {
+		memset(ptr + count, 0, ad);
+	}
 
 	count += ad;
+}
 
-	/* Sanity check. */
-	if (count >
-	skip - sizeof(struct ip6_hdr)) {
-		m_freem(m);
-
-		/* Free, if we allocated. */
-		if (alloc)
-			free(ptr, M_XDATA);
-		return EINVAL;
-	}
+if (count != noff) {
+	goto error6;
 }
 
 /* Advance. */
@@ -603,11 +594,13 @@ ah_massage_headers(struct mbuf **m0, int
 			default:
 DPRINTF(("ah_massage_headers: unexpected "
 "IPv6 header type %d", off));
+error6:
 if (alloc)
 	free(ptr, M_XDATA);
 m_freem(m);
 return EINVAL;
 			}
+		}
 
 		/* Copyback and free, if we allocated. */
 		if (alloc) {

Index: src/sys/netipsec/xform_esp.c
diff -u src/sys/netipsec/xform_esp.c:1.40 src/sys/netipsec/xform_esp.c:1.40.6.1
--- src/sys/netipsec/xform_esp.c:1.40	Wed Jan 25 20:31:23 2012
+++ src/sys/netipsec/xform_esp.c	Tue Mar 13 17:18:12 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: xform_esp.c,v 1.40 2012/01/25 20:31:23 drochner Exp $	*/
+/*	$NetBSD: xform_esp.c,v 1.40.6.1 2018/03/13 17:18:12 snj Exp $	*/
 /*	$FreeBSD: src/sys/netipsec/xform_esp.c,v 1.2.2.1 2003/01/24 05:11:36 sam Exp $	*/
 /*	$OpenBSD: ip_esp.c,v 1.69 2001/06/26 06:18:59 angelos Exp $ */
 
@@ -39,7 +39,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: xform_esp.c,v 1.40 2012/01/25 20:31:23 

CVS commit: [netbsd-6-0] src/sys/netipsec

2018-02-16 Thread Martin Husemann
Module Name:src
Committed By:   martin
Date:   Fri Feb 16 18:12:47 UTC 2018

Modified Files:
src/sys/netipsec [netbsd-6-0]: ipsec.c

Log Message:
Pull up following revision(s) (requested by maxv in ticket #1531):

sys/netipsec/ipsec.c: revision 1.130

Fix inverted logic, otherwise the kernel crashes when receiving a 1-byte
AH packet. Triggerable before authentication when IPsec and forwarding
are both enabled.


To generate a diff of this commit:
cvs rdiff -u -r1.55 -r1.55.12.1 src/sys/netipsec/ipsec.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/netipsec/ipsec.c
diff -u src/sys/netipsec/ipsec.c:1.55 src/sys/netipsec/ipsec.c:1.55.12.1
--- src/sys/netipsec/ipsec.c:1.55	Thu Jun  9 19:54:18 2011
+++ src/sys/netipsec/ipsec.c	Fri Feb 16 18:12:47 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ipsec.c,v 1.55 2011/06/09 19:54:18 drochner Exp $	*/
+/*	$NetBSD: ipsec.c,v 1.55.12.1 2018/02/16 18:12:47 martin Exp $	*/
 /*	$FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/netipsec/ipsec.c,v 1.2.2.2 2003/07/01 01:38:13 sam Exp $	*/
 /*	$KAME: ipsec.c,v 1.103 2001/05/24 07:14:18 sakane Exp $	*/
 
@@ -32,7 +32,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ipsec.c,v 1.55 2011/06/09 19:54:18 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipsec.c,v 1.55.12.1 2018/02/16 18:12:47 martin Exp $");
 
 /*
  * IPsec controller part.
@@ -979,7 +979,7 @@ ipsec4_get_ulp(struct mbuf *m, struct se
 			spidx->dst.sin.sin_port = uh.uh_dport;
 			return;
 		case IPPROTO_AH:
-			if (m->m_pkthdr.len > off + sizeof(ip6e))
+			if (off + sizeof(ip6e) > m->m_pkthdr.len)
 goto done;
 			/* XXX sigh, this works but is totally bogus */
 			m_copydata(m, off, sizeof(ip6e), );



CVS commit: [netbsd-6-0] src/sys/netipsec

2018-02-15 Thread Martin Husemann
Module Name:src
Committed By:   martin
Date:   Thu Feb 15 16:50:01 UTC 2018

Modified Files:
src/sys/netipsec [netbsd-6-0]: xform_ah.c

Log Message:
Fix previous (Ticket #1530)


To generate a diff of this commit:
cvs rdiff -u -r1.37.6.2 -r1.37.6.3 src/sys/netipsec/xform_ah.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/netipsec/xform_ah.c
diff -u src/sys/netipsec/xform_ah.c:1.37.6.2 src/sys/netipsec/xform_ah.c:1.37.6.3
--- src/sys/netipsec/xform_ah.c:1.37.6.2	Thu Feb 15 08:11:25 2018
+++ src/sys/netipsec/xform_ah.c	Thu Feb 15 16:50:01 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: xform_ah.c,v 1.37.6.2 2018/02/15 08:11:25 martin Exp $	*/
+/*	$NetBSD: xform_ah.c,v 1.37.6.3 2018/02/15 16:50:01 martin Exp $	*/
 /*	$FreeBSD: src/sys/netipsec/xform_ah.c,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $	*/
 /*	$OpenBSD: ip_ah.c,v 1.63 2001/06/26 06:18:58 angelos Exp $ */
 /*
@@ -39,7 +39,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: xform_ah.c,v 1.37.6.2 2018/02/15 08:11:25 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xform_ah.c,v 1.37.6.3 2018/02/15 16:50:01 martin Exp $");
 
 #include "opt_inet.h"
 #ifdef __FreeBSD__
@@ -687,11 +687,10 @@ ah_input(struct mbuf *m, const struct se
 		return EACCES;
 	}
 	if (skip + authsize + rplen > m->m_pkthdr.len) {
-		char buf[IPSEC_ADDRSTRLEN];
 		DPRINTF(("%s: bad mbuf length %u (expecting >= %lu)"
 			" for packet in SA %s/%08lx\n", __func__,
 			m->m_pkthdr.len, (u_long)(skip + authsize + rplen),
-			ipsec_address(>sah->saidx.dst, buf, sizeof(buf)),
+			ipsec_address(>sah->saidx.dst),
 			(u_long) ntohl(sav->spi)));
 		AH_STATINC(AH_STAT_BADAUTHL);
 		m_freem(m);



CVS commit: [netbsd-6-0] src/sys/netipsec

2018-02-15 Thread Martin Husemann
Module Name:src
Committed By:   martin
Date:   Thu Feb 15 14:51:44 UTC 2018

Modified Files:
src/sys/netipsec [netbsd-6-0]: xform_ipip.c

Log Message:
Pull up following revision(s) (requested by maxv in ticket #1529):
sys/netipsec/xform_ipip.c: revision 1.44 via patch

PR/52161: Ryota Ozaki: Fix AH tunnel ipsec for ipv6. Compute plen right,
don't forget to subtract the ipv6 header length.


To generate a diff of this commit:
cvs rdiff -u -r1.28 -r1.28.14.1 src/sys/netipsec/xform_ipip.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/netipsec/xform_ipip.c
diff -u src/sys/netipsec/xform_ipip.c:1.28 src/sys/netipsec/xform_ipip.c:1.28.14.1
--- src/sys/netipsec/xform_ipip.c:1.28	Sun Jul 17 20:54:54 2011
+++ src/sys/netipsec/xform_ipip.c	Thu Feb 15 14:51:44 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: xform_ipip.c,v 1.28 2011/07/17 20:54:54 joerg Exp $	*/
+/*	$NetBSD: xform_ipip.c,v 1.28.14.1 2018/02/15 14:51:44 martin Exp $	*/
 /*	$FreeBSD: src/sys/netipsec/xform_ipip.c,v 1.3.2.1 2003/01/24 05:11:36 sam Exp $	*/
 /*	$OpenBSD: ip_ipip.c,v 1.25 2002/06/10 18:04:55 itojun Exp $ */
 
@@ -39,7 +39,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: xform_ipip.c,v 1.28 2011/07/17 20:54:54 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xform_ipip.c,v 1.28.14.1 2018/02/15 14:51:44 martin Exp $");
 
 /*
  * IP-inside-IP processing
@@ -566,7 +566,7 @@ ipip_output(
 		ip6o->ip6_flow = 0;
 		ip6o->ip6_vfc &= ~IPV6_VERSION_MASK;
 		ip6o->ip6_vfc |= IPV6_VERSION;
-		ip6o->ip6_plen = htons(m->m_pkthdr.len);
+		ip6o->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6o));
 		ip6o->ip6_hlim = ip_defttl;
 		ip6o->ip6_dst = saidx->dst.sin6.sin6_addr;
 		ip6o->ip6_src = saidx->src.sin6.sin6_addr;



CVS commit: [netbsd-6-0] src/sys/netipsec

2018-02-15 Thread Martin Husemann
Module Name:src
Committed By:   martin
Date:   Thu Feb 15 08:11:25 UTC 2018

Modified Files:
src/sys/netipsec [netbsd-6-0]: xform_ah.c

Log Message:
Pull up following revision(s) (requested by maxv in ticket #1530):
sys/netipsec/xform_ah.c: revision 1.80-1.81 via patch

Fix use-after-free, 'ah' may not be valid after m_makewritable and
ah_massage_headers.

Make sure the Authentication Header fits the mbuf chain, otherwise panic.


To generate a diff of this commit:
cvs rdiff -u -r1.37.6.1 -r1.37.6.2 src/sys/netipsec/xform_ah.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/netipsec/xform_ah.c
diff -u src/sys/netipsec/xform_ah.c:1.37.6.1 src/sys/netipsec/xform_ah.c:1.37.6.2
--- src/sys/netipsec/xform_ah.c:1.37.6.1	Mon Jan 29 19:30:53 2018
+++ src/sys/netipsec/xform_ah.c	Thu Feb 15 08:11:25 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: xform_ah.c,v 1.37.6.1 2018/01/29 19:30:53 martin Exp $	*/
+/*	$NetBSD: xform_ah.c,v 1.37.6.2 2018/02/15 08:11:25 martin Exp $	*/
 /*	$FreeBSD: src/sys/netipsec/xform_ah.c,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $	*/
 /*	$OpenBSD: ip_ah.c,v 1.63 2001/06/26 06:18:58 angelos Exp $ */
 /*
@@ -39,7 +39,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: xform_ah.c,v 1.37.6.1 2018/01/29 19:30:53 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xform_ah.c,v 1.37.6.2 2018/02/15 08:11:25 martin Exp $");
 
 #include "opt_inet.h"
 #ifdef __FreeBSD__
@@ -636,6 +636,7 @@ ah_input(struct mbuf *m, const struct se
 	struct m_tag *mtag;
 	struct newah *ah;
 	int hl, rplen, authsize, error;
+	uint8_t nxt;
 
 	struct cryptodesc *crda;
 	struct cryptop *crp;
@@ -660,6 +661,8 @@ ah_input(struct mbuf *m, const struct se
 		return ENOBUFS;
 	}
 
+	nxt = ah->ah_nxt;
+
 	/* Check replay window, if applicable. */
 	if (sav->replay && !ipsec_chkreplay(ntohl(ah->ah_seq), sav)) {
 		AH_STATINC(AH_STAT_REPLAY);
@@ -683,6 +686,18 @@ ah_input(struct mbuf *m, const struct se
 		m_freem(m);
 		return EACCES;
 	}
+	if (skip + authsize + rplen > m->m_pkthdr.len) {
+		char buf[IPSEC_ADDRSTRLEN];
+		DPRINTF(("%s: bad mbuf length %u (expecting >= %lu)"
+			" for packet in SA %s/%08lx\n", __func__,
+			m->m_pkthdr.len, (u_long)(skip + authsize + rplen),
+			ipsec_address(>sah->saidx.dst, buf, sizeof(buf)),
+			(u_long) ntohl(sav->spi)));
+		AH_STATINC(AH_STAT_BADAUTHL);
+		m_freem(m);
+		return EACCES;
+	}
+
 	AH_STATADD(AH_STAT_IBYTES, m->m_pkthdr.len - skip - hl);
 
 	/* Get crypto descriptors. */
@@ -780,7 +795,7 @@ ah_input(struct mbuf *m, const struct se
 	tc->tc_spi = sav->spi;
 	tc->tc_dst = sav->sah->saidx.dst;
 	tc->tc_proto = sav->sah->saidx.proto;
-	tc->tc_nxt = ah->ah_nxt;
+	tc->tc_nxt = nxt;
 	tc->tc_protoff = protoff;
 	tc->tc_skip = skip;
 	tc->tc_ptr = mtag; /* Save the mtag we've identified. */



CVS commit: [netbsd-6-0] src/sys/netipsec

2018-01-29 Thread Martin Husemann
Module Name:src
Committed By:   martin
Date:   Mon Jan 29 19:30:53 UTC 2018

Modified Files:
src/sys/netipsec [netbsd-6-0]: xform_ah.c

Log Message:
Pull up following revision(s) (requested by maxv in ticket #1521):
sys/netipsec/xform_ah.c: revision 1.76
Fix a vulnerability in IPsec-IPv6-AH, that allows an attacker to remotely
crash the kernel with a single packet.
In this loop we need to increment 'ad' by two, because the length field
of the option header does not count the size of the option header itself.
If the length is zero, then 'count' is incremented by zero, and there's
an infinite loop. Beyond that, this code was written with the assumption
that since the IPv6 packet already went through the generic IPv6 option
parser, several fields are guaranteed to be valid; but this assumption
does not hold because of the missing '+2', and there's as a result a
triggerable buffer overflow (write zeros after the end of the mbuf,
potentially to the next mbuf in memory since it's a pool).
Add the missing '+2', this place will be reinforced in separate commits.


To generate a diff of this commit:
cvs rdiff -u -r1.37 -r1.37.6.1 src/sys/netipsec/xform_ah.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/netipsec/xform_ah.c
diff -u src/sys/netipsec/xform_ah.c:1.37 src/sys/netipsec/xform_ah.c:1.37.6.1
--- src/sys/netipsec/xform_ah.c:1.37	Thu Jan 26 21:10:24 2012
+++ src/sys/netipsec/xform_ah.c	Mon Jan 29 19:30:53 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: xform_ah.c,v 1.37 2012/01/26 21:10:24 drochner Exp $	*/
+/*	$NetBSD: xform_ah.c,v 1.37.6.1 2018/01/29 19:30:53 martin Exp $	*/
 /*	$FreeBSD: src/sys/netipsec/xform_ah.c,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $	*/
 /*	$OpenBSD: ip_ah.c,v 1.63 2001/06/26 06:18:58 angelos Exp $ */
 /*
@@ -39,7 +39,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: xform_ah.c,v 1.37 2012/01/26 21:10:24 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xform_ah.c,v 1.37.6.1 2018/01/29 19:30:53 martin Exp $");
 
 #include "opt_inet.h"
 #ifdef __FreeBSD__
@@ -527,12 +527,12 @@ ah_massage_headers(struct mbuf **m0, int
 		return EINVAL;
 	}
 
-	ad = ptr[count + 1];
+	ad = ptr[count + 1] + 2;
 
 	/* If mutable option, zeroize. */
 	if (ptr[count] & IP6OPT_MUTABLE)
 		memcpy(ptr + count, ipseczeroes,
-		ptr[count + 1]);
+		ad);
 
 	count += ad;