[sdk-wasm-js] Add length check on type conversion #341
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem
The
solana-sdk-wasm-jscrate contain several functions that copy an outside-controlled JS data into WebAssembly memory before validating the input's size. This "copy-before-validate" can lead to excessive memory growth when oversized data are provided as input.Summary of Changes
I went through the crate to added length checks for all the functions that "copy-before-validate".
hash.rs: This was pretty straightforward. I just added length check if the value that is provided to the constructor does not match the expected hash bytes (32 bytes).keypair.rs: I updated the API offromBytesfunction to directly take in aUint8Arrayinstead of a bytes slice.When a function exported via #[wasm_bindgen] accepts a byte slice (&[u8]) argument, wasm-bindgen generates JavaScript glue code. This glue code automatically allocates space in Wasm linear memory and copies the entire input Uint8Array before the Rust function body executes. This prevents the Rust code from validating the size before the allocation occurs.
Other parts should be straightforward.
transaction.rs: This was straightforward as well. The only nontrvial part is bounding the maximum transaction size length. I set this constant to be the maximum packet size from thesolana-packetcrate.instruction.rs: I changed thesetDatafunction to take in aUint8Arrayinstead of a byte slice.address.rs: This file required the most changes in terms of code lines, but should be straightforward I think.