summaryrefslogtreecommitdiffstats
path: root/sys/netipsec
diff options
context:
space:
mode:
authorae <ae@FreeBSD.org>2015-09-30 08:16:33 +0000
committerae <ae@FreeBSD.org>2015-09-30 08:16:33 +0000
commitc3f8d46dc4768cc2260aab00c30a9820ff61ac6e (patch)
tree4ad4f6510e88f8efc5d959645df14e0a121c347a /sys/netipsec
parenta6fac84fcf38d1a17650296ab2f345d62e855db1 (diff)
downloadFreeBSD-src-c3f8d46dc4768cc2260aab00c30a9820ff61ac6e.zip
FreeBSD-src-c3f8d46dc4768cc2260aab00c30a9820ff61ac6e.tar.gz
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
Diffstat (limited to 'sys/netipsec')
-rw-r--r--sys/netipsec/ipsec_output.c16
-rw-r--r--sys/netipsec/xform_ah.c1
-rw-r--r--sys/netipsec/xform_esp.c1
-rw-r--r--sys/netipsec/xform_ipcomp.c1
4 files changed, 5 insertions, 14 deletions
diff --git a/sys/netipsec/ipsec_output.c b/sys/netipsec/ipsec_output.c
index a6611a7..f5cdf5a 100644
--- a/sys/netipsec/ipsec_output.c
+++ b/sys/netipsec/ipsec_output.c
@@ -166,10 +166,6 @@ ipsec_process_done(struct mbuf *m, struct ipsecrequest *isr)
* 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, struct ipsecrequest *isr)
#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, struct ipsecrequest *isr)
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
diff --git a/sys/netipsec/xform_ah.c b/sys/netipsec/xform_ah.c
index 350a735..0d39eeb 100644
--- a/sys/netipsec/xform_ah.c
+++ b/sys/netipsec/xform_ah.c
@@ -1068,6 +1068,7 @@ ah_output(struct mbuf *m, struct ipsecrequest *isr, struct mbuf **mp,
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;
diff --git a/sys/netipsec/xform_esp.c b/sys/netipsec/xform_esp.c
index a48c038..9f645c0 100644
--- a/sys/netipsec/xform_esp.c
+++ b/sys/netipsec/xform_esp.c
@@ -874,6 +874,7 @@ esp_output(struct mbuf *m, struct ipsecrequest *isr, struct mbuf **mp,
}
/* Callback parameters */
+ key_addref(isr->sp);
tc->tc_isr = isr;
KEY_ADDREFSA(sav);
tc->tc_sav = sav;
diff --git a/sys/netipsec/xform_ipcomp.c b/sys/netipsec/xform_ipcomp.c
index ef460cd..122fc72 100644
--- a/sys/netipsec/xform_ipcomp.c
+++ b/sys/netipsec/xform_ipcomp.c
@@ -449,6 +449,7 @@ ipcomp_output(struct mbuf *m, struct ipsecrequest *isr, struct mbuf **mp,
goto bad;
}
+ key_addref(isr->sp);
tc->tc_isr = isr;
KEY_ADDREFSA(sav);
tc->tc_sav = sav;
OpenPOWER on IntegriCloud