diff options
author | Luiz Otavio O Souza <luiz@netgate.com> | 2015-09-15 15:27:49 -0500 |
---|---|---|
committer | Luiz Otavio O Souza <luiz@netgate.com> | 2015-10-20 12:02:15 -0500 |
commit | 5696701b2e19f4a198340ada5b4ba73fa5c6c9f9 (patch) | |
tree | 93cc9ec4253fb4f506b392065fab2214e23b2e51 /sys/netinet6/ip6_ipsec.c | |
parent | c10a06fdafd86efa4c2c4c262870f0d5276dd625 (diff) | |
download | FreeBSD-src-5696701b2e19f4a198340ada5b4ba73fa5c6c9f9.zip FreeBSD-src-5696701b2e19f4a198340ada5b4ba73fa5c6c9f9.tar.gz |
MFC r282046:
Fix possible use after free due to security policy deletion.
When we are passing mbuf to IPSec processing via ipsec[46]_process_packet(),
we hold one reference to security policy and release it just after return
from this function. But IPSec processing can be deffered and when we release
reference to security policy after ipsec[46]_process_packet(), user can
delete this security policy from SPDB. And when IPSec processing will be
done, xform's callback function will do access to already freed memory.
To fix this move KEY_FREESP() into callback function. Now IPSec code will
release reference to SP after processing will be finished.
Differential Revision: https://reviews.freebsd.org/D2324
No objections from: #network
Sponsored by: Yandex LLC
TAG: IPSEC-HEAD
Issue: #4841
Diffstat (limited to 'sys/netinet6/ip6_ipsec.c')
-rw-r--r-- | sys/netinet6/ip6_ipsec.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/sys/netinet6/ip6_ipsec.c b/sys/netinet6/ip6_ipsec.c index 66459cf..ac49275 100644 --- a/sys/netinet6/ip6_ipsec.c +++ b/sys/netinet6/ip6_ipsec.c @@ -212,7 +212,9 @@ ip6_ipsec_output(struct mbuf **m, struct inpcb *inp, int *error) /* NB: callee frees mbuf */ *error = ipsec6_process_packet(*m, sp->req); - + /* Release SP if an error occured */ + if (*error != 0) + KEY_FREESP(&sp); if (*error == EJUSTRETURN) { /* * We had a SP with a level of 'use' and no SA. We @@ -252,9 +254,7 @@ done: KEY_FREESP(&sp); return 0; reinjected: - if (sp != NULL) - KEY_FREESP(&sp); - return -1; + return (-1); bad: if (sp != NULL) KEY_FREESP(&sp); |