gossamer icon indicating copy to clipboard operation
gossamer copied to clipboard

Bug: payload makes scale decoder go out of memory

Open qdm12 opened this issue 2 years ago • 1 comments

Describe the bug

Scale decoder can go out of memory with specific input bytes, this will panic:

func Test_Decoder_Decode_Fail(t *testing.T) {
	reader := bytes.NewBuffer([]byte{0x7, 0x8, 0x9, 0x10, 0x0, 0x40})
	decoder := scale.NewDecoder(reader)
	var result []byte
	_ = decoder.Decode(&result)
}

The message was found a bit randomly whilst writing tests for the trie.

Maybe we need something like https://docs.rs/parity-scale-codec/3.1.5/parity_scale_codec/trait.DecodeLimit.html to prevent crazy recursions 🤔

As a side note, we should definitely do #2630

Expected Behavior

Do not go out of memory / do not panic.

Current Behavior

fatal error: runtime: out of memory

qdm12 avatar Jun 29 '22 18:06 qdm12

Parity have this scale limit built-in using those error strings (so check the code using those) https://github.com/paritytech/parity-scale-codec/blob/af15ea7cf7cc5195eb37d1f5c326f5335eff6631/src/compact.rs#L425

My Rust test code I added to src/decode_all.rs in the parity-scale-codec repository:

	fn decode_memory_maybe() {
		let encoded = vec![0x7, 0x8, 0x9, 0x10, 0x0, 0x40];
		let result = <Vec<u8>>::decode_all(&mut encoded.as_slice());
		assert_eq!(result.is_err(), true);
		assert_eq!(result.unwrap_err().to_string(), "out of range decoding Compact<u32>");
	}

qdm12 avatar Jul 18 '22 18:07 qdm12