Commit Graph

16965 Commits

Author SHA1 Message Date
Sangbida Chaudhuri
bf508387a3 hsmtool: change hsm_secret struct to have length awareness
This commit is updating hsmtool and exposesecrets to use the new pattern for storing the secret, which is the secret_data and secret_len, to support both 64 byte and 32 byte seeds.
2025-10-26 12:37:58 +10:30
Sangbida Chaudhuri
1b3e881d5a hsmd: find correct P2TR key for utxo
In the case where we receive a taproot utxo we want to be able to tell if it was derived using a BIP32 seed or a BIP86 seed. Considering we will only be supporting BI86 type wallet addresses for mnemonics we can check if the out secret is 64 bytes long and if it is we can use our BIP86 for the withdrawal.
2025-10-26 12:37:58 +10:30
Sangbida Chaudhuri
618d4f3377 walletrpc: add addresstype "bip86"; make newaddr+listaddresses use it
We should now be able to get BIP86 Taproot addresses through lightning-cli! For now we're just adding taproot addresses.
2025-10-26 12:37:58 +10:30
Sangbida Chaudhuri
d0d51479f5 wallet: scaffold BIP86 addrtype
Add the UTXO_P2TR_BIP86 in preparation to add BIP86 wallet functions such as newaddr, listaddr etc. We also add a new index in the database for BIP86 as this is using a completely different derivation path and hsm_secret.
2025-10-26 12:37:58 +10:30
Sangbida Chaudhuri
1665665271 lightningd: store base and derive pubkeys locally
RIP to this commit there's a good chance a lot of this code doesn't even make this into the final PR. Pour one out for the fallen lines of code.

This commit is doing the rest of the derivation. There was a significant overlap between the bip32_pubkey derivation and the bip86_pubkey derivation so that has been refactored in one place.
2025-10-26 12:37:58 +10:30
Sangbida Chaudhuri
63001745ca hsmd/libhsmd: add BIP86 base-key
BIP86 wants the full 64-byte BIP32 seed (from BIP39). This wires up BIP86
support so the HSM derives the hardened base m/86'/0'/0' inside the box,
and exposes helpers:
  • derive_bip86_base_key()   // m/86'/0'/0'
  • bip86_key(index)          // m/86'/0'/0'/0/index

Spoiler: derive_bip86_base_key() and bip86_key() now live in libhsmd.c as they will later be used to check the derived wallet address against hsmd's derivation, this is just to sanity check that we haven't had an accidental bit flip while we have generated this address.
2025-10-26 12:37:58 +10:30
Sangbida Chaudhuri
121fcfc92b hsmd: add BIP86 wire scaffolding (derive/check), no behavior yet
Here's some *foreshadowing* for what's to come. Here's what we're aiming for with our derivation flow:

Derivation split (hardened vs unhardened)
========================================

        ┌───────────────┐
        │      HSM      │  (secrets live here)
        │               │
        │  BIP39 → seed (64B)
        │       ↓
        │   m/86'/0'/0'           ← derive hardened base (private)
        │       ↓ (neuter)
        │   BIP86 base xpub       ← public-only + chain code
        │       ↓
        │  [send once over wire]
        └───────────────┘
                │
                ▼
        ┌───────────────────────┐
        │ lightningd / wallet   │
        │                       │
        │  local (unhardened) derivations:
        │    /0/i  → external
        │    /1/i  → change
        │                       │
        │  P2TR(BIP86) from pubkey_i
        │  (optionally: CHECK with HSM)
        └───────────────────────┘

We want to do part of the derivation inside hsmd and then send this base "pubkey" over the wire so our wallet can do the remaining derivation based on the address type and index. This lays the foundation for the base key wire message.
2025-10-26 12:37:58 +10:30
Sangbida Chaudhuri
fc981f4d30 hsmd/libhsmd: change hsmd_init to have secret_data and secret_len
hsmd: plumb length-aware secret into hsmd_init; keep 32B mirror

BIP86 (from BIP39) wants the full 64-byte BIP32 seed. This commit plumbs a variable-length (32/64B) secret into hsmd and uses the accessors from the previous commit. We keep the old 32B hsm_secret mirror and, for now, only use the first 32 bytes so legacy paths keep working.

Spoiler: HKDFs will keep using the 32B seed; only wallet address derivation
will switch to the full 64B in a follow-up.
2025-10-26 12:37:58 +10:30
Sangbida Chaudhuri
0192b82e94 common: refactor hsm_secret to {secret_data,len,type}
BIP86 derivation requires the full 64-byte seed that comes from the BIP39 mnemonic. The first 32 bytes goes towards to master seed material and the nest 32 bytes go towards the chaincode, so we need the entire 64 bytes for deterministic derivations. I've kept the old secret struct in for now for backwards compatibility and also added some accessors which will eventually die in this branch's git multiverse but that's a spoiler, they're on the ride for the next few commits at least to help us migrate to this length aware API throughout the rest of the code without making a lot of breaking changes.
2025-10-26 12:37:58 +10:30
Sangbida Chaudhuri
de9c6305a1 exposesecret: Add support for mnemonic-based HSM secrets
Update the exposesecret plugin to work with the new unified HSM secret
format that supports BIP39 mnemonics.

Changelog-Added - exposesecret now has a mnemonic field
2025-10-26 12:37:58 +10:30
Rusty Russell
5bac907505 common: tal_wally_discard()
In several places we were using tal_wally_end(tmpctx), which assumes
that libwally isn't using any of those allocations.

Make an explicit "tal_wally_discard" which asserts that there are no
outstanding libwally allocations.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-26 12:37:58 +10:30
Sangbida Chaudhuri
218dc2fe20 hsmd: use the new mnemonic-compatible hsm_secret routines.
Changelog-Changed: hsmd: New nodes will now be created with a BIP-39 12-word phrase as their root secret.
Changelog-Deprecated: config: `encrypted-hsm` to require a passphrase (use `hsm-passphrase`).
Changelog-Added: config: `hsm-passphrase` indicates we should use a manual passphrase with the hsm secret.
2025-10-26 12:37:58 +10:30
Sangbida Chaudhuri
e3fe739f64 hsmd: take the passphrase raw, not the derived secret.
In preparation for BIP-39, we need to hand the passphrase (if any) to HSMD.

So we extend the hsmd wire protocol to allow that.
2025-10-26 12:37:58 +10:30
Sangbida Chaudhuri
3da0f16f14 tools: update hsmtool to use the new hsm_secret API.
Changelog-Added: `hsmtool` now supports hsm_secret files using a 12-word mnemonic.
Changelog-Removed: hsmtool support for mnemonics in non-english languages removed.
2025-10-26 12:37:58 +10:30
Sangbida Chaudhuri
9977b72e8e common: add unified HSM secret handling module
This is a newer API to replace hsm_encryption.c and hsm_encryption.c, this tidies up the API to be used and also cleans things up to support our new formats. Our hsm_secret formats now include:
- Legacy 32-byte plain format
- Legacy 73-byte encrypted format
- New mnemonic format without passphrase (32 zero bytes + mnemonic)
- New mnemonic format with passphrase (32-byte hash + mnemonic)

This commit includes support to detect the format based on the file size and content structure. The hsm will store mnemonics in the hsm_secret file as:

`passphraseHash`mnemonic`
2025-10-26 12:37:58 +10:30
Rusty Russell
f40ff1d079 lightningd: fix compilation for older compilers.
gcc 9.3.0-10 (Ubunto Focal):

```
cc lightningd/offer.c
In file included from ccan/ccan/cast/cast.h:6,
                 from lightningd/offer.c:2:
lightningd/offer.c: In function 'json_createoffer':
ccan/ccan/cast/cast.h:115:13: error: dereferencing pointer to incomplete type 'struct json_escape'
  115 |  __typeof__(**(union { int z; __typeof__(expr) x; }){0}.x)
      |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ccan/ccan/build_assert/build_assert.h:38:24: note: in definition of macro 'BUILD_ASSERT_OR_ZERO'
   38 |  (sizeof(char [1 - 2*!(cond)]) - 1)
      |                        ^~~~
ccan/ccan/cast/cast.h:122:31: note: in expansion of macro 'cast_const_strip2'
  122 |  __builtin_types_compatible_p(cast_const_strip2(expr),  \
      |                               ^~~~~~~~~~~~~~~~~
ccan/ccan/cast/cast.h:59:35: note: in expansion of macro 'cast_const_compat2'
   59 |         (0 ? BUILD_ASSERT_OR_ZERO(cast_const_compat2((expr), type)) :   \
      |                                   ^~~~~~~~~~~~~~~~~~
lightningd/offer.c:105:12: note: in expansion of macro 'cast_const2'
  105 |            cast_const2(const struct json_escape **,
      |            ^~~~~~~~~~~
ccan/ccan/cast/cast.h:115:13: error: dereferencing pointer to incomplete type 'const struct json_escape'
  115 |  __typeof__(**(union { int z; __typeof__(expr) x; }){0}.x)
      |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ccan/ccan/build_assert/build_assert.h:38:24: note: in definition of macro 'BUILD_ASSERT_OR_ZERO'
   38 |  (sizeof(char [1 - 2*!(cond)]) - 1)
      |                        ^~~~
ccan/ccan/cast/cast.h:123:10: note: in expansion of macro 'cast_const_strip2'
  123 |          cast_const_strip2(type))
      |          ^~~~~~~~~~~~~~~~~
ccan/ccan/cast/cast.h:59:35: note: in expansion of macro 'cast_const_compat2'
   59 |         (0 ? BUILD_ASSERT_OR_ZERO(cast_const_compat2((expr), type)) :   \
      |                                   ^~~~~~~~~~~~~~~~~~
lightningd/offer.c:105:12: note: in expansion of macro 'cast_const2'
  105 |            cast_const2(const struct json_escape **,
      |            ^~~~~~~~~~~
make: *** [Makefile:320: lightningd/offer.o] Error 1
```

Reported-by: Shahana
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-24 16:23:37 +10:30
Rusty Russell
f801054e26 tests: use timemono not time_now() for duration measurement.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-24 11:30:17 +10:30
Rusty Russell
1df86130c3 lightningd: remove unused start_time field in bitcoind_getfilteredblock.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-24 11:30:17 +10:30
Rusty Russell
71f164a454 autogenerate-rpc-examples.py: add examples for listchainmoves and listchannelmoves.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-24 11:30:17 +10:30
Rusty Russell
4bc357f0a6 bitcoin: remove unused scriptpubkey_opreturn_padded.
I noticed, because it pulled in randomness routines.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-24 11:30:17 +10:30
Rusty Russell
9987b6f93a lightningd: try harder to ensure uniqueness in --dev-save-plugin-io names.
Incorporate a time: this covers the restart case as well.  And make it time_mono(),
which doesn't get overridden when we override normal wall time.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-24 11:30:17 +10:30
Rusty Russell
75616f6b77 common: add new_htable() macro to allocate, initialize and setup memleak coverage for any typed hash table.
You can now simply add per-tal-object helpers for memleak, but our older pattern required
calling memleak functions explicitly during memleak handling.  Hash tables in particular need
to be dynamically allocated (we override the allocators using htable_set_allocator and assume
this), so it makes sense to have a helper macro that does all three.

This eliminates a huge amount of code.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-24 11:30:17 +10:30
Rusty Russell
06f18b1d1d memleak: make notleak() work even before memleak is initalized.
It now simply renames tal names, so it's harmless to do even if we're
not going to do memleak detection.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-24 11:30:17 +10:30
Rusty Russell
478a0d5792 wallet: make sure to watch all txids in transactions table.
We watch if they are to do with a channel, or have outputs going to us, but otherwise
we didn't, so we never updated the blockheight in the db.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Fixed: JSON-RPC: `listtransactions` now correctly updates `blockheight` for txs created by `sendpsbt` which have no change outputs.
2025-10-24 11:30:17 +10:30
Rusty Russell
2591ac486d pytest: add test that we notice height change of sendpsbt with no change.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-24 11:30:17 +10:30
Rusty Russell
5a530e6c46 lightningd: fix crash in channel_control.
I got a NULL deref on `infcopy->remote_funding = *inflight->funding->splice_remote_funding`
at once point in testing, so this should prevent that from happening,
yet still allow us to catch it in CI if it happens again.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-24 11:30:17 +10:30
Rusty Russell
89eaf8341b lightningd: cancel watching original funding when we switch to the new one via splice.
This happens if the channel is *not* announcable yet.  Then we hit the assertion
in funding_depth_cb that the txid is the same as the current funding.txid.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-EXPERIMENTAL: fixed crash when we splice a channel which hasn't been announced yet.
2025-10-24 11:30:17 +10:30
Rusty Russell
d4a541c58a pytest: test for splicing while channel is not announced yet.
```
DEBUG   lightningd: Got depth change 2->3 for e9e31956f77c3844ee2e6e4607dbfebdee95a9aa549668a7a429b8246a6a29de
**BROKEN** lightningd: FATAL SIGNAL 6 (version v25.09-20-g003ba4a)
**BROKEN** lightningd: backtrace: common/daemon.c:41 (send_backtrace) 0x619bef20e274
**BROKEN** lightningd: backtrace: common/daemon.c:78 (crashdump) 0x619bef20e408
**BROKEN** lightningd: backtrace: ./signal/../sysdeps/unix/sysv/linux/x86_64/libc_sigaction.c:0 ((null)) 0x7a1ccf24532f
**BROKEN** lightningd: backtrace: ./nptl/pthread_kill.c:44 (__pthread_kill_implementation) 0x7a1ccf29eb2c
**BROKEN** lightningd: backtrace: ./nptl/pthread_kill.c:78 (__pthread_kill_internal) 0x7a1ccf29eb2c
**BROKEN** lightningd: backtrace: ./nptl/pthread_kill.c:89 (__GI___pthread_kill) 0x7a1ccf29eb2c
**BROKEN** lightningd: backtrace: ../sysdeps/posix/raise.c:26 (__GI_raise) 0x7a1ccf24527d
**BROKEN** lightningd: backtrace: ./stdlib/abort.c:79 (__GI_abort) 0x7a1ccf2288fe
**BROKEN** lightningd: backtrace: ./assert/assert.c:96 (__assert_fail_base) 0x7a1ccf22881a
**BROKEN** lightningd: backtrace: ./assert/assert.c:105 (__assert_fail) 0x7a1ccf23b516
**BROKEN** lightningd: backtrace: lightningd/peer_control.c:2202 (funding_depth_cb) 0x619bef1ac497
**BROKEN** lightningd: backtrace: lightningd/watch.c:223 (txw_fire) 0x619bef1cfcbf
**BROKEN** lightningd: backtrace: lightningd/watch.c:292 (watch_topology_changed) 0x619bef1cffa4
**BROKEN** lightningd: backtrace: lightningd/chaintopology.c:829 (updates_complete) 0x619bef144a8c
**BROKEN** lightningd: backtrace: lightningd/chaintopology.c:1047 (get_new_block) 0x619bef14561e
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-24 11:30:17 +10:30
Peter Neuroth
29999efbaa add .clangd to gitignore
I use .clangd to configure compiler flags for the lsp (language server)
I use in nvim.

Changelog-None

Signed-off-by: Peter Neuroth <pet.v.ne@gmail.com>
2025-10-24 11:29:51 +10:30
Rusty Russell
bc4bb2b0ef libplugin: use jsonrpc_io logic for sync requests too.
It's a little overkill, but it's clear.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-24 11:28:57 +10:30
Rusty Russell
4958cd3289 lightningd: use jsonrpc_io for plugin JSON commands.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-24 11:28:57 +10:30
Rusty Russell
203dbaab20 lightningd: wean pligun_log_handle/plugin_notify_handle/plugin_response_handle off plugin->buffer.
Hand buffer in as a parameter to reduce churn in the next patch.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-24 11:28:57 +10:30
Rusty Russell
eb0d042693 common: add brace hack for jsonrpc_async_parse.
This is a trick from bcli: we ask bitcoind for the block, and it hands
us a 2MB hex blob (which we read in multiple parts).  Our parser wades
through it all, but a quick search for '}' makes it much faster.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-24 11:28:57 +10:30
Rusty Russell
c88c8eacd0 lightningd: use jsonrpc_io for reading JSON commands.
This is more efficient if we have lots of incoming commands, too.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-24 11:28:57 +10:30
Rusty Russell
cbdffe0708 lightningd: wean parse_request off referencing jcon->buffer.
Hand it in as a parameter to reduce churn in the next patch.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-24 11:28:57 +10:30
Rusty Russell
cbfd65f600 libplugin: use jsonrpc_io for stdin from lightningd.
This is also more efficient if there are many commands at once.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-24 11:28:57 +10:30
Rusty Russell
cb2cf034f3 libplugin: wean ld_command_handle off referncing plugin->buffer.
Hand it in as a parameter to reduce churn in next patch.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-24 11:28:57 +10:30
Rusty Russell
690f95ff1f libplugin: use jsonrpc_io for reading replies to our async commands.
This will also be more efficient than doing memmove every time.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-24 11:28:57 +10:30
Rusty Russell
68f6a1a1dc common/jsonrpc_io: helper routines for reading JSON from sockets.
The efficient way to do this is to use membuf, which handles the buffer
control (only using memmove when necessary).  We have multiple places
where we opencoded this, some of which did not use membuf at all.

So now we create common infrastructure.  I tried making it a single
function but the various users are quite different, so instead I opted
for a toolbox approach.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-24 11:28:57 +10:30
Rusty Russell
dd7cc71b38 plugins: remove unused json_buffer / json_toks members from libplugin-pay.
They were never referenced, and saving the toks is questionable since their
lifetime is not guaranteed to live beyond this call (at least the buffer was
duplicated, but that also assumed it was at the start of the object).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-24 11:28:57 +10:30
Rusty Russell
e5318ee62c common: add json_dup_contents() to duplicate toks and buffer.
We do this in several places, might as well make it common code.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-24 11:28:57 +10:30
Rusty Russell
7c9e016fb7 common: export helper membuf_tal_realloc.
We have to call it membuf_tal_resize() because the other on is
a ccan/json_out static function!

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-24 11:28:57 +10:30
Rusty Russell
e28fed7504 plugins: make fatal errors neater.
Without this they get run together on stderr.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-24 11:28:57 +10:30
Rusty Russell
8f6d3d87bb plugins: fix %*.s typo.
And add a check for new uses creeping in, since it got cut & paste
everywhere.

This means "this is a valid string, but truncate it to this many characters"
vs "%.*s" which means "only read this many characters of string":

```
['lightningd-3 2025-10-23T02:31:40.890Z **BROKEN** plugin-funder: Plugin marked as important, shutting down lightningd!']
--------------------------- Captured stderr teardown ---------------------------
    #0 0x557da58ad1dc in printf_common(void*, char const*, __va_list_tag*) asan_interceptors.cpp.o
    #1 0x557da5aff814 in json_out_addv /home/runner/work/lightning/lightning/ccan/ccan/json_out/json_out.c:239:11
    #2 0x557da59740ce in plugin_logv /home/runner/work/lightning/lightning/plugins/libplugin.c:1777:2
    #3 0x557da5969b6f in plugin_log /home/runner/work/lightning/lightning/plugins/libplugin.c:1934:2
    #4 0x557da595c4f6 in datastore_del_success /home/runner/work/lightning/lightning/plugins/funder.c:161:2
    #5 0x557da598b837 in handle_rpc_reply /home/runner/work/lightning/lightning/plugins/libplugin.c:1072:10
    #6 0x557da598a4b0 in rpc_conn_read_response /home/runner/work/lightning/lightning/plugins/libplugin.c:1361:3
    #7 0x557da5adbea5 in next_plan /home/runner/work/lightning/lightning/ccan/ccan/io/io.c:60:9
    #8 0x557da5ae06ff in do_plan /home/runner/work/lightning/lightning/ccan/ccan/io/io.c:422:8
    #9 0x557da5adfb58 in io_ready /home/runner/work/lightning/lightning/ccan/ccan/io/io.c:439:10
    #10 0x557da5aec2ce in io_loop /home/runner/work/lightning/lightning/ccan/ccan/io/poll.c:455:5
    #11 0x557da59757ac in plugin_main /home/runner/work/lightning/lightning/plugins/libplugin.c:2409:3
    #12 0x557da594fe23 in main /home/runner/work/lightning/lightning/plugins/funder.c:1723:2
    #13 0x7f6572229d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #14 0x7f6572229e3f in __libc_start_main csu/../csu/libc-start.c:392:3
    #15 0x557da588b584 in _start (/home/runner/work/lightning/lightning/plugins/funder+0x10d584) (BuildId: 71ba63ab577fc6fa60573d3e8555f6db7d5c584d)

0x624000009d28 is located 0 bytes to the right of 7208-byte region [0x624000008100,0x624000009d28)
allocated by thread T0 here:
    #0 0x557da590e7f6 in __interceptor_realloc (/home/runner/work/lightning/lightning/plugins/funder+0x1907f6) (BuildId: 71ba63ab577fc6fa60573d3e8555f6db7d5c584d)
    #1 0x557da5b2149b in tal_resize_ /home/runner/work/lightning/lightning/ccan/ccan/tal/tal.c:755:13
    #2 0x557da59f2032 in membuf_tal_resize /home/runner/work/lightning/lightning/common/utils.c:203:2
    #3 0x557da5b03934 in membuf_prepare_space_ /home/runner/work/lightning/lightning/ccan/ccan/membuf/membuf.c:45:12
    #4 0x557da59d4289 in jsonrpc_io_read_ /home/runner/work/lightning/lightning/common/jsonrpc_io.c:127:2
    #5 0x557da598a635 in rpc_conn_read_response /home/runner/work/lightning/lightning/plugins/libplugin.c:1366:9
    #6 0x557da5adbea5 in next_plan /home/runner/work/lightning/lightning/ccan/ccan/io/io.c:60:9
    #7 0x557da5ae06ff in do_plan /home/runner/work/lightning/lightning/ccan/ccan/io/io.c:422:8
    #8 0x557da5adfb58 in io_ready /home/runner/work/lightning/lightning/ccan/ccan/io/io.c:439:10
    #9 0x557da5aec2ce in io_loop /home/runner/work/lightning/lightning/ccan/ccan/io/poll.c:455:5
    #10 0x557da59757ac in plugin_main /home/runner/work/lightning/lightning/plugins/libplugin.c:2409:3
    #11 0x557da594fe23 in main /home/runner/work/lightning/lightning/plugins/funder.c:1723:2
    #12 0x7f6572229d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16

SUMMARY: AddressSanitizer: heap-buffer-overflow asan_interceptors.cpp.o in printf_common(void*, char const*, __va_list_tag*)
Shadow bytes around the buggy address:
  0x0c487fff9350: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c487fff9360: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c487fff9370: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c487fff9380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c487fff9390: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c487fff93a0: 00 00 00 00 00[fa]fa fa fa fa fa fa fa fa fa fa
  0x0c487fff93b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c487fff93c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c487fff93d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c487fff93e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c487fff93f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==26122==ABORTING
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-24 11:28:57 +10:30
Rusty Russell
365add06f7 fuzz/fuzz-hsm_encryption: don't run as unit test under valgrind.
Thanks to Argon hashing, this is intolerably slow under valgrind, and
times out under CI.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-23 06:44:04 +10:30
Rusty Russell
2adfdfd0d9 Makefile: run fuzzing corpora as normal unit tests in non-fuzzing mode.
This means we can make sure the compile and run in normal builds.

Side note: various tests call common_setup(), which means we called it
twice in unit testing mode, so we conditionalize those.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-23 06:44:04 +10:30
Rusty Russell
a6ea428294 fuzz: fix build undr FreeBSD.
They have a `struct splice` already:

```
2025-10-22T08:33:39.2432203Z tests/fuzz/fuzz-wire-splice.c:6:8: error: redefinition of 'splice'
2025-10-22T08:33:39.2434453Z     6 | struct splice {
2025-10-22T08:33:39.2435520Z       |        ^
2025-10-22T08:33:39.2436087Z /usr/include/sys/socket.h:683:8: note: previous definition is here
2025-10-22T08:33:39.2436709Z   683 | struct splice {
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-23 06:44:04 +10:30
Rusty Russell
d8ee3a5eb9 tests/fuzz: fix include order.
Nobody ever runs `make check-includes` with fuzzing enabled.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-23 06:44:04 +10:30
Rusty Russell
c821e41085 common: assert that they don't call setup_tmpctx() twice.
Otherwise, leaks will occur.  And fix up dualopend and devtool/route,
which do this!

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-23 06:44:04 +10:30
Rusty Russell
61ecc4086d common: remove take() leak if new_initial_channel() fails.
This happens in the fuzzer corpora, but that doesn't check for take()
leaks.  Our unit tests do:

```
fuzz-initial_channel: outstanding taken(): 0x626c3b3affc8
make: *** [Makefile:823: unittest/tests/fuzz/fuzz-initial_channel] Error 1
```

This doesn't matter in real life, since we exit the subdaemon if this
fails, but it's still a bug.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-23 06:44:04 +10:30