mirror of
https://github.com/fluencelabs/wasmer
synced 2025-03-16 08:10:49 +00:00
Add bounds checking for memory accesses on dynamic memories
This commit is contained in:
parent
87c453a0ec
commit
ae3b2b2a42
@ -21,7 +21,7 @@ use wasmparser::{
|
||||
BinaryReaderError, CodeSectionReader, LocalsReader, MemoryImmediate, Operator, OperatorsReader,
|
||||
};
|
||||
|
||||
use crate::intrinsics::{CtxType, GlobalCache, Intrinsics};
|
||||
use crate::intrinsics::{CtxType, GlobalCache, Intrinsics, MemoryCache};
|
||||
use crate::read_info::type_to_type;
|
||||
use crate::state::{ControlFrame, IfElseState, State};
|
||||
use crate::trampolines::generate_trampolines;
|
||||
@ -1571,6 +1571,8 @@ fn parse_function(
|
||||
let effective_address = resolve_memory_ptr(
|
||||
builder,
|
||||
intrinsics,
|
||||
context,
|
||||
&function,
|
||||
&mut state,
|
||||
&mut ctx,
|
||||
memarg,
|
||||
@ -1583,6 +1585,8 @@ fn parse_function(
|
||||
let effective_address = resolve_memory_ptr(
|
||||
builder,
|
||||
intrinsics,
|
||||
context,
|
||||
&function,
|
||||
&mut state,
|
||||
&mut ctx,
|
||||
memarg,
|
||||
@ -1595,6 +1599,8 @@ fn parse_function(
|
||||
let effective_address = resolve_memory_ptr(
|
||||
builder,
|
||||
intrinsics,
|
||||
context,
|
||||
&function,
|
||||
&mut state,
|
||||
&mut ctx,
|
||||
memarg,
|
||||
@ -1607,6 +1613,8 @@ fn parse_function(
|
||||
let effective_address = resolve_memory_ptr(
|
||||
builder,
|
||||
intrinsics,
|
||||
context,
|
||||
&function,
|
||||
&mut state,
|
||||
&mut ctx,
|
||||
memarg,
|
||||
@ -1621,6 +1629,8 @@ fn parse_function(
|
||||
let effective_address = resolve_memory_ptr(
|
||||
builder,
|
||||
intrinsics,
|
||||
context,
|
||||
&function,
|
||||
&mut state,
|
||||
&mut ctx,
|
||||
memarg,
|
||||
@ -1633,6 +1643,8 @@ fn parse_function(
|
||||
let effective_address = resolve_memory_ptr(
|
||||
builder,
|
||||
intrinsics,
|
||||
context,
|
||||
&function,
|
||||
&mut state,
|
||||
&mut ctx,
|
||||
memarg,
|
||||
@ -1645,6 +1657,8 @@ fn parse_function(
|
||||
let effective_address = resolve_memory_ptr(
|
||||
builder,
|
||||
intrinsics,
|
||||
context,
|
||||
&function,
|
||||
&mut state,
|
||||
&mut ctx,
|
||||
memarg,
|
||||
@ -1657,6 +1671,8 @@ fn parse_function(
|
||||
let effective_address = resolve_memory_ptr(
|
||||
builder,
|
||||
intrinsics,
|
||||
context,
|
||||
&function,
|
||||
&mut state,
|
||||
&mut ctx,
|
||||
memarg,
|
||||
@ -1669,6 +1685,8 @@ fn parse_function(
|
||||
let effective_address = resolve_memory_ptr(
|
||||
builder,
|
||||
intrinsics,
|
||||
context,
|
||||
&function,
|
||||
&mut state,
|
||||
&mut ctx,
|
||||
memarg,
|
||||
@ -1685,6 +1703,8 @@ fn parse_function(
|
||||
let effective_address = resolve_memory_ptr(
|
||||
builder,
|
||||
intrinsics,
|
||||
context,
|
||||
&function,
|
||||
&mut state,
|
||||
&mut ctx,
|
||||
memarg,
|
||||
@ -1701,6 +1721,8 @@ fn parse_function(
|
||||
let effective_address = resolve_memory_ptr(
|
||||
builder,
|
||||
intrinsics,
|
||||
context,
|
||||
&function,
|
||||
&mut state,
|
||||
&mut ctx,
|
||||
memarg,
|
||||
@ -1717,6 +1739,8 @@ fn parse_function(
|
||||
let effective_address = resolve_memory_ptr(
|
||||
builder,
|
||||
intrinsics,
|
||||
context,
|
||||
&function,
|
||||
&mut state,
|
||||
&mut ctx,
|
||||
memarg,
|
||||
@ -1733,6 +1757,8 @@ fn parse_function(
|
||||
let effective_address = resolve_memory_ptr(
|
||||
builder,
|
||||
intrinsics,
|
||||
context,
|
||||
&function,
|
||||
&mut state,
|
||||
&mut ctx,
|
||||
memarg,
|
||||
@ -1750,6 +1776,8 @@ fn parse_function(
|
||||
let effective_address = resolve_memory_ptr(
|
||||
builder,
|
||||
intrinsics,
|
||||
context,
|
||||
&function,
|
||||
&mut state,
|
||||
&mut ctx,
|
||||
memarg,
|
||||
@ -1766,6 +1794,8 @@ fn parse_function(
|
||||
let effective_address = resolve_memory_ptr(
|
||||
builder,
|
||||
intrinsics,
|
||||
context,
|
||||
&function,
|
||||
&mut state,
|
||||
&mut ctx,
|
||||
memarg,
|
||||
@ -1782,6 +1812,8 @@ fn parse_function(
|
||||
let effective_address = resolve_memory_ptr(
|
||||
builder,
|
||||
intrinsics,
|
||||
context,
|
||||
&function,
|
||||
&mut state,
|
||||
&mut ctx,
|
||||
memarg,
|
||||
@ -1798,6 +1830,8 @@ fn parse_function(
|
||||
let effective_address = resolve_memory_ptr(
|
||||
builder,
|
||||
intrinsics,
|
||||
context,
|
||||
&function,
|
||||
&mut state,
|
||||
&mut ctx,
|
||||
memarg,
|
||||
@ -1814,6 +1848,8 @@ fn parse_function(
|
||||
let effective_address = resolve_memory_ptr(
|
||||
builder,
|
||||
intrinsics,
|
||||
context,
|
||||
&function,
|
||||
&mut state,
|
||||
&mut ctx,
|
||||
memarg,
|
||||
@ -1832,6 +1868,8 @@ fn parse_function(
|
||||
let effective_address = resolve_memory_ptr(
|
||||
builder,
|
||||
intrinsics,
|
||||
context,
|
||||
&function,
|
||||
&mut state,
|
||||
&mut ctx,
|
||||
memarg,
|
||||
@ -1846,6 +1884,8 @@ fn parse_function(
|
||||
let effective_address = resolve_memory_ptr(
|
||||
builder,
|
||||
intrinsics,
|
||||
context,
|
||||
&function,
|
||||
&mut state,
|
||||
&mut ctx,
|
||||
memarg,
|
||||
@ -1860,6 +1900,8 @@ fn parse_function(
|
||||
let effective_address = resolve_memory_ptr(
|
||||
builder,
|
||||
intrinsics,
|
||||
context,
|
||||
&function,
|
||||
&mut state,
|
||||
&mut ctx,
|
||||
memarg,
|
||||
@ -1964,6 +2006,8 @@ fn parse_function(
|
||||
fn resolve_memory_ptr(
|
||||
builder: &Builder,
|
||||
intrinsics: &Intrinsics,
|
||||
context: &Context,
|
||||
function: &FunctionValue,
|
||||
state: &mut State,
|
||||
ctx: &mut CtxType,
|
||||
memarg: MemoryImmediate,
|
||||
@ -1975,8 +2019,62 @@ fn resolve_memory_ptr(
|
||||
let var_offset =
|
||||
builder.build_int_z_extend(var_offset_i32, intrinsics.i64_ty, &state.var_name());
|
||||
let effective_offset = builder.build_int_add(var_offset, imm_offset, &state.var_name());
|
||||
let (mem_base, mem_bound) = ctx.memory(MemoryIndex::new(0));
|
||||
let mem_base_int = builder.build_ptr_to_int(mem_base, intrinsics.i64_ty, &state.var_name());
|
||||
let memory_cache = ctx.memory(MemoryIndex::new(0));
|
||||
|
||||
let mem_base_int = match memory_cache {
|
||||
MemoryCache::Dynamic {
|
||||
ptr_to_base_ptr,
|
||||
ptr_to_bounds,
|
||||
} => {
|
||||
let base = builder
|
||||
.build_load(ptr_to_base_ptr, "base")
|
||||
.into_pointer_value();
|
||||
let bounds = builder.build_load(ptr_to_bounds, "bounds").into_int_value();
|
||||
|
||||
let base_as_int = builder.build_ptr_to_int(base, intrinsics.i64_ty, "base_as_int");
|
||||
|
||||
let base_in_bounds =
|
||||
builder.build_int_compare(IntPredicate::ULT, base_as_int, bounds, "base_in_bounds");
|
||||
|
||||
let base_in_bounds = builder
|
||||
.build_call(
|
||||
intrinsics.expect_i1,
|
||||
&[
|
||||
base_in_bounds.as_basic_value_enum(),
|
||||
intrinsics.i1_ty.const_int(1, false).as_basic_value_enum(),
|
||||
],
|
||||
"base_in_bounds_expect",
|
||||
)
|
||||
.try_as_basic_value()
|
||||
.left()
|
||||
.unwrap()
|
||||
.into_int_value();
|
||||
|
||||
let in_bounds_continue_block =
|
||||
context.append_basic_block(function, "in_bounds_continue_block");
|
||||
let not_in_bounds_block = context.append_basic_block(function, "not_in_bounds_block");
|
||||
builder.build_conditional_branch(
|
||||
base_in_bounds,
|
||||
&in_bounds_continue_block,
|
||||
¬_in_bounds_block,
|
||||
);
|
||||
builder.position_at_end(¬_in_bounds_block);
|
||||
builder.build_call(
|
||||
intrinsics.throw_trap,
|
||||
&[intrinsics.trap_memory_oob],
|
||||
"throw",
|
||||
);
|
||||
builder.build_unreachable();
|
||||
builder.position_at_end(&in_bounds_continue_block);
|
||||
|
||||
base_as_int
|
||||
}
|
||||
MemoryCache::Static {
|
||||
base_ptr,
|
||||
bounds: _,
|
||||
} => builder.build_ptr_to_int(base_ptr, intrinsics.i64_ty, "base_as_int"),
|
||||
};
|
||||
|
||||
let effective_address_int =
|
||||
builder.build_int_add(mem_base_int, effective_offset, &state.var_name());
|
||||
Ok(builder.build_int_to_ptr(effective_address_int, ptr_ty, &state.var_name()))
|
||||
|
@ -398,7 +398,8 @@ impl Intrinsics {
|
||||
}
|
||||
}
|
||||
|
||||
enum MemoryCache {
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum MemoryCache {
|
||||
/// The memory moves around.
|
||||
Dynamic {
|
||||
ptr_to_base_ptr: PointerValue,
|
||||
@ -452,7 +453,7 @@ impl<'a> CtxType<'a> {
|
||||
self.ctx_ptr_value.as_basic_value_enum()
|
||||
}
|
||||
|
||||
pub fn memory(&mut self, index: MemoryIndex) -> (PointerValue, IntValue) {
|
||||
pub fn memory(&mut self, index: MemoryIndex) -> MemoryCache {
|
||||
let (cached_memories, builder, info, ctx_ptr_value, intrinsics, cache_builder) = (
|
||||
&mut self.cached_memories,
|
||||
self.builder,
|
||||
@ -462,7 +463,7 @@ impl<'a> CtxType<'a> {
|
||||
&self.cache_builder,
|
||||
);
|
||||
|
||||
let memory_cache = cached_memories.entry(index).or_insert_with(|| {
|
||||
*cached_memories.entry(index).or_insert_with(|| {
|
||||
let (memory_array_ptr_ptr, index, memory_type) = match index.local_or_import(info) {
|
||||
LocalOrImport::Local(local_mem_index) => (
|
||||
unsafe {
|
||||
@ -516,24 +517,7 @@ impl<'a> CtxType<'a> {
|
||||
.into_int_value(),
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
match memory_cache {
|
||||
MemoryCache::Dynamic {
|
||||
ptr_to_base_ptr,
|
||||
ptr_to_bounds,
|
||||
} => {
|
||||
let base = builder
|
||||
.build_load(*ptr_to_base_ptr, "base")
|
||||
.into_pointer_value();
|
||||
let bounds = builder
|
||||
.build_load(*ptr_to_bounds, "bounds")
|
||||
.into_int_value();
|
||||
|
||||
(base, bounds)
|
||||
}
|
||||
MemoryCache::Static { base_ptr, bounds } => (*base_ptr, *bounds),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn table(&mut self, index: TableIndex) -> (PointerValue, IntValue) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user