Skip to content

Commit

Permalink
revive: Limit the amount of static memory a contract can use (#5726)
Browse files Browse the repository at this point in the history
This will make sure that when uploading new code that the declared
static memory fits within a defined limit. We apply different limits to
code and data. Reason is that code will consume much more memory per
byte once decoded during lazy execution.

This PR:

1) Remove the MaxCodeLen from the `Config` to we maintain tight control
over it.
2) Defines a single `STATIC_MEMORY_BYTES` knob that limits the maximum
decoded size.
3) Enforces them only on upload but not on execution so we can raise
them later.
4) Adapt the worst case calculation in `integrity_check`.
5) Bumps the max stack depth from 5 to 10 as this will still fit within
our memory envelope.
6) The memory limit per contract is now a cool 1MB that can be spent on
data or code.
7) Bump PolkaVM for good measure
8) The blob is limited to 256kb which is just a sanity check to not even
try parsing very big inputs.

---------

Co-authored-by: Cyrill Leutwiler <cyrill@parity.io>
  • Loading branch information
athei and xermicus committed Sep 18, 2024
1 parent 08d171e commit 310ef5c
Show file tree
Hide file tree
Showing 15 changed files with 371 additions and 135 deletions.
62 changes: 31 additions & 31 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions prdoc/pr_5726.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
title: "revive: Limit the amount of static memory"

doc:
- audience: Runtime Dev
description: |
Limit the amount of static memory a contract can declare.

crates:
- name: pallet-revive
bump: major
- name: pallet-revive-fixtures
bump: minor
- name: pallet-revive-uapi
bump: patch
1 change: 0 additions & 1 deletion substrate/bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1410,7 +1410,6 @@ impl pallet_revive::Config for Runtime {
type WeightInfo = pallet_revive::weights::SubstrateWeight<Self>;
type ChainExtension = ();
type AddressMapper = pallet_revive::DefaultAddressMapper;
type MaxCodeLen = ConstU32<{ 123 * 1024 }>;
type RuntimeMemory = ConstU32<{ 128 * 1024 * 1024 }>;
type PVFMemory = ConstU32<{ 512 * 1024 * 1024 }>;
type UnsafeUnstableInterface = ConstBool<false>;
Expand Down
2 changes: 1 addition & 1 deletion substrate/frame/revive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ targets = ["x86_64-unknown-linux-gnu"]
[dependencies]
environmental = { workspace = true }
paste = { workspace = true }
polkavm = { version = "0.10.0", default-features = false }
polkavm = { version = "0.11.0", default-features = false }
bitflags = { workspace = true }
codec = { features = [
"derive",
Expand Down
2 changes: 1 addition & 1 deletion substrate/frame/revive/fixtures/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ log = { workspace = true }
parity-wasm = { workspace = true }
tempfile = { workspace = true }
toml = { workspace = true }
polkavm-linker = { version = "0.10.0" }
polkavm-linker = { version = "0.11.0" }
anyhow = { workspace = true, default-features = true }

[features]
Expand Down
2 changes: 1 addition & 1 deletion substrate/frame/revive/fixtures/build/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ edition = "2021"
[dependencies]
uapi = { package = 'pallet-revive-uapi', path = "", default-features = false }
common = { package = 'pallet-revive-fixtures-common', path = "" }
polkavm-derive = { version = "0.10.0" }
polkavm-derive = { version = "0.11.0" }

[profile.release]
opt-level = 3
Expand Down
44 changes: 44 additions & 0 deletions substrate/frame/revive/fixtures/contracts/oom_ro.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// This file is part of Substrate.

// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! This creates a large ro section. Even though it is zero
//! initialized we expect them to be included into the blob.
//! This means it will fail at the blob size check.

#![no_std]
#![no_main]

extern crate common;

use uapi::{HostFn, HostFnImpl as api, ReturnFlags};

static BUFFER: [u8; 1025 * 1024] = [0; 1025 * 1024];

#[no_mangle]
#[polkavm_derive::polkavm_export]
pub extern "C" fn call_never() {
// make sure the buffer is not optimized away
api::return_value(ReturnFlags::empty(), &BUFFER);
}

#[no_mangle]
#[polkavm_derive::polkavm_export]
pub extern "C" fn deploy() {}

#[no_mangle]
#[polkavm_derive::polkavm_export]
pub extern "C" fn call() {}
44 changes: 44 additions & 0 deletions substrate/frame/revive/fixtures/contracts/oom_rw_included.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// This file is part of Substrate.

// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! This creates a large rw section but with its contents
//! included into the blob. It should be rejected for its
//! blob size.

#![no_std]
#![no_main]

extern crate common;

use uapi::{HostFn, HostFnImpl as api, ReturnFlags};

static mut BUFFER: [u8; 513 * 1024] = [42; 513 * 1024];

#[no_mangle]
#[polkavm_derive::polkavm_export]
pub unsafe extern "C" fn call_never() {
// make sure the buffer is not optimized away
api::return_value(ReturnFlags::empty(), &BUFFER);
}

#[no_mangle]
#[polkavm_derive::polkavm_export]
pub extern "C" fn deploy() {}

#[no_mangle]
#[polkavm_derive::polkavm_export]
pub extern "C" fn call() {}
44 changes: 44 additions & 0 deletions substrate/frame/revive/fixtures/contracts/oom_rw_trailing.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// This file is part of Substrate.

// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! This creates a large rw section but the trailing zeroes
//! are removed by the linker. It should be rejected even
//! though the blob is small enough.

#![no_std]
#![no_main]

extern crate common;

use uapi::{HostFn, HostFnImpl as api, ReturnFlags};

static mut BUFFER: [u8; 1025 * 1024] = [0; 1025 * 1024];

#[no_mangle]
#[polkavm_derive::polkavm_export]
pub unsafe extern "C" fn call_never() {
// make sure the buffer is not optimized away
api::return_value(ReturnFlags::empty(), &BUFFER);
}

#[no_mangle]
#[polkavm_derive::polkavm_export]
pub extern "C" fn deploy() {}

#[no_mangle]
#[polkavm_derive::polkavm_export]
pub extern "C" fn call() {}
Loading

0 comments on commit 310ef5c

Please sign in to comment.