Module Name:    src
Committed By:   ozaki-r
Date:           Wed Jul 19 10:26:09 UTC 2017

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

Log Message:
Hold a reference to an SP during opencrypto processing

An SP has a list of isr (ipsecrequest) that represents a sequence
of IPsec encryption/authentication processing. One isr corresponds
to one opencrypto processing. The lifetime of an isr follows its SP.

We pass an isr to a callback function of opencrypto to continue
to a next encryption/authentication processing. However nobody
guaranteed that the isr wasn't freed, i.e., its SP wasn't destroyed.

In order to avoid such unexpected destruction of isr, hold a reference
to its SP during opencrypto processing.


To generate a diff of this commit:
cvs rdiff -u -r1.64 -r1.65 src/sys/netipsec/xform_ah.c \
    src/sys/netipsec/xform_esp.c
cvs rdiff -u -r1.45 -r1.46 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.64 src/sys/netipsec/xform_ah.c:1.65
--- src/sys/netipsec/xform_ah.c:1.64	Wed Jul 19 09:38:57 2017
+++ src/sys/netipsec/xform_ah.c	Wed Jul 19 10:26:09 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: xform_ah.c,v 1.64 2017/07/19 09:38:57 ozaki-r Exp $	*/
+/*	$NetBSD: xform_ah.c,v 1.65 2017/07/19 10:26:09 ozaki-r 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.64 2017/07/19 09:38:57 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xform_ah.c,v 1.65 2017/07/19 10:26:09 ozaki-r Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_inet.h"
@@ -1144,6 +1144,7 @@ ah_output(
 
 	/* These are passed as-is to the callback. */
 	tc->tc_isr = isr;
+	KEY_SP_REF(isr->sp);
 	tc->tc_spi = sav->spi;
 	tc->tc_dst = sav->sah->saidx.dst;
 	tc->tc_proto = sav->sah->saidx.proto;
@@ -1184,6 +1185,14 @@ ah_output_cb(struct cryptop *crp)
 
 	isr = tc->tc_isr;
 	sav = tc->tc_sav;
+	if (__predict_false(isr->sp->state == IPSEC_SPSTATE_DEAD)) {
+		AH_STATINC(AH_STAT_NOTDB);
+		IPSECLOG(LOG_DEBUG,
+		    "SP is being destroyed while in crypto (id=%u)\n",
+		    isr->sp->id);
+		error = ENOENT;
+		goto bad;
+	}
 	if (__predict_false(!SADB_SASTATE_USABLE_P(sav))) {
 		KEY_FREESAV(&sav);
 		sav = KEY_LOOKUP_SA(&tc->tc_dst, tc->tc_proto, tc->tc_spi, 0, 0);
@@ -1241,12 +1250,14 @@ ah_output_cb(struct cryptop *crp)
 	/* NB: m is reclaimed by ipsec_process_done. */
 	err = ipsec_process_done(m, isr, sav);
 	KEY_FREESAV(&sav);
+	KEY_FREESP(&isr->sp);
 	mutex_exit(softnet_lock);
 	splx(s);
 	return err;
 bad:
 	if (sav)
 		KEY_FREESAV(&sav);
+	KEY_FREESP(&isr->sp);
 	mutex_exit(softnet_lock);
 	splx(s);
 	if (m)
Index: src/sys/netipsec/xform_esp.c
diff -u src/sys/netipsec/xform_esp.c:1.64 src/sys/netipsec/xform_esp.c:1.65
--- src/sys/netipsec/xform_esp.c:1.64	Wed Jul 19 09:38:57 2017
+++ src/sys/netipsec/xform_esp.c	Wed Jul 19 10:26:09 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: xform_esp.c,v 1.64 2017/07/19 09:38:57 ozaki-r Exp $	*/
+/*	$NetBSD: xform_esp.c,v 1.65 2017/07/19 10:26:09 ozaki-r 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.64 2017/07/19 09:38:57 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xform_esp.c,v 1.65 2017/07/19 10:26:09 ozaki-r Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_inet.h"
@@ -895,6 +895,7 @@ esp_output(
 
 	/* Callback parameters */
 	tc->tc_isr = isr;
+	KEY_SP_REF(isr->sp);
 	tc->tc_spi = sav->spi;
 	tc->tc_dst = saidx->dst;
 	tc->tc_proto = saidx->proto;
@@ -958,6 +959,14 @@ esp_output_cb(struct cryptop *crp)
 
 	isr = tc->tc_isr;
 	sav = tc->tc_sav;
+	if (__predict_false(isr->sp->state == IPSEC_SPSTATE_DEAD)) {
+		ESP_STATINC(ESP_STAT_NOTDB);
+		IPSECLOG(LOG_DEBUG,
+		    "SP is being destroyed while in crypto (id=%u)\n",
+		    isr->sp->id);
+		error = ENOENT;
+		goto bad;
+	}
 	if (__predict_false(!SADB_SASTATE_USABLE_P(sav))) {
 		KEY_FREESAV(&sav);
 		sav = KEY_LOOKUP_SA(&tc->tc_dst, tc->tc_proto, tc->tc_spi, 0, 0);
@@ -1020,12 +1029,14 @@ esp_output_cb(struct cryptop *crp)
 	/* NB: m is reclaimed by ipsec_process_done. */
 	err = ipsec_process_done(m, isr, sav);
 	KEY_FREESAV(&sav);
+	KEY_FREESP(&isr->sp);
 	mutex_exit(softnet_lock);
 	splx(s);
 	return err;
 bad:
 	if (sav)
 		KEY_FREESAV(&sav);
+	KEY_FREESP(&isr->sp);
 	mutex_exit(softnet_lock);
 	splx(s);
 	if (m)

Index: src/sys/netipsec/xform_ipcomp.c
diff -u src/sys/netipsec/xform_ipcomp.c:1.45 src/sys/netipsec/xform_ipcomp.c:1.46
--- src/sys/netipsec/xform_ipcomp.c:1.45	Wed Jul 19 09:38:57 2017
+++ src/sys/netipsec/xform_ipcomp.c	Wed Jul 19 10:26:09 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: xform_ipcomp.c,v 1.45 2017/07/19 09:38:57 ozaki-r Exp $	*/
+/*	$NetBSD: xform_ipcomp.c,v 1.46 2017/07/19 10:26:09 ozaki-r 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.45 2017/07/19 09:38:57 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xform_ipcomp.c,v 1.46 2017/07/19 10:26:09 ozaki-r Exp $");
 
 /* IP payload compression protocol (IPComp), see RFC 2393 */
 #if defined(_KERNEL_OPT)
@@ -480,6 +480,7 @@ ipcomp_output(
 	}
 
 	tc->tc_isr = isr;
+	KEY_SP_REF(isr->sp);
 	tc->tc_spi = sav->spi;
 	tc->tc_dst = sav->sah->saidx.dst;
 	tc->tc_proto = sav->sah->saidx.proto;
@@ -530,6 +531,14 @@ ipcomp_output_cb(struct cryptop *crp)
 
 	isr = tc->tc_isr;
 	sav = tc->tc_sav;
+	if (__predict_false(isr->sp->state == IPSEC_SPSTATE_DEAD)) {
+		IPCOMP_STATINC(IPCOMP_STAT_NOTDB);
+		IPSECLOG(LOG_DEBUG,
+		    "SP is being destroyed while in crypto (id=%u)\n",
+		    isr->sp->id);
+		error = ENOENT;
+		goto bad;
+	}
 	if (__predict_false(!SADB_SASTATE_USABLE_P(sav))) {
 		KEY_FREESAV(&sav);
 		sav = KEY_LOOKUP_SA(&tc->tc_dst, tc->tc_proto, tc->tc_spi, 0, 0);
@@ -638,12 +647,14 @@ ipcomp_output_cb(struct cryptop *crp)
 	/* NB: m is reclaimed by ipsec_process_done. */
 	error = ipsec_process_done(m, isr, sav);
 	KEY_FREESAV(&sav);
+	KEY_FREESP(&isr->sp);
 	mutex_exit(softnet_lock);
 	splx(s);
 	return error;
 bad:
 	if (sav)
 		KEY_FREESAV(&sav);
+	KEY_FREESP(&isr->sp);
 	mutex_exit(softnet_lock);
 	splx(s);
 	if (m)

Reply via email to