From 4e6bac6d3678183ea4dbee5fb381c4f19a66deda Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 14 Oct 2024 11:02:08 +1030 Subject: [PATCH] connectd: fix double-free crash on connection timeout. tmpctx may not get cleaned immediately, so the timeout (a child of the struct early_peer at this point) can still outlast the conn. Do the clearer thing, and explicitly free the timeout. Changelog-Fixed: connectd: crash on erroneous timeout. Signed-off-by: Rusty Russell --- connectd/peer_exchange_initmsg.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/connectd/peer_exchange_initmsg.c b/connectd/peer_exchange_initmsg.c index 99933e3c0..63b3ddb8d 100644 --- a/connectd/peer_exchange_initmsg.c +++ b/connectd/peer_exchange_initmsg.c @@ -31,6 +31,9 @@ struct early_peer { enum is_websocket is_websocket; bool incoming; + + /* Timeout in case it takes too long */ + struct oneshot *timeout; }; static bool contains_common_chain(struct bitcoin_blkid *chains) @@ -128,6 +131,9 @@ static struct io_plan *peer_init_received(struct io_conn *conn, * window where it was: combine the two. */ features = featurebits_or(tmpctx, take(features), globalfeatures); + /* No longer timing out! */ + tal_free(peer->timeout); + /* We can dispose of peer after next call. */ tal_steal(tmpctx, peer); @@ -206,9 +212,7 @@ struct io_plan *peer_exchange_initmsg(struct io_conn *conn, peer->cs = *cs; peer->incoming = incoming; peer->is_websocket = is_websocket; - - /* Attach timer to early peer, so it gets freed with it. */ - notleak(tal_steal(peer, timeout)); + peer->timeout = timeout; /* BOLT #1: *