Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More bolt11 fixes #6776

Closed

Conversation

rustyrussell
Copy link
Contributor

Fixed from @morehouse with minor tweaks from me.

@rustyrussell rustyrussell added this to the v23.11 milestone Oct 15, 2023
@vincenzopalazzo vincenzopalazzo self-requested a review October 15, 2023 12:01
Copy link
Collaborator

@vincenzopalazzo vincenzopalazzo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a comment for 88ce922

This is in some sense reverting what we did in 5f6642a

The assert is in here because the string MUST be always valid because all the RPC should convert the string to a canonical one.

The bug is in to_canonical_invstr

https://github.com/ElementsProject/lightning/blob/master/common/bolt11.h#L128C1-L132C74

common/bolt11.c Show resolved Hide resolved
@morehouse
Copy link
Contributor

Rather than merging a second fuzz target for bolt11 decoding, I think we should extend @dergoegge's #6750. That target has the benefit of generating valid bech32 100% of the time, and I have some local changes that allow it to find all of these bugs.

I can submit a couple PRs doing this in the next few days.

@rustyrussell
Copy link
Contributor Author

I will apply this now, happy for later refinement.

@rustyrussell
Copy link
Contributor Author

Rebased with fix for my misunderstanding in decode_n (thanks, valgrind!).

Really, bolt11 parsing is nasty :(

@rustyrussell
Copy link
Contributor Author

Had to turn the bech32 csum reduction into a runtime flag, since it broke the bech32 fuzzing!

[ Turned bech32 csum disable into a runtime flag --RR ]
An error is preferable to an assertion failure. Before this fix, the
entire node crashes if there's an extra "lightning:" prefix:

  $ lightning-cli pay "lightning:lightning:"

Node log:
  pay: common/bolt11.c:718: bolt11_decode_nosig: Assertion `!has_lightning_prefix(str)' failed.
  pay: FATAL SIGNAL 6
  ...
  INFO    plugin-pay: Killing plugin: exited during normal operation
  **BROKEN** plugin-pay: Plugin marked as important, shutting down lightningd

[ I simply removed the check, so it fails on a bad bech32 string as expected --RR ]
Invalid recovery IDs cause
secp256k1_ecdsa_recoverable_signature_parse_compact to abort, which
crashes the entire node. We should return an error instead.

Detected by libFuzzer:
[libsecp256k1] illegal argument: recid >= 0 && recid <= 3
Otherwise, if pull_all fails, we attempt to create a script from NULL,
causing a UBSan report:

bitcoin/script.c:29:28: runtime error: null pointer passed as argument 2, which is declared to never be null
If both databits and *data_len are 0, pull_uint returns unitialized
stack memory in *val.

Detected by valgrind and UBSan.

valgrind:
==225078== Use of uninitialised value of size 8
==225078==    __sanitizer_cov_trace_cmp8
==225078==    decode_c (bolt11.c:294)
==225078==    bolt11_decode_nosig (bolt11.c:881)
==225078==    bolt11_decode (bolt11.c:945)

UBSan:
common/bolt11.c:79:29: runtime error: shift exponent 64 is too large for 64-bit type 'uint64_t'
Rather than crashing the entire node on invalid pubkey, we should return
an error.

Detected by libFuzzer:
==250024== ERROR: libFuzzer: deadly signal

[ Changed so that `n` really does check that it's valid --RR ]

    #7 abort
    #8 bolt11_decode common/bolt11.c:1002:4
Copy link
Collaborator

@vincenzopalazzo vincenzopalazzo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 71a3cc1

Copy link
Contributor

@morehouse morehouse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will apply this now, happy for later refinement.

Fine with me, if we get this PR working properly.

I'll also try to send an alternative PR today in case we want to skip the intermediate step.

@@ -126,6 +126,8 @@ void run(const uint8_t *data, size_t size)
const u5 *sigdata;
bool have_n = false;
char *fail;

dev_bech32_nocsum = true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the wrong fuzz test to enable the flag. We should do this during init in fuzz-bolt11-decode.c instead.

@morehouse
Copy link
Contributor

I'll also try to send an alternative PR today in case we want to skip the intermediate step.

Alternative PR: #6789

@rustyrussell
Copy link
Contributor Author

Preferred version merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants