Skip to content

manager: return an error for truncated adaptor signature lists - #194

Merged
bennyhodl merged 1 commit into
masterfrom
fix/adaptor-signature-bounds
Sep 14, 2026
Merged

bennyhodl merged 1 commit into
masterfrom
fix/adaptor-signature-bounds

Conversation

@bennyhodl

Copy link
Copy Markdown
Owner

Summary

Fixes the Bitcoin Red Team finding FND-006, "Truncated adaptor-signature lists in counterparty messages panic the DLC message-handler task". The enum descriptor, the numeric trie (serial and parallel), and the CET settlement paths indexed the wire-supplied adaptor signature vector without a length check. An AcceptDlc or SignDlc with a short list panicked inside on_dlc_message; both transports awaited the handler inline and nothing restarted the listener, so one malformed accept from any peer silenced DLC message processing until the process restarted. The auditor's re-run reproduced the panic at enum_descriptor.rs:129 on current master.

Changes

  • EnumDescriptor::verify_adaptor_info, both verify_helper variants in ddk-trie, get_signed_cet in contract_updater, and the settled channel close in channel_updater use bounds-checked access and return an invalid argument or invalid state error naming the missing index and the received count.
  • The parallel trie helper no longer unwraps on an empty trie, and carries the same too_many_arguments allowance as the serial one so clippy --all-features passes for the crate.
  • The nostr and lightning transports run each inbound message in its own tokio::spawn task and await the join handle. A handler panic is logged with the counterparty and the loop continues, so a parser bug can no longer take the listener down. The nostr reply path logs event build and send failures instead of unwrapping them.

Testing

  • New truncated_counterparty_adaptor_signatures_are_rejected in the stateless suite: an accept with an empty adaptor signature list now yields InvalidAccept mentioning the missing signature, where it panicked before.
  • Stateless suite (33), ddk-trie with and without parallel (42), and the regtest enum_single_oracle_test and single_oracle_numerical_test pass. cargo check --all-features --tests and cargo +1.89.0 clippy -- -D warnings (the CI configuration) are clean.
  • clippy --all-features still reports four pre-existing lints in ddk/src/oracle/nostr.rs and p2p_derivatives.rs that are untouched here and not part of the CI gate.

Enum, numeric trie, and settlement paths indexed the wire-supplied
adaptor signature vector without a length check, so an AcceptDlc or
SignDlc with a short list panicked inside the message handler. Both
transports awaited the handler inline, and nothing restarted the
listener, so one malformed accept from any peer silenced DLC message
processing until the process restarted.

Every indexed access is now bounds checked and returns an invalid
argument error, and the stateless suite covers an empty accept list.
The nostr and lightning transports run each inbound message in its own
task and log a panic instead of dying with it, and the nostr reply path
logs send failures instead of unwrapping them.
@bennyhodl
bennyhodl force-pushed the fix/adaptor-signature-bounds branch from a37d45a to 236c9c7 Compare September 14, 2026 20:41
@bennyhodl
bennyhodl merged commit 3f6a7d9 into master Sep 14, 2026
138 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant