mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-07 03:48:01 +00:00
contracts: Prevent contracts from allocating a too large buffer (#7818)
* Prevent contracts from allocating a too large buffer * Fix possible integer overflow
This commit is contained in:
committed by
GitHub
parent
fd24f66c76
commit
031b4ddabb
@@ -110,6 +110,13 @@ pub struct Limits {
|
||||
pub code_size: u32,
|
||||
}
|
||||
|
||||
impl Limits {
|
||||
/// The maximum memory size in bytes that a contract can occupy.
|
||||
pub fn max_memory_size(&self) -> u32 {
|
||||
self.memory_pages * 64 * 1024
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes the weight for all categories of supported wasm instructions.
|
||||
///
|
||||
/// There there is one field for each wasm instruction that describes the weight to
|
||||
|
||||
@@ -23,10 +23,8 @@ use crate::{
|
||||
gas::{Gas, GasMeter, Token, GasMeterResult, ChargedAmount},
|
||||
wasm::env_def::ConvertibleToWasm,
|
||||
};
|
||||
use sp_sandbox;
|
||||
use parity_wasm::elements::ValueType;
|
||||
use frame_system;
|
||||
use frame_support::dispatch::DispatchError;
|
||||
use frame_support::{dispatch::DispatchError, ensure};
|
||||
use sp_std::prelude::*;
|
||||
use codec::{Decode, DecodeAll, Encode};
|
||||
use sp_runtime::traits::SaturatedConversion;
|
||||
@@ -420,6 +418,7 @@ where
|
||||
pub fn read_sandbox_memory(&self, ptr: u32, len: u32)
|
||||
-> Result<Vec<u8>, DispatchError>
|
||||
{
|
||||
ensure!(len <= self.schedule.limits.max_memory_size(), Error::<E::T>::OutOfBounds);
|
||||
let mut buf = vec![0u8; len as usize];
|
||||
self.memory.get(ptr, buf.as_mut_slice())
|
||||
.map_err(|_| Error::<E::T>::OutOfBounds)?;
|
||||
@@ -1179,17 +1178,23 @@ define_env!(Env, <E: Ext>,
|
||||
let rent_allowance: BalanceOf<<E as Ext>::T> =
|
||||
ctx.read_sandbox_memory_as(rent_allowance_ptr, rent_allowance_len)?;
|
||||
let delta = {
|
||||
const KEY_SIZE: usize = 32;
|
||||
|
||||
// We can eagerly allocate because we charged for the complete delta count already
|
||||
let mut delta = Vec::with_capacity(delta_count as usize);
|
||||
// We still need to make sure that the allocation isn't larger than the memory
|
||||
// allocator can handle.
|
||||
ensure!(
|
||||
delta_count
|
||||
.saturating_mul(KEY_SIZE as u32) <= ctx.schedule.limits.max_memory_size(),
|
||||
Error::<E::T>::OutOfBounds,
|
||||
);
|
||||
let mut delta = vec![[0; KEY_SIZE]; delta_count as usize];
|
||||
let mut key_ptr = delta_ptr;
|
||||
|
||||
for _ in 0..delta_count {
|
||||
const KEY_SIZE: usize = 32;
|
||||
|
||||
// Read the delta into the provided buffer and collect it into the buffer.
|
||||
let mut delta_key: StorageKey = [0; KEY_SIZE];
|
||||
ctx.read_sandbox_memory_into_buf(key_ptr, &mut delta_key)?;
|
||||
delta.push(delta_key);
|
||||
for i in 0..delta_count {
|
||||
// Read the delta into the provided buffer
|
||||
// This cannot panic because of the loop condition
|
||||
ctx.read_sandbox_memory_into_buf(key_ptr, &mut delta[i as usize])?;
|
||||
|
||||
// Offset key_ptr to the next element.
|
||||
key_ptr = key_ptr.checked_add(KEY_SIZE as u32).ok_or(Error::<E::T>::OutOfBounds)?;
|
||||
|
||||
Reference in New Issue
Block a user