summaryrefslogtreecommitdiff
path: root/sys/netinet/ip_ipsp.h
diff options
context:
space:
mode:
authorTobias Heider <tobhe@cvs.openbsd.org>2023-10-11 22:13:17 +0000
committerTobias Heider <tobhe@cvs.openbsd.org>2023-10-11 22:13:17 +0000
commit387254b22bfeaf92797e898eb2c0e884f4356a56 (patch)
tree7556a10d2d18eb5764666fc7b335f757d8373849 /sys/netinet/ip_ipsp.h
parent947b6cb8d8a4ef6d89f386d4b38b21ef867b2904 (diff)
Prevent deref-after-free when tdb_timeout() fires on invalid new tdb.
When receiving a pfkeyv2 SADB_ADD message, a newly created tdb can fail in tdb_init(), which causes the tdb to not get added to the global tdb list and an immediate dereference. If a lifetime timeout triggers on this tdb, it will unconditionally try to remove it from the list and in the process deref once more than allowed, causing a one bit corruption in the already freed up slot in the tdb pool. We resolve this issue by moving timeout_add() after tdb_init() just before puttdb(). This means tdbs failing initialization get discarded immediately as they only hold a single reference. Valid tdbs get their timeouts activated just before we add them to the tdb list, meaning the timeout can safely assume they are linked. Feedback from mvs@ and millert@ ok mvs@ mbuhl@
Diffstat (limited to 'sys/netinet/ip_ipsp.h')
-rw-r--r--sys/netinet/ip_ipsp.h3
1 files changed, 2 insertions, 1 deletions
diff --git a/sys/netinet/ip_ipsp.h b/sys/netinet/ip_ipsp.h
index c24174d0f90..d5100a55eb8 100644
--- a/sys/netinet/ip_ipsp.h
+++ b/sys/netinet/ip_ipsp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ipsp.h,v 1.242 2023/08/07 01:44:51 dlg Exp $ */
+/* $OpenBSD: ip_ipsp.h,v 1.243 2023/10/11 22:13:16 tobhe Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
@@ -613,6 +613,7 @@ void tdb_unlink(struct tdb *);
void tdb_unlink_locked(struct tdb *);
void tdb_cleanspd(struct tdb *);
void tdb_unbundle(struct tdb *);
+void tdb_addtimeouts(struct tdb *);
void tdb_deltimeouts(struct tdb *);
int tdb_walk(u_int, int (*)(struct tdb *, void *, int), void *);
void tdb_printit(void *, int, int (*)(const char *, ...));