mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-06 17:18:32 +00:00
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
This commit is contained in:
parent
ec95c622ff
commit
3aee70991d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=318738
|
@ -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);
|
||||
|
|
|
@ -1049,6 +1049,8 @@ ah_output(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav,
|
|||
bad:
|
||||
if (m)
|
||||
m_freem(m);
|
||||
key_freesav(&sav);
|
||||
key_freesp(&sp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
|
@ -861,6 +861,8 @@ esp_output(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav,
|
|||
bad:
|
||||
if (m)
|
||||
m_freem(m);
|
||||
key_freesav(&sav);
|
||||
key_freesp(&sp);
|
||||
return (error);
|
||||
}
|
||||
/*
|
||||
|
|
|
@ -510,6 +510,8 @@ ipcomp_output(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav,
|
|||
bad:
|
||||
if (m)
|
||||
m_freem(m);
|
||||
key_freesav(&sav);
|
||||
key_freesp(&sp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue