svn commit: r318738 - head/sys/netipsec
Andrey V. Elsukov
ae at FreeBSD.org
Tue May 23 09:32:28 UTC 2017
Author: ae
Date: Tue May 23 09:32:26 2017
New Revision: 318738
URL: https://svnweb.freebsd.org/changeset/base/318738
Log:
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().
MFC after: 10 days
Modified:
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/netipsec/ipsec_output.c
==============================================================================
--- head/sys/netipsec/ipsec_output.c Tue May 23 09:30:42 2017 (r318737)
+++ head/sys/netipsec/ipsec_output.c Tue May 23 09:32:26 2017 (r318738)
@@ -273,10 +273,6 @@ ipsec4_perform_request(struct mbuf *m, s
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, s
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);
Modified: head/sys/netipsec/xform_ah.c
==============================================================================
--- head/sys/netipsec/xform_ah.c Tue May 23 09:30:42 2017 (r318737)
+++ head/sys/netipsec/xform_ah.c Tue May 23 09:32:26 2017 (r318738)
@@ -1049,6 +1049,8 @@ ah_output(struct mbuf *m, struct secpoli
bad:
if (m)
m_freem(m);
+ key_freesav(&sav);
+ key_freesp(&sp);
return (error);
}
Modified: head/sys/netipsec/xform_esp.c
==============================================================================
--- head/sys/netipsec/xform_esp.c Tue May 23 09:30:42 2017 (r318737)
+++ head/sys/netipsec/xform_esp.c Tue May 23 09:32:26 2017 (r318738)
@@ -861,6 +861,8 @@ esp_output(struct mbuf *m, struct secpol
bad:
if (m)
m_freem(m);
+ key_freesav(&sav);
+ key_freesp(&sp);
return (error);
}
/*
Modified: head/sys/netipsec/xform_ipcomp.c
==============================================================================
--- head/sys/netipsec/xform_ipcomp.c Tue May 23 09:30:42 2017 (r318737)
+++ head/sys/netipsec/xform_ipcomp.c Tue May 23 09:32:26 2017 (r318738)
@@ -510,6 +510,8 @@ ipcomp_output(struct mbuf *m, struct sec
bad:
if (m)
m_freem(m);
+ key_freesav(&sav);
+ key_freesp(&sp);
return (error);
}
More information about the svn-src-head
mailing list