From 1886760ebab777007d061303eacc7aa4307570f1 Mon Sep 17 00:00:00 2001 From: Brandon Fish Date: Mon, 19 Aug 2019 09:45:14 -0500 Subject: [PATCH] Fix issue with emscripten memory out of range --- lib/emscripten/src/lib.rs | 13 +++++++++--- lib/emscripten/src/utils.rs | 40 ++++++++++++++++++++++++++----------- 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/lib/emscripten/src/lib.rs b/lib/emscripten/src/lib.rs index 2f03dbb3b..c09f9b772 100644 --- a/lib/emscripten/src/lib.rs +++ b/lib/emscripten/src/lib.rs @@ -405,11 +405,18 @@ fn store_module_arguments(ctx: &mut Ctx, args: Vec<&str>) -> (u32, u32) { (argc as u32 - 1, argv_offset) } -pub fn emscripten_set_up_memory(memory: &Memory, globals: &EmscriptenGlobalsData) { +pub fn emscripten_set_up_memory( + memory: &Memory, + globals: &EmscriptenGlobalsData, +) -> Result<(), String> { let dynamictop_ptr = globals.dynamictop_ptr; let dynamic_base = globals.dynamic_base; + if (dynamictop_ptr / 4) as usize >= memory.view::().len() { + return Err("dynamictop_ptr beyond memory len".to_string()); + } memory.view::()[(dynamictop_ptr / 4) as usize].set(dynamic_base); + Ok(()) } pub struct EmscriptenGlobalsData { @@ -489,7 +496,7 @@ impl EmscriptenGlobals { static_top += 16; let (dynamic_base, dynamictop_ptr) = - get_emscripten_metadata(&module).unwrap_or_else(|| { + get_emscripten_metadata(&module)?.unwrap_or_else(|| { let dynamictop_ptr = static_alloc(&mut static_top, 4); ( align_memory(align_memory(static_top) + TOTAL_STACK), @@ -513,7 +520,7 @@ impl EmscriptenGlobals { } }; - emscripten_set_up_memory(&memory, &data); + emscripten_set_up_memory(&memory, &data)?; let mut null_func_names = vec![]; for ( diff --git a/lib/emscripten/src/utils.rs b/lib/emscripten/src/utils.rs index 246cd1686..57d26f24e 100644 --- a/lib/emscripten/src/utils.rs +++ b/lib/emscripten/src/utils.rs @@ -53,15 +53,23 @@ pub fn get_emscripten_memory_size(module: &Module) -> Result<(Pages, Option Option<(u32, u32)> { - let max_idx = &module.info().globals.iter().map(|(k, _)| k).max()?; - let snd_max_idx = &module +pub fn get_emscripten_metadata(module: &Module) -> Result, String> { + let max_idx = match module.info().globals.iter().map(|(k, _)| k).max() { + Some(x) => x, + None => return Ok(None), + }; + + let snd_max_idx = match module .info() .globals .iter() .map(|(k, _)| k) - .filter(|k| k != max_idx) - .max()?; + .filter(|k| *k != max_idx) + .max() + { + Some(x) => x, + None => return Ok(None), + }; use wasmer_runtime_core::types::{GlobalInit, Initializer::Const, Value::I32}; if let ( @@ -74,15 +82,23 @@ pub fn get_emscripten_metadata(module: &Module) -> Option<(u32, u32)> { .. }, ) = ( - &module.info().globals[*max_idx], - &module.info().globals[*snd_max_idx], + &module.info().globals[max_idx], + &module.info().globals[snd_max_idx], ) { - Some(( - align_memory(*dynamic_base as u32 - 32), - align_memory(*dynamictop_ptr as u32 - 32), - )) + let dynamic_base = (*dynamic_base as u32).checked_sub(32).ok_or(format!( + "emscripten unexpected dynamic_base {}", + *dynamic_base as u32 + ))?; + let dynamictop_ptr = (*dynamictop_ptr as u32).checked_sub(32).ok_or(format!( + "emscripten unexpected dynamictop_ptr {}", + *dynamictop_ptr as u32 + ))?; + Ok(Some(( + align_memory(dynamic_base), + align_memory(dynamictop_ptr), + ))) } else { - None + Ok(None) } }