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)