summaryrefslogtreecommitdiffstats
path: root/sys/netipsec/ipsec_output.c
diff options
context:
space:
mode:
authorae <ae@FreeBSD.org>2017-06-02 09:54:41 +0000
committerae <ae@FreeBSD.org>2017-06-02 09:54:41 +0000
commitd8ee8035f662ebc549539a73c8d4d567ab467aa7 (patch)
tree6388d9aae6af772bd810026f3ab68299ce112eec /sys/netipsec/ipsec_output.c
parentc00d83f65d3c23a8ef65a816388d8ad63136ba7f (diff)
downloadFreeBSD-src-d8ee8035f662ebc549539a73c8d4d567ab467aa7.zip
FreeBSD-src-d8ee8035f662ebc549539a73c8d4d567ab467aa7.tar.gz
MFC r318734:
Fix possible double releasing for SA reference. There are two possible ways how crypto callback are called: directly from caller and deffered from crypto thread. For inbound packets the direct call chain is the following: IPSEC_INPUT() method -> ipsec_common_input() -> xform_input() -> -> crypto_dispatch() -> crypto_invoke() -> crypto_done() -> -> xform_input_cb() -> ipsec[46]_common_input_cb() -> netisr_queue(). The SA reference is held while crypto processing is not finished. The error handling code wrongly expected that crypto callback always called from the crypto thread context, and it did SA reference releasing in xform_input_cb(). But when the crypto callback called directly, in case of error (e.g. data authentification failed) the error handling in ipsec_common_input() also did SA reference releasing. To fix this, remove error handling from ipsec_common_input() and do it in xform_input() before crypto_dispatch(). PR: 219356 MFC r318738: Fix possible double releasing for SA and SP references. There are two possible ways how crypto callback are called: directly from caller and deffered from crypto thread. For outbound packets the direct call chain is the following: IPSEC_OUTPUT() method -> ipsec[46]_common_output() -> -> ipsec[46]_perform_request() -> xform_output() -> -> crypto_dispatch() -> crypto_invoke() -> crypto_done() -> -> xform_output_cb() -> ipsec_process_done() -> ip[6]_output(). The SA and SP references are held while crypto processing is not finished. The error handling code wrongly expected that crypto callback always called from the crypto thread context, and it did references releasing in xform_output_cb(). But when the crypto callback called directly, in case of error the error handling code in ipsec[46]_perform_request() also did references releasing. To fix this, remove error handling from ipsec[46]_perform_request() and do it in xform_output() before crypto_dispatch(). Approved by: re (kib)
Diffstat (limited to 'sys/netipsec/ipsec_output.c')
-rw-r--r--sys/netipsec/ipsec_output.c8
1 files changed, 0 insertions, 8 deletions
diff --git a/sys/netipsec/ipsec_output.c b/sys/netipsec/ipsec_output.c
index 392008e..80b6ab83 100644
--- a/sys/netipsec/ipsec_output.c
+++ b/sys/netipsec/ipsec_output.c
@@ -273,10 +273,6 @@ ipsec4_perform_request(struct mbuf *m, struct secpolicy *sp, u_int idx)
goto bad;
}
error = (*sav->tdb_xform->xf_output)(m, sp, sav, idx, i, off);
- if (error != 0) {
- key_freesav(&sav);
- key_freesp(&sp);
- }
return (error);
bad:
IPSECSTAT_INC(ips_out_inval);
@@ -581,10 +577,6 @@ ipsec6_perform_request(struct mbuf *m, struct secpolicy *sp, u_int idx)
goto bad;
}
error = (*sav->tdb_xform->xf_output)(m, sp, sav, idx, i, off);
- if (error != 0) {
- key_freesav(&sav);
- key_freesp(&sp);
- }
return (error);
bad:
IPSEC6STAT_INC(ips_out_inval);
OpenPOWER on IntegriCloud