Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 30 Sep 2015 08:16:34 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r288418 - in head/sys: netinet netinet6 netipsec
Message-ID:  <201509300816.t8U8GYP1075923@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Wed Sep 30 08:16:33 2015
New Revision: 288418
URL: https://svnweb.freebsd.org/changeset/base/288418

Log:
  Take extra reference to security policy before calling crypto_dispatch().
  
  Currently we perform crypto requests for IPSEC synchronous for most of
  crypto providers (software, aesni) and only VIA padlock calls crypto
  callback asynchronous. In synchronous mode it is possible, that security
  policy will be removed during the processing crypto request. And crypto
  callback will release the last reference to SP. Then upon return into
  ipsec[46]_process_packet() IPSECREQUEST_UNLOCK() will be called to already
  freed request. To prevent this we will take extra reference to SP.
  
  PR:		201876
  Sponsored by:	Yandex LLC

Modified:
  head/sys/netinet/ip_ipsec.c
  head/sys/netinet6/ip6_ipsec.c
  head/sys/netipsec/ipsec_output.c
  head/sys/netipsec/xform_ah.c
  head/sys/netipsec/xform_esp.c
  head/sys/netipsec/xform_ipcomp.c

Modified: head/sys/netinet/ip_ipsec.c
==============================================================================
--- head/sys/netinet/ip_ipsec.c	Wed Sep 30 05:46:56 2015	(r288417)
+++ head/sys/netinet/ip_ipsec.c	Wed Sep 30 08:16:33 2015	(r288418)
@@ -199,9 +199,7 @@ ip_ipsec_output(struct mbuf **m, struct 
 
 		/* NB: callee frees mbuf */
 		*error = ipsec4_process_packet(*m, sp->req);
-		/* Release SP if an error occured */
-		if (*error != 0)
-			KEY_FREESP(&sp);
+		KEY_FREESP(&sp);
 		if (*error == EJUSTRETURN) {
 			/*
 			 * We had a SP with a level of 'use' and no SA. We

Modified: head/sys/netinet6/ip6_ipsec.c
==============================================================================
--- head/sys/netinet6/ip6_ipsec.c	Wed Sep 30 05:46:56 2015	(r288417)
+++ head/sys/netinet6/ip6_ipsec.c	Wed Sep 30 08:16:33 2015	(r288418)
@@ -200,9 +200,7 @@ ip6_ipsec_output(struct mbuf **m, struct
 
 		/* NB: callee frees mbuf */
 		*error = ipsec6_process_packet(*m, sp->req);
-		/* Release SP if an error occured */
-		if (*error != 0)
-			KEY_FREESP(&sp);
+		KEY_FREESP(&sp);
 		if (*error == EJUSTRETURN) {
 			/*
 			 * We had a SP with a level of 'use' and no SA. We

Modified: head/sys/netipsec/ipsec_output.c
==============================================================================
--- head/sys/netipsec/ipsec_output.c	Wed Sep 30 05:46:56 2015	(r288417)
+++ head/sys/netipsec/ipsec_output.c	Wed Sep 30 08:16:33 2015	(r288418)
@@ -166,10 +166,6 @@ ipsec_process_done(struct mbuf *m, struc
 	 * If this is a problem we'll need to introduce a queue
 	 * to set the packet on so we can unwind the stack before
 	 * doing further processing.
-	 *
-	 * If ipsec[46]_process_packet() will successfully queue
-	 * the request, we need to take additional reference to SP,
-	 * because xform callback will release reference.
 	 */
 	if (isr->next) {
 		/* XXX-BZ currently only support same AF bundles. */
@@ -177,11 +173,7 @@ ipsec_process_done(struct mbuf *m, struc
 #ifdef INET
 		case AF_INET:
 			IPSECSTAT_INC(ips_out_bundlesa);
-			key_addref(isr->sp);
-			error = ipsec4_process_packet(m, isr->next);
-			if (error != 0)
-				KEY_FREESP(&isr->sp);
-			return (error);
+			return (ipsec4_process_packet(m, isr->next));
 			/* NOTREACHED */
 #endif
 #ifdef notyet
@@ -189,11 +181,7 @@ ipsec_process_done(struct mbuf *m, struc
 		case AF_INET6:
 			/* XXX */
 			IPSEC6STAT_INC(ips_out_bundlesa);
-			key_addref(isr->sp);
-			error = ipsec6_process_packet(m, isr->next);
-			if (error != 0)
-				KEY_FREESP(&isr->sp);
-			return (error);
+			return (ipsec6_process_packet(m, isr->next));
 			/* NOTREACHED */
 #endif /* INET6 */
 #endif

Modified: head/sys/netipsec/xform_ah.c
==============================================================================
--- head/sys/netipsec/xform_ah.c	Wed Sep 30 05:46:56 2015	(r288417)
+++ head/sys/netipsec/xform_ah.c	Wed Sep 30 08:16:33 2015	(r288418)
@@ -1068,6 +1068,7 @@ ah_output(struct mbuf *m, struct ipsecre
 	crp->crp_opaque = (caddr_t) tc;
 
 	/* These are passed as-is to the callback. */
+	key_addref(isr->sp);
 	tc->tc_isr = isr;
 	KEY_ADDREFSA(sav);
 	tc->tc_sav = sav;

Modified: head/sys/netipsec/xform_esp.c
==============================================================================
--- head/sys/netipsec/xform_esp.c	Wed Sep 30 05:46:56 2015	(r288417)
+++ head/sys/netipsec/xform_esp.c	Wed Sep 30 08:16:33 2015	(r288418)
@@ -874,6 +874,7 @@ esp_output(struct mbuf *m, struct ipsecr
 	}
 
 	/* Callback parameters */
+	key_addref(isr->sp);
 	tc->tc_isr = isr;
 	KEY_ADDREFSA(sav);
 	tc->tc_sav = sav;

Modified: head/sys/netipsec/xform_ipcomp.c
==============================================================================
--- head/sys/netipsec/xform_ipcomp.c	Wed Sep 30 05:46:56 2015	(r288417)
+++ head/sys/netipsec/xform_ipcomp.c	Wed Sep 30 08:16:33 2015	(r288418)
@@ -449,6 +449,7 @@ ipcomp_output(struct mbuf *m, struct ips
 		goto bad;
 	}
 
+	key_addref(isr->sp);
 	tc->tc_isr = isr;
 	KEY_ADDREFSA(sav);
 	tc->tc_sav = sav;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201509300816.t8U8GYP1075923>