diff options
author | Tobias Heider <tobhe@cvs.openbsd.org> | 2023-10-11 22:13:17 +0000 |
---|---|---|
committer | Tobias Heider <tobhe@cvs.openbsd.org> | 2023-10-11 22:13:17 +0000 |
commit | 387254b22bfeaf92797e898eb2c0e884f4356a56 (patch) | |
tree | 7556a10d2d18eb5764666fc7b335f757d8373849 /sys/netinet/ip_ipsp.h | |
parent | 947b6cb8d8a4ef6d89f386d4b38b21ef867b2904 (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.h | 3 |
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 *, ...)); |