From 6b3f5c977aafb753a360830cd1a797430a76ae8a Mon Sep 17 00:00:00 2001 From: NikVolf Date: Thu, 3 Aug 2017 21:35:51 +0300 Subject: [PATCH 1/2] overflow check in addition --- util/rlp/src/error.rs | 2 ++ util/rlp/src/untrusted_rlp.rs | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/util/rlp/src/error.rs b/util/rlp/src/error.rs index 6b15ea8a6..5113fdc17 100644 --- a/util/rlp/src/error.rs +++ b/util/rlp/src/error.rs @@ -30,6 +30,8 @@ pub enum DecoderError { RlpInvalidIndirection, /// Declared length is inconsistent with data specified after. RlpInconsistentLengthAndData, + /// Declared length is invalid and results in overflow + RlpInvalidLength, /// Custom rlp decoding error. Custom(&'static str), } diff --git a/util/rlp/src/untrusted_rlp.rs b/util/rlp/src/untrusted_rlp.rs index 16714fe98..e7eb44f5d 100644 --- a/util/rlp/src/untrusted_rlp.rs +++ b/util/rlp/src/untrusted_rlp.rs @@ -371,7 +371,8 @@ impl<'a> BasicDecoder<'a> { } let len = decode_usize(&bytes[1..begin_of_value])?; - let last_index_of_value = begin_of_value + len; + let last_index_of_value = begin_of_value.overflowing_add(len) + .ok_or(DecoderError::RlpInvalidLength)?; if bytes.len() < last_index_of_value { return Err(DecoderError::RlpInconsistentLengthAndData); } From d30e47a50e73cb8c7c1298615e431877a153c1b0 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Thu, 3 Aug 2017 21:40:16 +0300 Subject: [PATCH 2/2] add test --- util/rlp/src/untrusted_rlp.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/util/rlp/src/untrusted_rlp.rs b/util/rlp/src/untrusted_rlp.rs index e7eb44f5d..41149606c 100644 --- a/util/rlp/src/untrusted_rlp.rs +++ b/util/rlp/src/untrusted_rlp.rs @@ -371,7 +371,7 @@ impl<'a> BasicDecoder<'a> { } let len = decode_usize(&bytes[1..begin_of_value])?; - let last_index_of_value = begin_of_value.overflowing_add(len) + let last_index_of_value = begin_of_value.checked_add(len) .ok_or(DecoderError::RlpInvalidLength)?; if bytes.len() < last_index_of_value { return Err(DecoderError::RlpInconsistentLengthAndData); @@ -386,7 +386,7 @@ impl<'a> BasicDecoder<'a> { #[cfg(test)] mod tests { - use UntrustedRlp; + use {UntrustedRlp, DecoderError}; #[test] fn test_rlp_display() { @@ -395,4 +395,12 @@ mod tests { let rlp = UntrustedRlp::new(&data); assert_eq!(format!("{}", rlp), "[\"0x05\", \"0x010efbef67941f79b2\", \"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\", \"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\"]"); } + + #[test] + fn length_overflow() { + let bs = [0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe5]; + let rlp = UntrustedRlp::new(&bs); + let res: Result = rlp.as_val(); + assert_eq!(Err(DecoderError::RlpInvalidLength), res); + } }