Unverified Commit de70336f authored by Sergey Pepyakin's avatar Sergey Pepyakin Committed by GitHub
Browse files

A simple check to reject obviously wrong validation code binaries (#1989)

* A simple check to reject obviously wrong validation code binaries

* Use wasm-magic constants in the tests.

* tabs not spaces

* move WASM_MAGIC into lib.rs
parent 4a491d34
Pipeline #114552 passed with stages
in 29 minutes and 36 seconds
......@@ -49,6 +49,10 @@ pub use impls::ToAuthor;
pub type NegativeImbalance<T> = <pallet_balances::Module<T> as Currency<<T as frame_system::Trait>::AccountId>>::NegativeImbalance;
/// The sequence of bytes a valid wasm module binary always starts with. Apart from that it's also a
/// valid wasm module.
const WASM_MAGIC: &[u8] = &[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00];
/// We assume that an on-initialize consumes 2.5% of the weight on average, hence a single extrinsic
/// will not be allowed to consume more than `AvailableBlockRatio - 2.5%`.
pub const AVERAGE_ON_INITIALIZE_WEIGHT: Perbill = Perbill::from_perthousand(25);
......
......@@ -17,8 +17,8 @@
//! Module to handle parathread/parachain registration and related fund management.
//! In essence this is a simple wrapper around `paras`.
use crate::WASM_MAGIC;
use sp_std::{prelude::*, result};
use frame_support::{
decl_storage, decl_module, decl_error, ensure,
dispatch::DispatchResult,
......@@ -86,6 +86,8 @@ decl_error! {
HeadDataTooLarge,
/// Parathreads registration is disabled.
ParathreadsRegistrationDisabled,
/// The validation code provided doesn't start with the Wasm file magic string.
DefinitelyNotWasm,
}
}
......@@ -96,7 +98,7 @@ decl_module! {
/// Register a parathread with given code for immediate use.
///
/// Must be sent from a Signed origin that is able to have `ParathreadDeposit` reserved.
/// `gensis_head` and `validation_code` are used to initalize the parathread's state.
/// `genesis_head` and `validation_code` are used to initalize the parathread's state.
#[weight = 0]
fn register_parathread(
origin,
......@@ -107,6 +109,7 @@ decl_module! {
let who = ensure_signed(origin)?;
ensure!(ParathreadsRegistrationEnabled::get(), Error::<T>::ParathreadsRegistrationDisabled);
ensure!(validation_code.0.starts_with(WASM_MAGIC), Error::<T>::DefinitelyNotWasm);
ensure!(!Paras::contains_key(id), Error::<T>::ParaAlreadyExists);
......@@ -217,6 +220,7 @@ impl<T: Trait> Module<T> {
validation_code: ValidationCode,
) -> DispatchResult {
ensure!(!Paras::contains_key(id), Error::<T>::ParaAlreadyExists);
ensure!(validation_code.0.starts_with(WASM_MAGIC), Error::<T>::DefinitelyNotWasm);
let outgoing = <paras::Module<T>>::outgoing_paras();
......@@ -609,7 +613,7 @@ mod tests {
assert_ok!(Registrar::register_parachain(
2u32.into(),
vec![3; 3].into(),
vec![3; 3].into(),
WASM_MAGIC.to_vec().into(),
));
let orig_bal = Balances::free_balance(&3u64);
......@@ -619,7 +623,7 @@ mod tests {
Origin::signed(3u64),
8u32.into(),
vec![3; 3].into(),
vec![3; 3].into(),
WASM_MAGIC.to_vec().into(),
));
// deposit should be taken (reserved)
......@@ -658,13 +662,13 @@ mod tests {
Origin::signed(1),
8u32.into(),
vec![1; 3].into(),
vec![1; 3].into(),
WASM_MAGIC.to_vec().into(),
));
assert_ok!(Registrar::register_parachain(
2u32.into(),
vec![1; 3].into(),
vec![1; 3].into(),
WASM_MAGIC.to_vec().into(),
));
run_to_block(9);
......@@ -692,7 +696,7 @@ mod tests {
assert_ok!(Registrar::register_parachain(
1u32.into(),
vec![1; 3].into(),
vec![1; 3].into(),
WASM_MAGIC.to_vec().into(),
));
run_to_block(4);
......@@ -703,7 +707,7 @@ mod tests {
assert!(Registrar::register_parachain(
1u32.into(),
vec![1; 3].into(),
vec![1; 3].into(),
WASM_MAGIC.to_vec().into(),
).is_err());
run_to_block(6);
......@@ -711,7 +715,7 @@ mod tests {
assert_ok!(Registrar::register_parachain(
1u32.into(),
vec![1; 3].into(),
vec![1; 3].into(),
WASM_MAGIC.to_vec().into(),
));
});
}
......
......@@ -16,6 +16,7 @@
//! A simple wrapper allowing `Sudo` to call into `paras` routines.
use crate::WASM_MAGIC;
use sp_std::prelude::*;
use frame_support::{
decl_error, decl_module, ensure,
......@@ -41,6 +42,8 @@ decl_error! {
/// A DMP message couldn't be sent because it exceeds the maximum size allowed for a downward
/// message.
ExceedsMaxMessageSize,
/// The validation code provided doesn't start with the Wasm file magic string.
DefinitelyNotWasm,
}
}
......@@ -57,6 +60,7 @@ decl_module! {
genesis: ParaGenesisArgs,
) -> DispatchResult {
ensure_root(origin)?;
ensure!(genesis.validation_code.0.starts_with(WASM_MAGIC), Error::<T>::DefinitelyNotWasm);
runtime_parachains::schedule_para_initialize::<T>(id, genesis);
Ok(())
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment