From 207552514f5db2140d56ddd1e64714bd493743d1 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 14 Aug 2026 12:18:41 +0930 Subject: [PATCH 1/2] bcli: require bitcoind >= 23.0, and remove unneeded bitcoind version gate for getblockfrompeer. Minimum version for bitcoind in CI is 25.0, but elements is older. Bump hard reject version to 23.0 (which elements will still pass, just). Signed-off-by: Rusty Russell --- plugins/bcli.c | 64 +++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 35 deletions(-) diff --git a/plugins/bcli.c b/plugins/bcli.c index 1b3af2b13388..7ce164ab7cc6 100644 --- a/plugins/bcli.c +++ b/plugins/bcli.c @@ -19,9 +19,6 @@ /* Hex-encoded SHA256 block hash length (32 bytes = 64 hex chars) */ #define BLOCK_HASH_HEX_LEN 64 -/* Bitcoin Core version 23.0.0 introduced getblockfrompeer RPC */ -#define BITCOIND_VERSION_GETBLOCKFROMPEER 230000 - struct bitcoind { /* eg. "bitcoin-cli" */ char *cli; @@ -402,42 +399,39 @@ static struct command_result *getrawblockbyheight(struct command *cmd, block_hash, bitcoind->retry_timeout), NULL); } - /* Try fetching from peers if bitcoind >= 23.0.0 */ - if (bitcoind->version >= BITCOIND_VERSION_GETBLOCKFROMPEER) { - if (!peers) - peers = get_fullnode_peers(cmd, cmd); - - if (tal_count(peers) > 0) { - int peer = peers[tal_count(peers) - 1]; - tal_resize(&peers, tal_count(peers) - 1); - - res = run_bitcoin_cli(cmd, cmd->plugin, - "getblockfrompeer", - block_hash, - tal_fmt(tmpctx, "%i", peer), - NULL); - - if (res->exitstatus != 0) { - /* We still continue with the execution if we cannot fetch the - * block from peer */ - plugin_log(cmd->plugin, LOG_DBG, - "failed to fetch block %s from peer %i, skip.", - block_hash, peer); - } else { - plugin_log(cmd->plugin, LOG_DBG, - "try to fetch block %s from peer %i.", - block_hash, peer); - } - } + if (!peers) + peers = get_fullnode_peers(cmd, cmd); + + if (tal_count(peers) > 0) { + int peer = peers[tal_count(peers) - 1]; + tal_resize(&peers, tal_count(peers) - 1); + + res = run_bitcoin_cli(cmd, cmd->plugin, + "getblockfrompeer", + block_hash, + tal_fmt(tmpctx, "%i", peer), + NULL); - if (tal_count(peers) == 0) { + if (res->exitstatus != 0) { + /* We still continue with the execution if we cannot fetch the + * block from peer */ plugin_log(cmd->plugin, LOG_DBG, - "asked all known peers about block %s, retry", - block_hash); - peers = tal_free(peers); + "failed to fetch block %s from peer %i, skip.", + block_hash, peer); + } else { + plugin_log(cmd->plugin, LOG_DBG, + "try to fetch block %s from peer %i.", + block_hash, peer); } } + if (tal_count(peers) == 0) { + plugin_log(cmd->plugin, LOG_DBG, + "asked all known peers about block %s, retry", + block_hash); + peers = tal_free(peers); + } + sleep(1); } } @@ -743,7 +737,7 @@ static void parse_getnetworkinfo_result(struct plugin *p, const char *buf) { const jsmntok_t *result; bool tx_relay; - u32 min_version = 220000; + u32 min_version = 230000; const char *err; result = json_parse_simple(NULL, buf, strlen(buf)); From 215712569e43aa4c1fbc2dd2c1c9faabc586f03a Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 14 Aug 2026 12:21:25 +0930 Subject: [PATCH 2/2] openchannel: remove dead code. This triggered a false positive use-after-free issue from Red Team. In fact, the children of new_node_copy are deliberately owned by clone already (see f2468963488026b7a9fa2c08a60f391195745ae8) so this cleanup attempt (which was wrong, since size_t is never "> -1") was unnecessary anyway. Signed-off-by: Rusty Russell --- plugins/spender/openchannel.c | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/plugins/spender/openchannel.c b/plugins/spender/openchannel.c index c0698f3cb7f1..849fa6630681 100644 --- a/plugins/spender/openchannel.c +++ b/plugins/spender/openchannel.c @@ -215,24 +215,9 @@ static bool update_parent_psbt(const tal_t *ctx, goto fail; } - /* We want to preserve the memory bits associated with - * the inputs/outputs we just copied over when we free - * the copy, so remove ones the *added* from the copy. - * We go from the back since this will modify the indexes */ - for (size_t i = tal_count(changes->added_ins) - 1; - i > -1; - i--) { - psbt_rm_input(new_node_copy, - changes->added_ins[i].idx); - } - for (size_t i = tal_count(changes->added_outs) - 1; - i > -1; - i--) { - psbt_rm_output(new_node_copy, - changes->added_outs[i].idx); - } - tal_free(changes); + /* All those new_node_copy children are owned by clone + * already, so shallow copying them above was fine. */ tal_free(new_node_copy); tal_free(*parent_psbt);