mirror of
https://github.com/fluencelabs/wasmer
synced 2025-04-04 00:31:07 +00:00
Make setjmp/longjmp more secure
This commit is contained in:
parent
e278bd4a29
commit
db93d2693d
@ -1,12 +1,21 @@
|
|||||||
use crate::webassembly::Instance;
|
use crate::webassembly::Instance;
|
||||||
use libc::{c_int, c_void};
|
use libc::{c_int, c_void};
|
||||||
|
use std::cell::UnsafeCell;
|
||||||
|
|
||||||
/// setjmp
|
/// setjmp
|
||||||
pub extern "C" fn __setjmp(env_addr: u32, instance: &mut Instance) -> c_int {
|
pub extern "C" fn __setjmp(env_addr: u32, instance: &mut Instance) -> c_int {
|
||||||
debug!("emscripten::__setjmp (setjmp)");
|
debug!("emscripten::__setjmp (setjmp)");
|
||||||
unsafe {
|
unsafe {
|
||||||
let env = instance.memory_offset_addr(0, env_addr as usize) as *mut c_void;
|
// Rather than using the env as the holder of the jump address,
|
||||||
setjmp(env)
|
// we obscure that id so we are in complete control of it
|
||||||
|
let obscure_env = instance.memory_offset_addr(0, env_addr as usize) as *mut i8;
|
||||||
|
let jmp_buf: UnsafeCell<[c_int; 27]> = UnsafeCell::new([0; 27]);
|
||||||
|
let mut jumps = &mut instance.emscripten_data.as_mut().unwrap().jumps;
|
||||||
|
let result = setjmp(jmp_buf.get() as _);
|
||||||
|
*obscure_env = jumps.len() as _;
|
||||||
|
jumps.push(jmp_buf);
|
||||||
|
// We use the index of the jump as the jump buffer (env)
|
||||||
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -14,8 +23,10 @@ pub extern "C" fn __setjmp(env_addr: u32, instance: &mut Instance) -> c_int {
|
|||||||
pub extern "C" fn __longjmp(env_addr: u32, val: c_int, instance: &mut Instance) -> ! {
|
pub extern "C" fn __longjmp(env_addr: u32, val: c_int, instance: &mut Instance) -> ! {
|
||||||
debug!("emscripten::__longjmp (longjmp) {}", val);
|
debug!("emscripten::__longjmp (longjmp) {}", val);
|
||||||
unsafe {
|
unsafe {
|
||||||
let env = instance.memory_offset_addr(0, env_addr as usize) as *mut c_void;
|
let obscure_env = instance.memory_offset_addr(0, env_addr as usize) as *mut i8;
|
||||||
longjmp(env, val)
|
let mut jumps = &mut instance.emscripten_data.as_mut().unwrap().jumps;
|
||||||
|
let mut real_env = &jumps[*obscure_env as usize];
|
||||||
|
longjmp(real_env.get() as _, val)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,9 @@ use cranelift_wasm::{FuncIndex, GlobalInit};
|
|||||||
use indicatif::{ProgressBar, ProgressStyle};
|
use indicatif::{ProgressBar, ProgressStyle};
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
|
|
||||||
|
use libc::c_int;
|
||||||
use region;
|
use region;
|
||||||
|
use std::cell::UnsafeCell;
|
||||||
use std::iter::FromIterator;
|
use std::iter::FromIterator;
|
||||||
use std::iter::Iterator;
|
use std::iter::Iterator;
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
@ -72,6 +74,7 @@ pub struct EmscriptenData {
|
|||||||
pub memalign: extern "C" fn(u32, u32, &mut Instance) -> u32,
|
pub memalign: extern "C" fn(u32, u32, &mut Instance) -> u32,
|
||||||
pub memset: extern "C" fn(u32, i32, u32, &mut Instance) -> u32,
|
pub memset: extern "C" fn(u32, i32, u32, &mut Instance) -> u32,
|
||||||
pub stack_alloc: extern "C" fn(u32, &Instance) -> u32,
|
pub stack_alloc: extern "C" fn(u32, &Instance) -> u32,
|
||||||
|
pub jumps: Vec<UnsafeCell<[c_int; 27]>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EmscriptenData {
|
impl EmscriptenData {
|
||||||
@ -116,6 +119,7 @@ impl EmscriptenData {
|
|||||||
memalign: mem::transmute(memalign_addr),
|
memalign: mem::transmute(memalign_addr),
|
||||||
memset: mem::transmute(memset_addr),
|
memset: mem::transmute(memset_addr),
|
||||||
stack_alloc: mem::transmute(stack_alloc_addr),
|
stack_alloc: mem::transmute(stack_alloc_addr),
|
||||||
|
jumps: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user