Skip to content

avoid panic when truncating payer_note in UTF-8 code point #3750

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

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 18 additions & 8 deletions fuzz/src/invoice_request_deser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,16 +85,26 @@ fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
let expanded_key = ExpandedKey::new([42; 32]);
let entropy_source = Randomness {};
let nonce = Nonce::from_entropy_source(&entropy_source);

let invoice_request_fields =
if let Ok(ver) = invoice_request.clone().verify_using_metadata(&expanded_key, secp_ctx) {
// Previously we had a panic where we'd truncate the payer note possibly cutting a
// Unicode character in two here, so try to fetch fields if we can validate.
ver.fields()
Copy link
Contributor

Choose a reason for hiding this comment

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

Somehow I expected this call not here directly, but a fuzzer that indirectly hits it via channel manager. But that would be a whole different fuzz test.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yea, hitting something that requires eg 3 specific TLVs to line up as a part of a much, much larger target is probably an infeasible level of complexity for a fuzzer.

} else {
InvoiceRequestFields {
payer_signing_pubkey: invoice_request.payer_signing_pubkey(),
quantity: invoice_request.quantity(),
payer_note_truncated: invoice_request
.payer_note()
.map(|s| UntrustedString(s.to_string())),
human_readable_name: None,
}
};

let payment_context = PaymentContext::Bolt12Offer(Bolt12OfferContext {
offer_id: OfferId([42; 32]),
invoice_request: InvoiceRequestFields {
payer_signing_pubkey: invoice_request.payer_signing_pubkey(),
quantity: invoice_request.quantity(),
payer_note_truncated: invoice_request
.payer_note()
.map(|s| UntrustedString(s.to_string())),
human_readable_name: None,
},
invoice_request: invoice_request_fields,
});
let payee_tlvs = UnauthenticatedReceiveTlvs {
payment_secret: PaymentSecret([42; 32]),
Expand Down
14 changes: 13 additions & 1 deletion lightning/src/offers/invoice_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -989,7 +989,14 @@ impl VerifiedInvoiceRequest {
InvoiceWithDerivedSigningPubkeyBuilder
);

pub(crate) fn fields(&self) -> InvoiceRequestFields {
/// Fetch the [`InvoiceRequestFields`] for this verified invoice.
///
/// These are fields which we expect to be useful when receiving a payment for this invoice
/// request, and include the returned [`InvoiceRequestFields`] in the
/// [`PaymentContext::Bolt12Offer`].
///
/// [`PaymentContext::Bolt12Offer`]: crate::blinded_path::payment::PaymentContext::Bolt12Offer
pub fn fields(&self) -> InvoiceRequestFields {
let InvoiceRequestContents {
payer_signing_pubkey,
inner: InvoiceRequestContentsWithoutPayerSigningPubkey { quantity, payer_note, .. },
Expand Down Expand Up @@ -1404,8 +1411,13 @@ pub struct InvoiceRequestFields {
}

/// The maximum number of characters included in [`InvoiceRequestFields::payer_note_truncated`].
#[cfg(not(fuzzing))]
pub const PAYER_NOTE_LIMIT: usize = 512;

/// The maximum number of characters included in [`InvoiceRequestFields::payer_note_truncated`].
#[cfg(fuzzing)]
pub const PAYER_NOTE_LIMIT: usize = 8;

impl Writeable for InvoiceRequestFields {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
write_tlv_fields!(writer, {
Expand Down
Loading