Prevent deref-after-free when tdb_timeout() fires on invalid new tdb.
authortobhe <tobhe@openbsd.org>
Wed, 11 Oct 2023 22:13:16 +0000 (22:13 +0000)
committertobhe <tobhe@openbsd.org>
Wed, 11 Oct 2023 22:13:16 +0000 (22:13 +0000)
commit804d0a749c66d5dc8ae510207a392a249d98c2c7
treefe1fadc97875443dc413f39cfd30739417839622
parent4be5cdd0cde0cfc8f1dc131ba911ee5d6e72b500
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@
sys/net/pfkeyv2.c
sys/net/pfkeyv2_convert.c
sys/netinet/ip_ipsp.c
sys/netinet/ip_ipsp.h