summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2021-12-07 17:28:47 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2021-12-07 17:28:47 +0000
commit19c4a0cf2f74a4966b267dc81baff43f2d955106 (patch)
treef5acef8d1efb419b69ef292a0c3e467bda7aedda
parent93bc4f53f314f2dad29792dd38f92a975efa0210 (diff)
In ipo_tdb the flow contains a reference counted TDB cache. This
may prevent that tdb_free() is called. It is not a real leak as ipsecctl -F or termination of iked flush this cache when they remove the IPsec policy. Move the code from tdb_free() to tdb_delete(), then the kernel does the cleanup itself. OK mvs@ tobhe@
-rw-r--r--sys/netinet/ip_ipsp.c27
-rw-r--r--sys/netinet/ip_ipsp.h3
2 files changed, 19 insertions, 11 deletions
diff --git a/sys/netinet/ip_ipsp.c b/sys/netinet/ip_ipsp.c
index 4789c635473..551a589631e 100644
--- a/sys/netinet/ip_ipsp.c
+++ b/sys/netinet/ip_ipsp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ipsp.c,v 1.261 2021/12/03 19:04:49 tobhe Exp $ */
+/* $OpenBSD: ip_ipsp.c,v 1.262 2021/12/07 17:28:46 bluhm Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
@@ -923,6 +923,19 @@ tdb_unlink_locked(struct tdb *tdbp)
}
void
+tdb_cleanspd(struct tdb *tdbp)
+{
+ struct ipsec_policy *ipo;
+
+ while ((ipo = TAILQ_FIRST(&tdbp->tdb_policy_head)) != NULL) {
+ TAILQ_REMOVE(&tdbp->tdb_policy_head, ipo, ipo_tdb_next);
+ tdb_unref(ipo->ipo_tdb);
+ ipo->ipo_tdb = NULL;
+ ipo->ipo_last_searched = 0; /* Force a re-search. */
+ }
+}
+
+void
tdb_unbundle(struct tdb *tdbp)
{
if (tdbp->tdb_onext != NULL) {
@@ -1001,6 +1014,8 @@ tdb_dodelete(struct tdb *tdbp, int locked)
else
tdb_unlink(tdbp);
+ /* cleanup SPD references */
+ tdb_cleanspd(tdbp);
/* release tdb_onext/tdb_inext references */
tdb_unbundle(tdbp);
/* delete timeouts and release references */
@@ -1043,8 +1058,6 @@ tdb_alloc(u_int rdomain)
void
tdb_free(struct tdb *tdbp)
{
- struct ipsec_policy *ipo;
-
NET_ASSERT_LOCKED();
if (tdbp->tdb_xform) {
@@ -1057,13 +1070,7 @@ tdb_free(struct tdb *tdbp)
pfsync_delete_tdb(tdbp);
#endif
- /* Cleanup SPD references. */
- while ((ipo = TAILQ_FIRST(&tdbp->tdb_policy_head)) != NULL) {
- TAILQ_REMOVE(&tdbp->tdb_policy_head, ipo, ipo_tdb_next);
- tdb_unref(ipo->ipo_tdb);
- ipo->ipo_tdb = NULL;
- ipo->ipo_last_searched = 0; /* Force a re-search. */
- }
+ KASSERT(TAILQ_EMPTY(&tdbp->tdb_policy_head));
if (tdbp->tdb_ids) {
ipsp_ids_free(tdbp->tdb_ids);
diff --git a/sys/netinet/ip_ipsp.h b/sys/netinet/ip_ipsp.h
index 06d069fe949..bb8b1a6fb29 100644
--- a/sys/netinet/ip_ipsp.h
+++ b/sys/netinet/ip_ipsp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ipsp.h,v 1.227 2021/12/03 19:04:49 tobhe Exp $ */
+/* $OpenBSD: ip_ipsp.h,v 1.228 2021/12/07 17:28:46 bluhm Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
@@ -577,6 +577,7 @@ void tdb_free(struct tdb *);
int tdb_init(struct tdb *, u_int16_t, struct ipsecinit *);
void tdb_unlink(struct tdb *);
void tdb_unlink_locked(struct tdb *);
+void tdb_cleanspd(struct tdb *);
void tdb_unbundle(struct tdb *);
void tdb_deltimeouts(struct tdb *);
int tdb_walk(u_int, int (*)(struct tdb *, void *, int), void *);