Skip to content

Commit cf413c5

Browse files
committed
Fix
1 parent 01c3c4e commit cf413c5

File tree

3 files changed

+53
-29
lines changed

3 files changed

+53
-29
lines changed

packages/vm/src/errors/communication_error.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ pub enum CommunicationError {
2525
#[from]
2626
source: RegionValidationError,
2727
},
28+
/// When the contract supplies invalid section data to the host. See also `decode_sections` [crate::sections::decode_sections].
29+
#[error("Got an invalid section: {}", msg)]
30+
InvalidSection { msg: String },
2831
/// Whenever UTF-8 bytes cannot be decoded into a unicode string, e.g. in String::from_utf8 or str::from_utf8.
2932
#[error("Cannot decode UTF8 bytes into string: {}", msg)]
3033
InvalidUtf8 { msg: String },
@@ -56,6 +59,10 @@ impl CommunicationError {
5659
CommunicationError::InvalidOrder { value }
5760
}
5861

62+
pub(crate) fn invalid_section(msg: impl Into<String>) -> Self {
63+
CommunicationError::InvalidSection { msg: msg.into() }
64+
}
65+
5966
#[allow(dead_code)]
6067
pub(crate) fn invalid_utf8(msg: impl ToString) -> Self {
6168
CommunicationError::InvalidUtf8 {

packages/vm/src/imports.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -730,9 +730,9 @@ pub fn do_ed25519_batch_verify<
730730
(EDDSA_PUBKEY_LEN + 4) * MAX_COUNT_ED25519_BATCH,
731731
)?;
732732

733-
let messages = decode_sections(&messages);
734-
let signatures = decode_sections(&signatures);
735-
let public_keys = decode_sections(&public_keys);
733+
let messages = decode_sections(&messages)?;
734+
let signatures = decode_sections(&signatures)?;
735+
let public_keys = decode_sections(&public_keys)?;
736736

737737
let gas_cost = if public_keys.len() == 1 {
738738
&data.gas_config.ed25519_batch_verify_one_pubkey_cost

packages/vm/src/sections.rs

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
use crate::conversion::to_u32;
2-
use crate::errors::VmResult;
2+
use crate::{CommunicationError, VmResult};
33

44
/// Decodes sections of data into multiple slices.
55
///
66
/// Each encoded section is suffixed by a section length, encoded as big endian uint32.
77
///
8-
/// See also: `encode_section`.
9-
#[allow(dead_code)]
10-
pub fn decode_sections(data: &[u8]) -> Vec<&[u8]> {
8+
/// See also: [`encode_sections`].
9+
pub fn decode_sections(data: &[u8]) -> Result<Vec<&[u8]>, CommunicationError> {
1110
let mut result: Vec<&[u8]> = vec![];
1211
let mut remaining_len = data.len();
1312
while remaining_len >= 4 {
@@ -17,11 +16,20 @@ pub fn decode_sections(data: &[u8]) -> Vec<&[u8]> {
1716
data[remaining_len - 2],
1817
data[remaining_len - 1],
1918
]) as usize;
20-
result.push(&data[remaining_len - 4 - tail_len..remaining_len - 4]);
21-
remaining_len -= 4 + tail_len;
19+
let tail_len_idx = remaining_len - 4; // index of the first byte of the tail length
20+
let section_start = tail_len_idx
21+
.checked_sub(tail_len)
22+
.ok_or_else(|| CommunicationError::invalid_section("section length overflow"))?;
23+
result.push(&data[section_start..tail_len_idx]);
24+
remaining_len = section_start;
25+
}
26+
if remaining_len > 0 {
27+
return Err(CommunicationError::invalid_section(
28+
"extra data outside of any section",
29+
));
2230
}
2331
result.reverse();
24-
result
32+
Ok(result)
2533
}
2634

2735
/// Encodes multiple sections of data into one vector.
@@ -57,52 +65,61 @@ mod tests {
5765

5866
#[test]
5967
fn decode_sections_works_for_empty_sections() {
60-
let dec = decode_sections(&[]);
68+
let dec = decode_sections(&[]).unwrap();
6169
assert_eq!(dec.len(), 0);
62-
let dec = decode_sections(b"\0\0\0\0");
70+
let dec = decode_sections(b"\0\0\0\0").unwrap();
6371
assert_eq!(dec, &[&[0u8; 0]]);
64-
let dec = decode_sections(b"\0\0\0\0\0\0\0\0");
72+
let dec = decode_sections(b"\0\0\0\0\0\0\0\0").unwrap();
6573
assert_eq!(dec, &[&[0u8; 0]; 2]);
66-
let dec = decode_sections(b"\0\0\0\0\0\0\0\0\0\0\0\0");
74+
let dec = decode_sections(b"\0\0\0\0\0\0\0\0\0\0\0\0").unwrap();
6775
assert_eq!(dec, &[&[0u8; 0]; 3]);
68-
// ignores "trailing" stuff
69-
let dec = decode_sections(b"\0\0\0\0\0\0\0\0\0\0\0");
70-
assert_eq!(dec, &[&[0u8; 0]; 2]);
7176
}
7277

7378
#[test]
7479
fn decode_sections_works_for_one_element() {
75-
let dec = decode_sections(b"\xAA\0\0\0\x01");
80+
let dec = decode_sections(b"\xAA\0\0\0\x01").unwrap();
7681
assert_eq!(dec, &[vec![0xAA]]);
77-
let dec = decode_sections(b"\xAA\xBB\0\0\0\x02");
82+
let dec = decode_sections(b"\xAA\xBB\0\0\0\x02").unwrap();
7883
assert_eq!(dec, &[vec![0xAA, 0xBB]]);
79-
let dec = decode_sections(b"\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\0\0\x01\x15");
84+
let dec = decode_sections(b"\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\0\0\x01\x15").unwrap();
8085
assert_eq!(dec, &[vec![0x9D; 277]]);
8186
}
8287

8388
#[test]
8489
fn decode_sections_works_for_two_elements() {
8590
let data = b"\xAA\0\0\0\x01\xBB\xCC\0\0\0\x02".to_vec();
86-
assert_eq!(decode_sections(&data), &[vec![0xAA], vec![0xBB, 0xCC]]);
91+
assert_eq!(
92+
decode_sections(&data).unwrap(),
93+
&[vec![0xAA], vec![0xBB, 0xCC]]
94+
);
8795
let data = b"\xDE\xEF\x62\0\0\0\x03\0\0\0\0".to_vec();
88-
assert_eq!(decode_sections(&data), &[vec![0xDE, 0xEF, 0x62], vec![]]);
96+
assert_eq!(
97+
decode_sections(&data).unwrap(),
98+
&[vec![0xDE, 0xEF, 0x62], vec![]]
99+
);
89100
let data = b"\0\0\0\0\xDE\xEF\x62\0\0\0\x03".to_vec();
90-
assert_eq!(decode_sections(&data), &[vec![], vec![0xDE, 0xEF, 0x62]]);
101+
assert_eq!(
102+
decode_sections(&data).unwrap(),
103+
&[vec![], vec![0xDE, 0xEF, 0x62]]
104+
);
91105
let data = b"\0\0\0\0\0\0\0\0".to_vec();
92-
assert_eq!(decode_sections(&data), &[vec![0u8; 0], vec![]]);
106+
assert_eq!(decode_sections(&data).unwrap(), &[vec![0u8; 0], vec![]]);
93107
let data = b"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\x13\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\x9D\0\0\x01\x15".to_vec();
94-
assert_eq!(decode_sections(&data), &[vec![0xFF; 19], vec![0x9D; 277]]);
108+
assert_eq!(
109+
decode_sections(&data).unwrap(),
110+
&[vec![0xFF; 19], vec![0x9D; 277]]
111+
);
95112
}
96113

97114
#[test]
98115
fn decode_sections_works_for_multiple_elements() {
99-
let dec = decode_sections(b"\xAA\0\0\0\x01");
116+
let dec = decode_sections(b"\xAA\0\0\0\x01").unwrap();
100117
assert_eq!(dec, &[vec![0xAA]]);
101-
let dec = decode_sections(b"\xAA\0\0\0\x01\xDE\xDE\0\0\0\x02");
118+
let dec = decode_sections(b"\xAA\0\0\0\x01\xDE\xDE\0\0\0\x02").unwrap();
102119
assert_eq!(dec, &[vec![0xAA], vec![0xDE, 0xDE]]);
103-
let dec = decode_sections(b"\xAA\0\0\0\x01\xDE\xDE\0\0\0\x02\0\0\0\0");
120+
let dec = decode_sections(b"\xAA\0\0\0\x01\xDE\xDE\0\0\0\x02\0\0\0\0").unwrap();
104121
assert_eq!(dec, &[vec![0xAA], vec![0xDE, 0xDE], vec![]]);
105-
let dec = decode_sections(b"\xAA\0\0\0\x01\xDE\xDE\0\0\0\x02\0\0\0\0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\x13");
122+
let dec = decode_sections(b"\xAA\0\0\0\x01\xDE\xDE\0\0\0\x02\0\0\0\0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\x13").unwrap();
106123
assert_eq!(dec, &[vec![0xAA], vec![0xDE, 0xDE], vec![], vec![0xFF; 19]]);
107124
}
108125

0 commit comments

Comments
 (0)