Skip to content

Commit 81e3c41

Browse files
Fix possible incomplete read bug on onion packet decode
Pre-existing to this PR, we were reading next packet bytes with io::Read::read, which is not guaranteed to read all the bytes we need, only guaranteed to read *some* bytes. We fix this to be read_exact, which is guaranteed to read all the next hop packet bytes.
1 parent b542021 commit 81e3c41

File tree

2 files changed

+18
-3
lines changed

2 files changed

+18
-3
lines changed

lightning/src/ln/onion_utils.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,7 @@ pub(crate) fn decode_next_hop<D: DecodeInput, R: ReadableArgs<D::Arg>, N: NextPa
683683
}
684684

685685
let mut chacha = ChaCha20::new(&rho, &[0u8; 8]);
686-
let mut chacha_stream = ChaChaReader { chacha: &mut chacha, read: Cursor::new(&hop_data[..]) };
686+
let mut chacha_stream = ChaChaReader::new(&mut chacha, Cursor::new(&hop_data[..]));
687687
match R::read(&mut chacha_stream, decode_input.read_arg()) {
688688
Err(err) => {
689689
let error_code = match err {
@@ -725,7 +725,8 @@ pub(crate) fn decode_next_hop<D: DecodeInput, R: ReadableArgs<D::Arg>, N: NextPa
725725
return Ok((msg, None)); // We are the final destination for this packet
726726
} else {
727727
let mut new_packet_bytes = N::new(hop_data.len());
728-
let read_pos = chacha_stream.read(new_packet_bytes.as_mut()).unwrap();
728+
let new_packet_bytes_len = hop_data.len() - chacha_stream.bytes_read();
729+
chacha_stream.read_exact(&mut new_packet_bytes.as_mut()[..new_packet_bytes_len]).unwrap();
729730
#[cfg(debug_assertions)]
730731
{
731732
// Check two things:
@@ -737,7 +738,7 @@ pub(crate) fn decode_next_hop<D: DecodeInput, R: ReadableArgs<D::Arg>, N: NextPa
737738
}
738739
// Once we've emptied the set of bytes our peer gave us, encrypt 0 bytes until we
739740
// fill the onion hop data we'll forward to our next-hop peer.
740-
chacha_stream.chacha.process_in_place(&mut new_packet_bytes.as_mut()[read_pos..]);
741+
chacha_stream.chacha.process_in_place(&mut new_packet_bytes.as_mut()[new_packet_bytes_len..]);
741742
return Ok((msg, Some((hmac, new_packet_bytes)))) // This packet needs forwarding
742743
}
743744
},

lightning/src/util/chacha20.rs

+14
Original file line numberDiff line numberDiff line change
@@ -303,16 +303,30 @@ pub use self::fuzzy_chacha::ChaCha20;
303303
pub(crate) struct ChaChaReader<'a, R: io::Read> {
304304
pub chacha: &'a mut ChaCha20,
305305
pub read: R,
306+
bytes_read: usize,
306307
}
307308
impl<'a, R: io::Read> io::Read for ChaChaReader<'a, R> {
308309
fn read(&mut self, dest: &mut [u8]) -> Result<usize, io::Error> {
309310
let res = self.read.read(dest)?;
310311
if res > 0 {
311312
self.chacha.process_in_place(&mut dest[0..res]);
312313
}
314+
self.bytes_read += res;
313315
Ok(res)
314316
}
315317
}
318+
impl<'a, R: io::Read> ChaChaReader<'a, R> {
319+
pub(crate) fn new(chacha: &'a mut ChaCha20, read: R) -> Self {
320+
Self {
321+
chacha,
322+
read,
323+
bytes_read: 0,
324+
}
325+
}
326+
pub(crate) fn bytes_read(&self) -> usize {
327+
self.bytes_read
328+
}
329+
}
316330

317331
#[cfg(test)]
318332
mod test {

0 commit comments

Comments
 (0)