Skip to content

Commit c6ee09b

Browse files
Use LengthLimitedReadable for all read-to-end Readables
When deserializing these structs, they will consume the reader until it is out of bytes. Therefore, it's safer if they are only provided with readers that limit how much of the byte stream will be read. Most of the relevant structs were updated in the previous commit when we transitioned impl_writeable_msg to use LengthReadable, here we finish the job.
1 parent ebe10ad commit c6ee09b

File tree

9 files changed

+116
-73
lines changed

9 files changed

+116
-73
lines changed

lightning-liquidity/src/lsps0/ser.rs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ use crate::lsps2::msgs::{
1818
};
1919
use crate::prelude::{HashMap, String};
2020

21-
use lightning::ln::msgs::LightningError;
21+
use lightning::io;
22+
use lightning::ln::msgs::{DecodeError, LightningError};
2223
use lightning::ln::wire;
23-
use lightning::util::ser::WithoutLength;
24+
use lightning::util::ser::{Readable, WithoutLength};
2425

2526
use bitcoin::secp256k1::PublicKey;
2627

@@ -168,9 +169,21 @@ impl lightning::util::ser::Writeable for RawLSPSMessage {
168169
}
169170
}
170171

171-
impl lightning::util::ser::Readable for RawLSPSMessage {
172-
fn read<R: lightning::io::Read>(r: &mut R) -> Result<Self, lightning::ln::msgs::DecodeError> {
173-
let payload_without_length = WithoutLength::read(r)?;
172+
impl Readable for RawLSPSMessage {
173+
fn read<R: io::Read>(r: &mut R) -> Result<Self, DecodeError> {
174+
// Because strings will consume the entire reader when read, they are intended to be read from a
175+
// length-limiting reader. However, there's no way of knowing the length ahead of time in this
176+
// case so use a wrapper.
177+
struct UnknownLengthString(String);
178+
impl Readable for UnknownLengthString {
179+
fn read<R: io::Read>(r: &mut R) -> Result<Self, DecodeError> {
180+
let v: alloc::vec::Vec<u8> = Readable::read(r)?;
181+
let ret = String::from_utf8(v).map_err(|_| DecodeError::InvalidValue)?;
182+
Ok(Self(ret))
183+
}
184+
}
185+
186+
let payload_without_length: UnknownLengthString = Readable::read(r)?;
174187
Ok(Self { payload: payload_without_length.0 })
175188
}
176189
}

lightning/src/ln/msgs.rs

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2412,8 +2412,8 @@ impl Writeable for AcceptChannel {
24122412
}
24132413
}
24142414

2415-
impl Readable for AcceptChannel {
2416-
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
2415+
impl LengthReadable for AcceptChannel {
2416+
fn read_from_fixed_length_buffer<R: LengthLimitedRead>(r: &mut R) -> Result<Self, DecodeError> {
24172417
let temporary_channel_id: ChannelId = Readable::read(r)?;
24182418
let dust_limit_satoshis: u64 = Readable::read(r)?;
24192419
let max_htlc_value_in_flight_msat: u64 = Readable::read(r)?;
@@ -2497,8 +2497,8 @@ impl Writeable for AcceptChannelV2 {
24972497
}
24982498
}
24992499

2500-
impl Readable for AcceptChannelV2 {
2501-
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
2500+
impl LengthReadable for AcceptChannelV2 {
2501+
fn read_from_fixed_length_buffer<R: LengthLimitedRead>(r: &mut R) -> Result<Self, DecodeError> {
25022502
let temporary_channel_id: ChannelId = Readable::read(r)?;
25032503
let funding_satoshis: u64 = Readable::read(r)?;
25042504
let dust_limit_satoshis: u64 = Readable::read(r)?;
@@ -2760,8 +2760,8 @@ impl Writeable for Init {
27602760
}
27612761
}
27622762

2763-
impl Readable for Init {
2764-
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
2763+
impl LengthReadable for Init {
2764+
fn read_from_fixed_length_buffer<R: LengthLimitedRead>(r: &mut R) -> Result<Self, DecodeError> {
27652765
let global_features: InitFeatures = Readable::read(r)?;
27662766
let features: InitFeatures = Readable::read(r)?;
27672767
let mut remote_network_address: Option<SocketAddress> = None;
@@ -2806,8 +2806,8 @@ impl Writeable for OpenChannel {
28062806
}
28072807
}
28082808

2809-
impl Readable for OpenChannel {
2810-
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
2809+
impl LengthReadable for OpenChannel {
2810+
fn read_from_fixed_length_buffer<R: LengthLimitedRead>(r: &mut R) -> Result<Self, DecodeError> {
28112811
let chain_hash: ChainHash = Readable::read(r)?;
28122812
let temporary_channel_id: ChannelId = Readable::read(r)?;
28132813
let funding_satoshis: u64 = Readable::read(r)?;
@@ -2890,8 +2890,8 @@ impl Writeable for OpenChannelV2 {
28902890
}
28912891
}
28922892

2893-
impl Readable for OpenChannelV2 {
2894-
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
2893+
impl LengthReadable for OpenChannelV2 {
2894+
fn read_from_fixed_length_buffer<R: LengthLimitedRead>(r: &mut R) -> Result<Self, DecodeError> {
28952895
let chain_hash: ChainHash = Readable::read(r)?;
28962896
let temporary_channel_id: ChannelId = Readable::read(r)?;
28972897
let funding_feerate_sat_per_1000_weight: u32 = Readable::read(r)?;
@@ -3526,8 +3526,8 @@ impl Writeable for Ping {
35263526
}
35273527
}
35283528

3529-
impl Readable for Ping {
3530-
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
3529+
impl LengthReadable for Ping {
3530+
fn read_from_fixed_length_buffer<R: LengthLimitedRead>(r: &mut R) -> Result<Self, DecodeError> {
35313531
Ok(Ping {
35323532
ponglen: Readable::read(r)?,
35333533
byteslen: {
@@ -3546,8 +3546,8 @@ impl Writeable for Pong {
35463546
}
35473547
}
35483548

3549-
impl Readable for Pong {
3550-
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
3549+
impl LengthReadable for Pong {
3550+
fn read_from_fixed_length_buffer<R: LengthLimitedRead>(r: &mut R) -> Result<Self, DecodeError> {
35513551
Ok(Pong {
35523552
byteslen: {
35533553
let byteslen = Readable::read(r)?;
@@ -3653,8 +3653,8 @@ impl Writeable for ErrorMessage {
36533653
}
36543654
}
36553655

3656-
impl Readable for ErrorMessage {
3657-
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
3656+
impl LengthReadable for ErrorMessage {
3657+
fn read_from_fixed_length_buffer<R: LengthLimitedRead>(r: &mut R) -> Result<Self, DecodeError> {
36583658
Ok(Self {
36593659
channel_id: Readable::read(r)?,
36603660
data: {
@@ -3680,8 +3680,8 @@ impl Writeable for WarningMessage {
36803680
}
36813681
}
36823682

3683-
impl Readable for WarningMessage {
3684-
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
3683+
impl LengthReadable for WarningMessage {
3684+
fn read_from_fixed_length_buffer<R: LengthLimitedRead>(r: &mut R) -> Result<Self, DecodeError> {
36853685
Ok(Self {
36863686
channel_id: Readable::read(r)?,
36873687
data: {
@@ -3787,8 +3787,8 @@ impl_writeable!(NodeAnnouncement, {
37873787
contents
37883788
});
37893789

3790-
impl Readable for QueryShortChannelIds {
3791-
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
3790+
impl LengthReadable for QueryShortChannelIds {
3791+
fn read_from_fixed_length_buffer<R: LengthLimitedRead>(r: &mut R) -> Result<Self, DecodeError> {
37923792
let chain_hash: ChainHash = Readable::read(r)?;
37933793

37943794
let encoding_len: u16 = Readable::read(r)?;
@@ -3863,8 +3863,8 @@ impl_writeable_msg!(QueryChannelRange, {
38633863
number_of_blocks
38643864
}, {});
38653865

3866-
impl Readable for ReplyChannelRange {
3867-
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
3866+
impl LengthReadable for ReplyChannelRange {
3867+
fn read_from_fixed_length_buffer<R: LengthLimitedRead>(r: &mut R) -> Result<Self, DecodeError> {
38683868
let chain_hash: ChainHash = Readable::read(r)?;
38693869
let first_blocknum: u32 = Readable::read(r)?;
38703870
let number_of_blocks: u32 = Readable::read(r)?;
@@ -5445,7 +5445,7 @@ mod tests {
54455445
let encoded_value = reply_channel_range.encode();
54465446
assert_eq!(encoded_value, target_value);
54475447

5448-
reply_channel_range = Readable::read(&mut Cursor::new(&target_value[..])).unwrap();
5448+
reply_channel_range = LengthReadable::read_from_fixed_length_buffer(&mut &target_value[..]).unwrap();
54495449
assert_eq!(reply_channel_range.chain_hash, expected_chain_hash);
54505450
assert_eq!(reply_channel_range.first_blocknum, 756230);
54515451
assert_eq!(reply_channel_range.number_of_blocks, 1500);
@@ -5455,7 +5455,7 @@ mod tests {
54555455
assert_eq!(reply_channel_range.short_channel_ids[2], 0x000000000045a6c4);
54565456
} else {
54575457
target_value.append(&mut <Vec<u8>>::from_hex("001601789c636000833e08659309a65878be010010a9023a").unwrap());
5458-
let result: Result<msgs::ReplyChannelRange, msgs::DecodeError> = Readable::read(&mut Cursor::new(&target_value[..]));
5458+
let result: Result<msgs::ReplyChannelRange, msgs::DecodeError> = LengthReadable::read_from_fixed_length_buffer(&mut &target_value[..]);
54595459
assert!(result.is_err(), "Expected decode failure with unsupported zlib encoding");
54605460
}
54615461
}
@@ -5479,14 +5479,14 @@ mod tests {
54795479
let encoded_value = query_short_channel_ids.encode();
54805480
assert_eq!(encoded_value, target_value);
54815481

5482-
query_short_channel_ids = Readable::read(&mut Cursor::new(&target_value[..])).unwrap();
5482+
query_short_channel_ids = LengthReadable::read_from_fixed_length_buffer(&mut &target_value[..]).unwrap();
54835483
assert_eq!(query_short_channel_ids.chain_hash, expected_chain_hash);
54845484
assert_eq!(query_short_channel_ids.short_channel_ids[0], 0x000000000000008e);
54855485
assert_eq!(query_short_channel_ids.short_channel_ids[1], 0x0000000000003c69);
54865486
assert_eq!(query_short_channel_ids.short_channel_ids[2], 0x000000000045a6c4);
54875487
} else {
54885488
target_value.append(&mut <Vec<u8>>::from_hex("001601789c636000833e08659309a65878be010010a9023a").unwrap());
5489-
let result: Result<msgs::QueryShortChannelIds, msgs::DecodeError> = Readable::read(&mut Cursor::new(&target_value[..]));
5489+
let result: Result<msgs::QueryShortChannelIds, msgs::DecodeError> = LengthReadable::read_from_fixed_length_buffer(&mut &target_value[..]);
54905490
assert!(result.is_err(), "Expected decode failure with unsupported zlib encoding");
54915491
}
54925492
}

lightning/src/ln/wire.rs

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -257,21 +257,39 @@ where
257257
H::Target: CustomMessageReader<CustomMessage = T>,
258258
{
259259
match message_type {
260-
msgs::Init::TYPE => Ok(Message::Init(Readable::read(buffer)?)),
261-
msgs::ErrorMessage::TYPE => Ok(Message::Error(Readable::read(buffer)?)),
262-
msgs::WarningMessage::TYPE => Ok(Message::Warning(Readable::read(buffer)?)),
263-
msgs::Ping::TYPE => Ok(Message::Ping(Readable::read(buffer)?)),
264-
msgs::Pong::TYPE => Ok(Message::Pong(Readable::read(buffer)?)),
260+
msgs::Init::TYPE => {
261+
Ok(Message::Init(LengthReadable::read_from_fixed_length_buffer(buffer)?))
262+
},
263+
msgs::ErrorMessage::TYPE => {
264+
Ok(Message::Error(LengthReadable::read_from_fixed_length_buffer(buffer)?))
265+
},
266+
msgs::WarningMessage::TYPE => {
267+
Ok(Message::Warning(LengthReadable::read_from_fixed_length_buffer(buffer)?))
268+
},
269+
msgs::Ping::TYPE => {
270+
Ok(Message::Ping(LengthReadable::read_from_fixed_length_buffer(buffer)?))
271+
},
272+
msgs::Pong::TYPE => {
273+
Ok(Message::Pong(LengthReadable::read_from_fixed_length_buffer(buffer)?))
274+
},
265275
msgs::PeerStorage::TYPE => {
266276
Ok(Message::PeerStorage(LengthReadable::read_from_fixed_length_buffer(buffer)?))
267277
},
268278
msgs::PeerStorageRetrieval::TYPE => Ok(Message::PeerStorageRetrieval(
269279
LengthReadable::read_from_fixed_length_buffer(buffer)?,
270280
)),
271-
msgs::OpenChannel::TYPE => Ok(Message::OpenChannel(Readable::read(buffer)?)),
272-
msgs::OpenChannelV2::TYPE => Ok(Message::OpenChannelV2(Readable::read(buffer)?)),
273-
msgs::AcceptChannel::TYPE => Ok(Message::AcceptChannel(Readable::read(buffer)?)),
274-
msgs::AcceptChannelV2::TYPE => Ok(Message::AcceptChannelV2(Readable::read(buffer)?)),
281+
msgs::OpenChannel::TYPE => {
282+
Ok(Message::OpenChannel(LengthReadable::read_from_fixed_length_buffer(buffer)?))
283+
},
284+
msgs::OpenChannelV2::TYPE => {
285+
Ok(Message::OpenChannelV2(LengthReadable::read_from_fixed_length_buffer(buffer)?))
286+
},
287+
msgs::AcceptChannel::TYPE => {
288+
Ok(Message::AcceptChannel(LengthReadable::read_from_fixed_length_buffer(buffer)?))
289+
},
290+
msgs::AcceptChannelV2::TYPE => {
291+
Ok(Message::AcceptChannelV2(LengthReadable::read_from_fixed_length_buffer(buffer)?))
292+
},
275293
msgs::FundingCreated::TYPE => {
276294
Ok(Message::FundingCreated(LengthReadable::read_from_fixed_length_buffer(buffer)?))
277295
},
@@ -364,9 +382,9 @@ where
364382
},
365383
msgs::NodeAnnouncement::TYPE => Ok(Message::NodeAnnouncement(Readable::read(buffer)?)),
366384
msgs::ChannelUpdate::TYPE => Ok(Message::ChannelUpdate(Readable::read(buffer)?)),
367-
msgs::QueryShortChannelIds::TYPE => {
368-
Ok(Message::QueryShortChannelIds(Readable::read(buffer)?))
369-
},
385+
msgs::QueryShortChannelIds::TYPE => Ok(Message::QueryShortChannelIds(
386+
LengthReadable::read_from_fixed_length_buffer(buffer)?,
387+
)),
370388
msgs::ReplyShortChannelIdsEnd::TYPE => Ok(Message::ReplyShortChannelIdsEnd(
371389
LengthReadable::read_from_fixed_length_buffer(buffer)?,
372390
)),

lightning/src/offers/invoice.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,8 @@ use crate::offers::signer::{self, Metadata};
148148
use crate::types::features::{Bolt12InvoiceFeatures, InvoiceRequestFeatures, OfferFeatures};
149149
use crate::types::payment::PaymentHash;
150150
use crate::util::ser::{
151-
CursorReadable, HighZeroBytesDroppedBigSize, Iterable, Readable, WithoutLength, Writeable,
152-
Writer,
151+
CursorReadable, HighZeroBytesDroppedBigSize, Iterable, LengthLimitedRead, LengthReadable,
152+
WithoutLength, Writeable, Writer,
153153
};
154154
use crate::util::string::PrintableString;
155155
use bitcoin::address::Address;
@@ -1398,9 +1398,11 @@ impl Writeable for Bolt12Invoice {
13981398
}
13991399
}
14001400

1401-
impl Readable for Bolt12Invoice {
1402-
fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
1403-
let bytes: WithoutLength<Vec<u8>> = Readable::read(reader)?;
1401+
impl LengthReadable for Bolt12Invoice {
1402+
fn read_from_fixed_length_buffer<R: LengthLimitedRead>(
1403+
reader: &mut R,
1404+
) -> Result<Self, DecodeError> {
1405+
let bytes: WithoutLength<Vec<u8>> = LengthReadable::read_from_fixed_length_buffer(reader)?;
14041406
Self::try_from(bytes.0).map_err(|_| DecodeError::InvalidValue)
14051407
}
14061408
}

lightning/src/offers/invoice_request.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ use crate::onion_message::dns_resolution::HumanReadableName;
8686
use crate::types::features::InvoiceRequestFeatures;
8787
use crate::types::payment::PaymentHash;
8888
use crate::util::ser::{
89-
CursorReadable, HighZeroBytesDroppedBigSize, Readable, WithoutLength, Writeable, Writer,
89+
CursorReadable, HighZeroBytesDroppedBigSize, LengthLimitedRead, LengthReadable, Readable,
90+
WithoutLength, Writeable, Writer,
9091
};
9192
use crate::util::string::{PrintableString, UntrustedString};
9293
use bitcoin::constants::ChainHash;
@@ -1119,9 +1120,9 @@ impl Writeable for InvoiceRequestContents {
11191120
}
11201121
}
11211122

1122-
impl Readable for InvoiceRequest {
1123-
fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
1124-
let bytes: WithoutLength<Vec<u8>> = Readable::read(reader)?;
1123+
impl LengthReadable for InvoiceRequest {
1124+
fn read_from_fixed_length_buffer<R: LengthLimitedRead>(r: &mut R) -> Result<Self, DecodeError> {
1125+
let bytes: WithoutLength<Vec<u8>> = LengthReadable::read_from_fixed_length_buffer(r)?;
11251126
Self::try_from(bytes.0).map_err(|_| DecodeError::InvalidValue)
11261127
}
11271128
}

lightning/src/offers/offer.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ use crate::offers::parse::{Bech32Encode, Bolt12ParseError, Bolt12SemanticError,
8888
use crate::offers::signer::{self, Metadata, MetadataMaterial};
8989
use crate::types::features::OfferFeatures;
9090
use crate::util::ser::{
91-
CursorReadable, HighZeroBytesDroppedBigSize, Readable, WithoutLength, Writeable, Writer,
91+
CursorReadable, HighZeroBytesDroppedBigSize, LengthLimitedRead, LengthReadable, Readable,
92+
WithoutLength, Writeable, Writer,
9293
};
9394
use crate::util::string::PrintableString;
9495
use bitcoin::constants::ChainHash;
@@ -1033,9 +1034,11 @@ impl OfferContents {
10331034
}
10341035
}
10351036

1036-
impl Readable for Offer {
1037-
fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
1038-
let bytes: WithoutLength<Vec<u8>> = Readable::read(reader)?;
1037+
impl LengthReadable for Offer {
1038+
fn read_from_fixed_length_buffer<R: LengthLimitedRead>(
1039+
reader: &mut R,
1040+
) -> Result<Self, DecodeError> {
1041+
let bytes: WithoutLength<Vec<u8>> = LengthReadable::read_from_fixed_length_buffer(reader)?;
10391042
Self::try_from(bytes.0).map_err(|_| DecodeError::InvalidValue)
10401043
}
10411044
}

lightning/src/offers/refund.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@ use crate::offers::signer::{self, Metadata, MetadataMaterial};
102102
use crate::sign::EntropySource;
103103
use crate::types::features::InvoiceRequestFeatures;
104104
use crate::types::payment::PaymentHash;
105-
use crate::util::ser::{CursorReadable, Readable, WithoutLength, Writeable, Writer};
105+
use crate::util::ser::{
106+
CursorReadable, LengthLimitedRead, LengthReadable, WithoutLength, Writeable, Writer,
107+
};
106108
use crate::util::string::PrintableString;
107109
use bitcoin::constants::ChainHash;
108110
use bitcoin::network::Network;
@@ -822,9 +824,11 @@ impl RefundContents {
822824
}
823825
}
824826

825-
impl Readable for Refund {
826-
fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
827-
let bytes: WithoutLength<Vec<u8>> = Readable::read(reader)?;
827+
impl LengthReadable for Refund {
828+
fn read_from_fixed_length_buffer<R: LengthLimitedRead>(
829+
reader: &mut R,
830+
) -> Result<Self, DecodeError> {
831+
let bytes: WithoutLength<Vec<u8>> = LengthReadable::read_from_fixed_length_buffer(reader)?;
828832
Self::try_from(bytes.0).map_err(|_| DecodeError::InvalidValue)
829833
}
830834
}

0 commit comments

Comments
 (0)