rgb-cln/connectd
Rusty Russell 82ed71d621 connectd: don't crash if connect() fails immediately.
Took me a while (stressing under valgrind) to reproduce this,
then longer to figure out how it happened.

Turns out io_new_conn() can fail if the init function fails.
In our case, this can happen if connect() immediately returns
an error (inside io_connect).  But we've already set the finish
function, which (if this was the last address), will free connect,
making the assignment `connect->conn = ...` write to a freed address.

Either way, if it fails, try_connect_one_addr() has taken care to
update connect->conn, or free connect, and the caller should not do it.

Here's the valgrind trace:
```
==384981== Invalid write of size 8
==384981==    at 0x11127C: try_connect_one_addr (connectd.c:880)
==384981==    by 0x112BA1: destroy_io_conn (connectd.c:708)
==384981==    by 0x141459: destroy_conn (poll.c:244)
==384981==    by 0x14147F: destroy_conn_close_fd (poll.c:250)
==384981==    by 0x149EB9: notify (tal.c:240)
==384981==    by 0x149F8B: del_tree (tal.c:402)
==384981==    by 0x14A51A: tal_free (tal.c:486)
==384981==    by 0x140036: io_close (io.c:450)
==384981==    by 0x1400B3: do_plan (io.c:401)
==384981==    by 0x140134: io_ready (io.c:423)
==384981==    by 0x141A57: io_loop (poll.c:445)
==384981==    by 0x112CB0: main (connectd.c:1703)
==384981==  Address 0x4d67020 is 64 bytes inside a block of size 160 free'd
==384981==    at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==384981==    by 0x14A020: del_tree (tal.c:421)
==384981==    by 0x14A51A: tal_free (tal.c:486)
==384981==    by 0x1110C5: try_connect_one_addr (connectd.c:806)
==384981==    by 0x112BA1: destroy_io_conn (connectd.c:708)
==384981==    by 0x141459: destroy_conn (poll.c:244)
==384981==    by 0x14147F: destroy_conn_close_fd (poll.c:250)
==384981==    by 0x149EB9: notify (tal.c:240)
==384981==    by 0x149F8B: del_tree (tal.c:402)
==384981==    by 0x14A51A: tal_free (tal.c:486)
==384981==    by 0x140036: io_close (io.c:450)
==384981==    by 0x1405DC: io_connect_ (io.c:345)
==384981==  Block was alloc'd at
==384981==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==384981==    by 0x149CF1: allocate (tal.c:250)
==384981==    by 0x14A3C6: tal_alloc_ (tal.c:428)
==384981==    by 0x1114F2: try_connect_peer (connectd.c:1526)
==384981==    by 0x111717: connect_to_peer (connectd.c:1558)
==384981==    by 0x1124F5: recv_req (connectd.c:1627)
==384981==    by 0x1188B2: handle_read (daemon_conn.c:31)
==384981==    by 0x13FBCB: next_plan (io.c:59)
==384981==    by 0x140076: do_plan (io.c:407)
==384981==    by 0x140113: io_ready (io.c:417)
==384981==    by 0x141A57: io_loop (poll.c:445)
==384981==    by 0x112CB0: main (connectd.c:1703)
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Fixed: Occasional crash in connectd due to use-after-free
Fixes: #4343
2021-02-01 21:01:06 +01:00
..
test bitcoin/pubkey: add pubkey32 primitive for xonly pubkey types. 2020-12-09 16:40:13 +10:30
Makefile dualfund: rearrange things so that the wire-dependent calls are separate 2020-10-20 14:27:19 +10:30
connectd.c connectd: don't crash if connect() fails immediately. 2021-02-01 21:01:06 +01:00
connectd.h connectd/connectd: Display an error hint for V3 tor onions when connect fail. 2020-07-01 11:21:58 +02:00
connectd_gossipd_wire.csv connectd: convert to new wire generation style. 2020-08-25 12:53:13 +09:30
connectd_gossipd_wiregen.c tools/generate-wire.py: include digits in #ifndef idempotent header. 2021-01-13 14:45:36 +01:00
connectd_gossipd_wiregen.h tools/generate-wire.py: include digits in #ifndef idempotent header. 2021-01-13 14:45:36 +01:00
connectd_wire.csv connectd: implement connection timeout (60 seconds). 2020-09-11 21:27:45 +09:30
connectd_wiregen.c tools/generate-wire.py: include digits in #ifndef idempotent header. 2021-01-13 14:45:36 +01:00
connectd_wiregen.h tools/generate-wire.py: include digits in #ifndef idempotent header. 2021-01-13 14:45:36 +01:00
handshake.c common: generalize ecdh function. 2020-04-04 16:08:49 +10:30
handshake.h common: generalize ecdh function. 2020-04-04 16:08:49 +10:30
netaddress.c connectd: add annotation and fix up formatting on connectd/netaddress.c 2020-12-07 14:26:52 +01:00
netaddress.h gossipd: move files into connectd. 2018-07-25 02:13:52 +00:00
peer_exchange_initmsg.c connectd: convert to new wire generation style. 2020-08-25 12:53:13 +09:30
peer_exchange_initmsg.h cleanup: make 'u8 *features' and 'struct feature_set *fset' more explicit. 2020-04-03 13:13:21 +10:30
tor.c connect/tor: Set errno, if connection failed we want to reflect this. 2020-07-01 11:21:58 +02:00
tor.h connectd: rename 'struct reaching' to 'struct connecting'. 2018-09-28 04:14:28 +00:00
tor_autoservice.c Add the missing space between "if" and "(" 2020-01-06 12:57:59 +01:00
tor_autoservice.h Init commit to be able to create a tor static service on the fly. 2019-12-03 23:35:18 +01:00