Fix memory leak in runtime interface (#4837)

* Fix memory leak in runtime interface

We used `slice::from_raw_parts` in runtime-interface which did not free
the memory afterwards. This pr changes it to `Vec::from_raw_parts` to
make sure `drop` is called properly and the values are freed.

* Check that `len` is non-zero

* Adds comment
This commit is contained in:
Bastian Köcher
2020-02-06 14:26:41 +01:00
committed by GitHub
parent 3c79e6d03c
commit c7867e5125
4 changed files with 68 additions and 12 deletions
@@ -38,9 +38,6 @@ use sp_std::{any::TypeId, mem, vec::Vec};
#[cfg(feature = "std")]
use sp_std::borrow::Cow;
#[cfg(not(feature = "std"))]
use sp_std::{slice, boxed::Box};
// Make sure that our assumptions for storing a pointer + its size in `u64` is valid.
#[cfg(all(not(feature = "std"), not(feature = "disable_target_static_assertions")))]
assert_eq_size!(usize, u32);
@@ -196,11 +193,16 @@ impl<T: 'static + Decode> FromFFIValue for Vec<T> {
let (ptr, len) = unpack_ptr_and_len(arg);
let len = len as usize;
if len == 0 {
return Vec::new();
}
let data = unsafe { Vec::from_raw_parts(ptr as *mut u8, len, len) };
if TypeId::of::<T>() == TypeId::of::<u8>() {
unsafe { mem::transmute(Vec::from_raw_parts(ptr as *mut u8, len, len)) }
unsafe { mem::transmute(data) }
} else {
let slice = unsafe { slice::from_raw_parts(ptr as *const u8, len) };
Self::decode(&mut &slice[..]).expect("Host to wasm values are encoded correctly; qed")
Self::decode(&mut &data[..]).expect("Host to wasm values are encoded correctly; qed")
}
}
}
@@ -302,10 +304,9 @@ macro_rules! impl_traits_for_arrays {
impl FromFFIValue for [u8; $n] {
fn from_ffi_value(arg: u32) -> [u8; $n] {
let mut res = [0u8; $n];
res.copy_from_slice(unsafe { slice::from_raw_parts(arg as *const u8, $n) });
let data = unsafe { Vec::from_raw_parts(arg as *mut u8, $n, $n) };
// Make sure we free the pointer.
let _ = unsafe { Box::from_raw(arg as *mut u8) };
res.copy_from_slice(&data);
res
}