Skip to content

Commit 7b1bb4a

Browse files
Require length limited reader for all LN messages
When deserializing lightning messages, many consume the reader until it is out of bytes, or could in the future if new fields or TLVs are added. Therefore, it's safer if they are only provided with readers that limit how much of the byte stream will be read. Many of the relevant LN messages were updated in a prior commit when we transitioned impl_writeable_msg to require length limiting readers, here we finish the job.
1 parent 6f96d02 commit 7b1bb4a

File tree

4 files changed

+81
-55
lines changed

4 files changed

+81
-55
lines changed

fuzz/src/msg_targets/utils.rs

+11-10
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,16 @@ impl Writer for VecWriter {
3030
#[macro_export]
3131
macro_rules! test_msg {
3232
($MsgType: path, $data: ident) => {{
33-
use lightning::util::ser::{Readable, Writeable};
34-
let mut r = ::lightning::io::Cursor::new($data);
35-
if let Ok(msg) = <$MsgType as Readable>::read(&mut r) {
36-
let p = r.position() as usize;
33+
use lightning::util::ser::{LengthReadable, Writeable};
34+
let mut r = &$data[..];
35+
if let Ok(msg) = <$MsgType as LengthReadable>::read_from_fixed_length_buffer(&mut r) {
36+
let p = $data.len() - r.len() as usize;
3737
let mut w = VecWriter(Vec::new());
3838
msg.write(&mut w).unwrap();
3939

4040
assert_eq!(w.0.len(), p);
4141
assert_eq!(msg.serialized_length(), p);
42-
assert_eq!(&r.into_inner()[..p], &w.0[..p]);
42+
assert_eq!(&$data[..p], &w.0[..p]);
4343
}
4444
}};
4545
}
@@ -88,17 +88,18 @@ macro_rules! test_msg_exact {
8888
#[macro_export]
8989
macro_rules! test_msg_hole {
9090
($MsgType: path, $data: ident, $hole: expr, $hole_len: expr) => {{
91-
use lightning::util::ser::{Readable, Writeable};
92-
let mut r = ::lightning::io::Cursor::new($data);
93-
if let Ok(msg) = <$MsgType as Readable>::read(&mut r) {
91+
use lightning::util::ser::{LengthReadable, Writeable};
92+
if let Ok(msg) =
93+
<$MsgType as LengthReadable>::read_from_fixed_length_buffer(&mut &$data[..])
94+
{
9495
let mut w = VecWriter(Vec::new());
9596
msg.write(&mut w).unwrap();
9697
let p = w.0.len() as usize;
9798
assert_eq!(msg.serialized_length(), p);
9899

99100
assert_eq!(w.0.len(), p);
100-
assert_eq!(&r.get_ref()[..$hole], &w.0[..$hole]);
101-
assert_eq!(&r.get_ref()[$hole + $hole_len..p], &w.0[$hole + $hole_len..]);
101+
assert_eq!(&$data[..$hole], &w.0[..$hole]);
102+
assert_eq!(&$data[$hole + $hole_len..p], &w.0[$hole + $hole_len..]);
102103
}
103104
}};
104105
}

fuzz/src/onion_message.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,23 @@ use lightning::onion_message::packet::OnionMessageContents;
2626
use lightning::sign::{EntropySource, NodeSigner, Recipient, SignerProvider};
2727
use lightning::types::features::InitFeatures;
2828
use lightning::util::logger::Logger;
29-
use lightning::util::ser::{Readable, Writeable, Writer};
29+
use lightning::util::ser::{LengthReadable, Writeable, Writer};
3030
use lightning::util::test_channel_signer::TestChannelSigner;
3131

3232
use lightning_invoice::RawBolt11Invoice;
3333

3434
use crate::utils::test_logger;
3535

36-
use lightning::io::{self, Cursor};
36+
use lightning::io;
3737
use std::sync::atomic::{AtomicU64, Ordering};
3838

3939
#[inline]
4040
/// Actual fuzz test, method signature and name are fixed
4141
pub fn do_test<L: Logger>(data: &[u8], logger: &L) {
42-
if let Ok(msg) = <msgs::OnionMessage as Readable>::read(&mut Cursor::new(data)) {
42+
let mut reader = &data[..];
43+
if let Ok(msg) =
44+
<msgs::OnionMessage as LengthReadable>::read_from_fixed_length_buffer(&mut reader)
45+
{
4346
let mut secret_bytes = [1; 32];
4447
secret_bytes[31] = 2;
4548
let secret = SecretKey::from_slice(&secret_bytes).unwrap();

lightning/src/ln/msgs.rs

+28-28
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)?;
@@ -3052,8 +3052,8 @@ impl_writeable_msg!(UpdateAddHTLC, {
30523052
(65537, skimmed_fee_msat, option)
30533053
});
30543054

3055-
impl Readable for OnionMessage {
3056-
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
3055+
impl LengthReadable for OnionMessage {
3056+
fn read_from_fixed_length_buffer<R: LengthLimitedRead>(r: &mut R) -> Result<Self, DecodeError> {
30573057
let blinding_point: PublicKey = Readable::read(r)?;
30583058
let len: u16 = Readable::read(r)?;
30593059
let mut packet_reader = FixedLengthReader::new(r, len as u64);
@@ -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)?;
@@ -3680,8 +3680,8 @@ impl Writeable for ErrorMessage {
36803680
}
36813681
}
36823682

3683-
impl Readable for ErrorMessage {
3684-
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
3683+
impl LengthReadable for ErrorMessage {
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: {
@@ -3707,8 +3707,8 @@ impl Writeable for WarningMessage {
37073707
}
37083708
}
37093709

3710-
impl Readable for WarningMessage {
3711-
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
3710+
impl LengthReadable for WarningMessage {
3711+
fn read_from_fixed_length_buffer<R: LengthLimitedRead>(r: &mut R) -> Result<Self, DecodeError> {
37123712
Ok(Self {
37133713
channel_id: Readable::read(r)?,
37143714
data: {
@@ -3826,8 +3826,8 @@ impl LengthReadable for NodeAnnouncement {
38263826
}
38273827
}
38283828

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

38333833
let encoding_len: u16 = Readable::read(r)?;
@@ -3902,8 +3902,8 @@ impl_writeable_msg!(QueryChannelRange, {
39023902
number_of_blocks
39033903
}, {});
39043904

3905-
impl Readable for ReplyChannelRange {
3906-
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
3905+
impl LengthReadable for ReplyChannelRange {
3906+
fn read_from_fixed_length_buffer<R: LengthLimitedRead>(r: &mut R) -> Result<Self, DecodeError> {
39073907
let chain_hash: ChainHash = Readable::read(r)?;
39083908
let first_blocknum: u32 = Readable::read(r)?;
39093909
let number_of_blocks: u32 = Readable::read(r)?;
@@ -5484,7 +5484,7 @@ mod tests {
54845484
let encoded_value = reply_channel_range.encode();
54855485
assert_eq!(encoded_value, target_value);
54865486

5487-
reply_channel_range = Readable::read(&mut Cursor::new(&target_value[..])).unwrap();
5487+
reply_channel_range = LengthReadable::read_from_fixed_length_buffer(&mut &target_value[..]).unwrap();
54885488
assert_eq!(reply_channel_range.chain_hash, expected_chain_hash);
54895489
assert_eq!(reply_channel_range.first_blocknum, 756230);
54905490
assert_eq!(reply_channel_range.number_of_blocks, 1500);
@@ -5494,7 +5494,7 @@ mod tests {
54945494
assert_eq!(reply_channel_range.short_channel_ids[2], 0x000000000045a6c4);
54955495
} else {
54965496
target_value.append(&mut <Vec<u8>>::from_hex("001601789c636000833e08659309a65878be010010a9023a").unwrap());
5497-
let result: Result<msgs::ReplyChannelRange, msgs::DecodeError> = Readable::read(&mut Cursor::new(&target_value[..]));
5497+
let result: Result<msgs::ReplyChannelRange, msgs::DecodeError> = LengthReadable::read_from_fixed_length_buffer(&mut &target_value[..]);
54985498
assert!(result.is_err(), "Expected decode failure with unsupported zlib encoding");
54995499
}
55005500
}
@@ -5518,14 +5518,14 @@ mod tests {
55185518
let encoded_value = query_short_channel_ids.encode();
55195519
assert_eq!(encoded_value, target_value);
55205520

5521-
query_short_channel_ids = Readable::read(&mut Cursor::new(&target_value[..])).unwrap();
5521+
query_short_channel_ids = LengthReadable::read_from_fixed_length_buffer(&mut &target_value[..]).unwrap();
55225522
assert_eq!(query_short_channel_ids.chain_hash, expected_chain_hash);
55235523
assert_eq!(query_short_channel_ids.short_channel_ids[0], 0x000000000000008e);
55245524
assert_eq!(query_short_channel_ids.short_channel_ids[1], 0x0000000000003c69);
55255525
assert_eq!(query_short_channel_ids.short_channel_ids[2], 0x000000000045a6c4);
55265526
} else {
55275527
target_value.append(&mut <Vec<u8>>::from_hex("001601789c636000833e08659309a65878be010010a9023a").unwrap());
5528-
let result: Result<msgs::QueryShortChannelIds, msgs::DecodeError> = Readable::read(&mut Cursor::new(&target_value[..]));
5528+
let result: Result<msgs::QueryShortChannelIds, msgs::DecodeError> = LengthReadable::read_from_fixed_length_buffer(&mut &target_value[..]);
55295529
assert!(result.is_err(), "Expected decode failure with unsupported zlib encoding");
55305530
}
55315531
}

lightning/src/ln/wire.rs

+36-14
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
},
@@ -329,7 +347,9 @@ where
329347
msgs::ClosingSigned::TYPE => {
330348
Ok(Message::ClosingSigned(LengthReadable::read_from_fixed_length_buffer(buffer)?))
331349
},
332-
msgs::OnionMessage::TYPE => Ok(Message::OnionMessage(Readable::read(buffer)?)),
350+
msgs::OnionMessage::TYPE => {
351+
Ok(Message::OnionMessage(LengthReadable::read_from_fixed_length_buffer(buffer)?))
352+
},
333353
msgs::UpdateAddHTLC::TYPE => {
334354
Ok(Message::UpdateAddHTLC(LengthReadable::read_from_fixed_length_buffer(buffer)?))
335355
},
@@ -366,16 +386,18 @@ where
366386
msgs::ChannelUpdate::TYPE => {
367387
Ok(Message::ChannelUpdate(LengthReadable::read_from_fixed_length_buffer(buffer)?))
368388
},
369-
msgs::QueryShortChannelIds::TYPE => {
370-
Ok(Message::QueryShortChannelIds(Readable::read(buffer)?))
371-
},
389+
msgs::QueryShortChannelIds::TYPE => Ok(Message::QueryShortChannelIds(
390+
LengthReadable::read_from_fixed_length_buffer(buffer)?,
391+
)),
372392
msgs::ReplyShortChannelIdsEnd::TYPE => Ok(Message::ReplyShortChannelIdsEnd(
373393
LengthReadable::read_from_fixed_length_buffer(buffer)?,
374394
)),
375395
msgs::QueryChannelRange::TYPE => {
376396
Ok(Message::QueryChannelRange(LengthReadable::read_from_fixed_length_buffer(buffer)?))
377397
},
378-
msgs::ReplyChannelRange::TYPE => Ok(Message::ReplyChannelRange(Readable::read(buffer)?)),
398+
msgs::ReplyChannelRange::TYPE => {
399+
Ok(Message::ReplyChannelRange(LengthReadable::read_from_fixed_length_buffer(buffer)?))
400+
},
379401
msgs::GossipTimestampFilter::TYPE => Ok(Message::GossipTimestampFilter(
380402
LengthReadable::read_from_fixed_length_buffer(buffer)?,
381403
)),

0 commit comments

Comments
 (0)