In ipo_tdb the flow contains a reference counted TDB cache. This
authorbluhm <bluhm@openbsd.org>
Tue, 7 Dec 2021 17:28:46 +0000 (17:28 +0000)
committerbluhm <bluhm@openbsd.org>
Tue, 7 Dec 2021 17:28:46 +0000 (17:28 +0000)
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@

sys/netinet/ip_ipsp.c
sys/netinet/ip_ipsp.h

index 4789c63..551a589 100644 (file)
@@ -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),
@@ -922,6 +922,19 @@ tdb_unlink_locked(struct tdb *tdbp)
 #endif /* IPSEC */
 }
 
+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)
 {
@@ -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);
index 06d069f..bb8b1a6 100644 (file)
@@ -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 *);