From 3ce90f807209d00864b0291262e4f7c346e4f7ca Mon Sep 17 00:00:00 2001 From: dovgopoly Date: Wed, 10 Dec 2025 18:00:13 +0200 Subject: [PATCH 1/2] lightningd: fix segfault when parse_filter fails We need to initialize ->json_cmd *before* complaining about malformed filters. ``` lightningd: FATAL SIGNAL 11 (version v25.12-21-g3851187-modded) 0x1042d2023 ??? send_backtrace+0x4f:0 0x1042d20cb ??? crashdump+0x43:0 0x19fe3b743 ??? ???:0 0x104180173 command_log lightningd/jsonrpc.c:1406 0x10420d8f7 command_fail_badparam common/json_command.c:25 0x104181a07 parse_request lightningd/jsonrpc.c:1075 0x104181a07 read_json lightningd/jsonrpc.c:1216 0x10424c65b next_plan ccan/ccan/io/io.c:60 0x10424c65b do_plan ccan/ccan/io/io.c:422 0x10424c587 io_ready ccan/ccan/io/io.c:439 0x10424dd9b io_loop ccan/ccan/io/poll.c:470 0x10417ede7 io_loop_with_timers lightningd/io_loop_with_timers.c:22 0x104183a33 main lightningd/lightningd.c:1492 ``` Co-authored-by: Rusty Russell Changelog-Fixed: JSON-RPC: malformed filters no longer crash lightningd. --- lightningd/jsonrpc.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lightningd/jsonrpc.c b/lightningd/jsonrpc.c index 7240fdc9c1b4..dbd7fd84b73d 100644 --- a/lightningd/jsonrpc.c +++ b/lightningd/jsonrpc.c @@ -1070,6 +1070,13 @@ parse_request(struct json_connection *jcon, "Expected string for method"); } + c->json_cmd = find_cmd(jcon->ld->jsonrpc, buffer, method); + if (!c->json_cmd) { + return command_fail( + c, JSONRPC2_METHOD_NOT_FOUND, "Unknown command '%.*s'", + method->end - method->start, buffer + method->start); + } + if (filter) { struct command_result *ret; ret = parse_filter(c, "filter", buffer, filter); @@ -1081,12 +1088,6 @@ parse_request(struct json_connection *jcon, * actually just logging the id */ log_io(jcon->log, LOG_IO_IN, NULL, c->id, NULL, 0); - c->json_cmd = find_cmd(jcon->ld->jsonrpc, buffer, method); - if (!c->json_cmd) { - return command_fail( - c, JSONRPC2_METHOD_NOT_FOUND, "Unknown command '%.*s'", - method->end - method->start, buffer + method->start); - } if (!command_deprecated_in_ok(c, NULL, c->json_cmd->depr_start, c->json_cmd->depr_end)) { From 2ade7048a1bca04e7b3a7028f19a88aea628a54e Mon Sep 17 00:00:00 2001 From: dovgopoly Date: Fri, 12 Dec 2025 13:33:40 +0200 Subject: [PATCH 2/2] tests: added *non-developer mode* test for invalid filtering --- tests/test_misc.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/test_misc.py b/tests/test_misc.py index e17d4935fc9c..e159b1c48bb4 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -5042,3 +5042,27 @@ def test_zero_locktime_blocks(node_factory, bitcoind): l2.rpc.close(l3.info['id']) bitcoind.generate_block(1, wait_for_mempool=2) sync_blockheight(bitcoind, [l1, l2, l3]) + + +def test_filter_with_invalid_json(node_factory): + # This crashes only in *non-developer mode*: it uses command_log() + # in that case (since it doesn't print the invalid token in + # non-dev mode), and that expects cmd->json_cmd to be populated!` + l1 = node_factory.get_node(start=False) + l1.daemon.early_opts = [] + l1.daemon.opts = {k: v for k, v in l1.daemon.opts.items() if not k.startswith('dev')} + l1.start() + + out = subprocess.run(['cli/lightning-cli', + '--network={}'.format(TEST_NETWORK), + '--lightning-dir={}' + .format(l1.daemon.lightning_dir), + '-l', '1', + '-k', + 'wait', + 'subsystem=invoices', + 'indexname=created', + 'nextvalue=0'], + stdout=subprocess.PIPE) + assert 'filter: Expected object: invalid token' in out.stdout.decode('utf-8') + assert out.returncode == 1