Module Name:    src
Committed By:   drochner
Date:           Wed Jan 25 20:31:23 UTC 2012

Modified Files:
        src/sys/netipsec: xform_ah.c xform_esp.c xform_ipcomp.c

Log Message:
Make sure the mbufs in the input path (only the parts which we are going
to modify in the AH case) are writable/non-shared.
This addresses PR kern/33162 by Jeff Rizzo, and replaces the insufficient
patch from that time by a radical solution.
(The PR's problem had been worked around by rev.1.3 of xennetback_xenbus.c,
so it needs a network driver modification to reproduce it.)
Being here, clarify a bit of ipcomp -- uncompression is done in-place,
the header must be removed explicitly.


To generate a diff of this commit:
cvs rdiff -u -r1.35 -r1.36 src/sys/netipsec/xform_ah.c
cvs rdiff -u -r1.39 -r1.40 src/sys/netipsec/xform_esp.c
cvs rdiff -u -r1.28 -r1.29 src/sys/netipsec/xform_ipcomp.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.35 src/sys/netipsec/xform_ah.c:1.36
--- src/sys/netipsec/xform_ah.c:1.35	Tue Jan 24 21:57:03 2012
+++ src/sys/netipsec/xform_ah.c	Wed Jan 25 20:31:23 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: xform_ah.c,v 1.35 2012/01/24 21:57:03 drochner Exp $	*/
+/*	$NetBSD: xform_ah.c,v 1.36 2012/01/25 20:31:23 drochner 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 <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xform_ah.c,v 1.35 2012/01/24 21:57:03 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xform_ah.c,v 1.36 2012/01/25 20:31:23 drochner Exp $");
 
 #include "opt_inet.h"
 #ifdef __FreeBSD__
@@ -641,7 +641,7 @@ ah_input(struct mbuf *m, const struct se
 	struct tdb_crypto *tc;
 	struct m_tag *mtag;
 	struct newah *ah;
-	int hl, rplen, authsize;
+	int hl, rplen, authsize, error;
 
 	struct cryptodesc *crda;
 	struct cryptop *crp;
@@ -746,10 +746,18 @@ ah_input(struct mbuf *m, const struct se
 		return ENOBUFS;
 	}
 
+	error = m_makewritable(&m, 0, skip + rplen + authsize, M_NOWAIT);
+	if (error) {
+		m_freem(m);
+		DPRINTF(("ah_input: failed to copyback_cow\n"));
+		AH_STATINC(AH_STAT_HDROPS);
+		free(tc, M_XDATA);
+		crypto_freereq(crp);
+		return error;
+	}
+
 	/* Only save information if crypto processing is needed. */
 	if (mtag == NULL) {
-		int error;
-
 		/*
 		 * Save the authenticator, the skipped portion of the packet,
 		 * and the AH header.

Index: src/sys/netipsec/xform_esp.c
diff -u src/sys/netipsec/xform_esp.c:1.39 src/sys/netipsec/xform_esp.c:1.40
--- src/sys/netipsec/xform_esp.c:1.39	Wed Aug 31 18:31:04 2011
+++ src/sys/netipsec/xform_esp.c	Wed Jan 25 20:31:23 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: xform_esp.c,v 1.39 2011/08/31 18:31:04 plunky Exp $	*/
+/*	$NetBSD: xform_esp.c,v 1.40 2012/01/25 20:31:23 drochner 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 <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xform_esp.c,v 1.39 2011/08/31 18:31:04 plunky Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xform_esp.c,v 1.40 2012/01/25 20:31:23 drochner Exp $");
 
 #include "opt_inet.h"
 #ifdef __FreeBSD__
@@ -297,7 +297,7 @@ esp_input(struct mbuf *m, const struct s
 	const struct enc_xform *espx;
 	struct tdb_ident *tdbi;
 	struct tdb_crypto *tc;
-	int plen, alen, hlen;
+	int plen, alen, hlen, error;
 	struct m_tag *mtag;
 	struct newesp *esp;
 
@@ -398,6 +398,16 @@ esp_input(struct mbuf *m, const struct s
 		return ENOBUFS;
 	}
 
+	error = m_makewritable(&m, 0, m->m_pkthdr.len, M_NOWAIT);
+	if (error) {
+		m_freem(m);
+		free(tc, M_XDATA);
+		crypto_freereq(crp);
+		DPRINTF(("esp_input: m_makewritable failed\n"));
+		ESP_STATINC(ESP_STAT_CRYPTO);
+		return error;
+	}
+
 	tc->tc_ptr = mtag;
 
 	if (esph) {
@@ -681,15 +691,7 @@ DPRINTF(("esp_input_cb: %x %x\n", lastth
 	m_adj(m, -(lastthree[1] + 2));
 
 	/* Restore the Next Protocol field */
-	m = m_copyback_cow(m, protoff, sizeof (u_int8_t), lastthree + 2,
-			   M_DONTWAIT);
-
-	if (m == NULL) {
-		ESP_STATINC(ESP_STAT_CRYPTO);
-		DPRINTF(("esp_input_cb: failed to allocate mbuf\n"));
-		error = ENOBUFS;
-		goto bad;
-	}
+	m_copyback(m, protoff, sizeof (u_int8_t), lastthree + 2);
 
 	IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff, mtag);
 

Index: src/sys/netipsec/xform_ipcomp.c
diff -u src/sys/netipsec/xform_ipcomp.c:1.28 src/sys/netipsec/xform_ipcomp.c:1.29
--- src/sys/netipsec/xform_ipcomp.c:1.28	Fri May  6 21:48:46 2011
+++ src/sys/netipsec/xform_ipcomp.c	Wed Jan 25 20:31:23 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: xform_ipcomp.c,v 1.28 2011/05/06 21:48:46 drochner Exp $	*/
+/*	$NetBSD: xform_ipcomp.c,v 1.29 2012/01/25 20:31:23 drochner Exp $	*/
 /*	$FreeBSD: src/sys/netipsec/xform_ipcomp.c,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $	*/
 /* $OpenBSD: ip_ipcomp.c,v 1.1 2001/07/05 12:08:52 jjbg Exp $ */
 
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xform_ipcomp.c,v 1.28 2011/05/06 21:48:46 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xform_ipcomp.c,v 1.29 2012/01/25 20:31:23 drochner Exp $");
 
 /* IP payload compression protocol (IPComp), see RFC 2393 */
 #include "opt_inet.h"
@@ -152,7 +152,7 @@ ipcomp_input(struct mbuf *m, const struc
 	struct tdb_crypto *tc;
 	struct cryptodesc *crdc;
 	struct cryptop *crp;
-	int hlen = IPCOMP_HLENGTH;
+	int error, hlen = IPCOMP_HLENGTH;
 
 	IPSEC_SPLASSERT_SOFTNET("ipcomp_input");
 
@@ -173,11 +173,22 @@ ipcomp_input(struct mbuf *m, const struc
 		IPCOMP_STATINC(IPCOMP_STAT_CRYPTO);
 		return ENOBUFS;
 	}
+
+	error = m_makewritable(&m, 0, m->m_pkthdr.len, M_NOWAIT);
+	if (error) {
+		DPRINTF(("ipcomp_input: m_makewritable failed\n"));
+		m_freem(m);
+		free(tc, M_XDATA);
+		crypto_freereq(crp);
+		IPCOMP_STATINC(IPCOMP_STAT_CRYPTO);
+		return error;
+	}
+
 	crdc = crp->crp_desc;
 
 	crdc->crd_skip = skip + hlen;
 	crdc->crd_len = m->m_pkthdr.len - (skip + hlen);
-	crdc->crd_inject = skip;
+	crdc->crd_inject = 0; /* unused */
 
 	tc->tc_ptr = 0;
 

Reply via email to