Skip to content

Commit

Permalink
Fix possible incomplete read bug on onion packet decode
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
valentinewallace committed Jul 28, 2022
1 parent b542021 commit 81e3c41
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 3 deletions.
7 changes: 4 additions & 3 deletions lightning/src/ln/onion_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,7 @@ pub(crate) fn decode_next_hop<D: DecodeInput, R: ReadableArgs<D::Arg>, N: NextPa
}

let mut chacha = ChaCha20::new(&rho, &[0u8; 8]);
let mut chacha_stream = ChaChaReader { chacha: &mut chacha, read: Cursor::new(&hop_data[..]) };
let mut chacha_stream = ChaChaReader::new(&mut chacha, Cursor::new(&hop_data[..]));
match R::read(&mut chacha_stream, decode_input.read_arg()) {
Err(err) => {
let error_code = match err {
Expand Down Expand Up @@ -725,7 +725,8 @@ pub(crate) fn decode_next_hop<D: DecodeInput, R: ReadableArgs<D::Arg>, N: NextPa
return Ok((msg, None)); // We are the final destination for this packet
} else {
let mut new_packet_bytes = N::new(hop_data.len());
let read_pos = chacha_stream.read(new_packet_bytes.as_mut()).unwrap();
let new_packet_bytes_len = hop_data.len() - chacha_stream.bytes_read();
chacha_stream.read_exact(&mut new_packet_bytes.as_mut()[..new_packet_bytes_len]).unwrap();
#[cfg(debug_assertions)]
{
// Check two things:
Expand All @@ -737,7 +738,7 @@ pub(crate) fn decode_next_hop<D: DecodeInput, R: ReadableArgs<D::Arg>, N: NextPa
}
// Once we've emptied the set of bytes our peer gave us, encrypt 0 bytes until we
// fill the onion hop data we'll forward to our next-hop peer.
chacha_stream.chacha.process_in_place(&mut new_packet_bytes.as_mut()[read_pos..]);
chacha_stream.chacha.process_in_place(&mut new_packet_bytes.as_mut()[new_packet_bytes_len..]);
return Ok((msg, Some((hmac, new_packet_bytes)))) // This packet needs forwarding
}
},
Expand Down
14 changes: 14 additions & 0 deletions lightning/src/util/chacha20.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,16 +303,30 @@ pub use self::fuzzy_chacha::ChaCha20;
pub(crate) struct ChaChaReader<'a, R: io::Read> {
pub chacha: &'a mut ChaCha20,
pub read: R,
bytes_read: usize,
}
impl<'a, R: io::Read> io::Read for ChaChaReader<'a, R> {
fn read(&mut self, dest: &mut [u8]) -> Result<usize, io::Error> {
let res = self.read.read(dest)?;
if res > 0 {
self.chacha.process_in_place(&mut dest[0..res]);
}
self.bytes_read += res;
Ok(res)
}
}
impl<'a, R: io::Read> ChaChaReader<'a, R> {
pub(crate) fn new(chacha: &'a mut ChaCha20, read: R) -> Self {
Self {
chacha,
read,
bytes_read: 0,
}
}
pub(crate) fn bytes_read(&self) -> usize {
self.bytes_read
}
}

#[cfg(test)]
mod test {
Expand Down

0 comments on commit 81e3c41

Please sign in to comment.