mirror of
https://github.com/urbit/ares.git
synced 2024-11-22 15:08:54 +03:00
guard: boots a baby pill and sigint works too; uses box
This commit is contained in:
parent
a28137d472
commit
a0ddc1f89c
@ -17,6 +17,7 @@ use crate::trace::{write_nock_trace, TraceInfo, TraceStack};
|
||||
use crate::unifying_equality::unifying_equality;
|
||||
use ares_guard::*;
|
||||
use ares_macros::tas;
|
||||
use assert_no_alloc::permit_alloc;
|
||||
use assert_no_alloc::{assert_no_alloc, ensure_alloc_counters};
|
||||
use bitvec::prelude::{BitSlice, Lsb0};
|
||||
use either::*;
|
||||
@ -420,36 +421,27 @@ impl<'closure> CCallback<'closure> {
|
||||
F: FnMut() -> Result,
|
||||
{
|
||||
let cb: &mut F = user_data.cast::<F>().as_mut().unwrap();
|
||||
let mut v = (*cb)();
|
||||
// eprint!("call_closure: v: {:?}\r\n", v);
|
||||
let v_ptr = &mut v as *mut _ as *mut c_void;
|
||||
// eprint!("call_closure: v_ptr: {:p}\r\n", v_ptr);
|
||||
v_ptr
|
||||
let v = (*cb)();
|
||||
permit_alloc(|| {
|
||||
// eprint!("call_closure: v: {:?}\r\n", v);
|
||||
let v_box = Box::new(v);
|
||||
let v_ptr = Box::into_raw(v_box);
|
||||
// let v_ptr = &mut v as *mut _ as *mut c_void;
|
||||
// eprint!("call_closure: v_ptr: {:p}\r\n", v_ptr);
|
||||
v_ptr as *mut c_void
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// fn main() {
|
||||
// let mut v = Vec::new();
|
||||
|
||||
// // must assign to a variable to ensure it lives until the end of scope
|
||||
// let closure = &mut |x: i32| { v.push(x) };
|
||||
// let c = CCallback::new(closure);
|
||||
|
||||
// unsafe { (c.function)(c.user_data, 123) };
|
||||
|
||||
// assert_eq!(v, [123]);
|
||||
// }
|
||||
|
||||
pub fn call_with_guard<F: FnMut() -> Result>(
|
||||
f: &mut F,
|
||||
stack: *const *mut c_void,
|
||||
alloc: *const *mut c_void,
|
||||
) -> Result {
|
||||
let c = CCallback::new(f);
|
||||
let mut result: Result = Ok(D(0));
|
||||
let res_ptr = &mut result as *mut _ as *mut c_void;
|
||||
let res_ptr_ptr = &res_ptr as *const *mut c_void;
|
||||
// eprint!("call_with_guard: before res_ptr: {:p}\r\n", res_ptr);
|
||||
let mut ret: Result = Ok(D(0));
|
||||
let ret_p = &mut ret as *mut _ as *mut c_void;
|
||||
let ret_pp = &ret_p as *const *mut c_void;
|
||||
|
||||
unsafe {
|
||||
let err = guard(
|
||||
@ -457,15 +449,14 @@ pub fn call_with_guard<F: FnMut() -> Result>(
|
||||
c.user_data as *mut c_void,
|
||||
stack,
|
||||
alloc,
|
||||
res_ptr_ptr,
|
||||
ret_pp,
|
||||
);
|
||||
|
||||
// eprint!("call_with_guard: after res_ptr: {:p}\r\n", res_ptr);
|
||||
|
||||
if let Ok(err) = GuardError::try_from(err) {
|
||||
match err {
|
||||
GuardError::GuardSound => {
|
||||
let result = *(res_ptr as *mut Result);
|
||||
let result = *(ret_p as *mut Result);
|
||||
// eprint!("call_with_guard: ret_p: {:p}\r\n", ret_p);
|
||||
// eprint!("call_with_guard: result: {:?}\r\n", result);
|
||||
return result;
|
||||
}
|
||||
|
@ -33,7 +33,8 @@ guard_err _focus_guard()
|
||||
|
||||
// Unmark the old guard page.
|
||||
void *old_guard_p = guard_p;
|
||||
if (old_guard_p != 0 && mprotect(old_guard_p, GD_PAGESIZE, PROT_READ | PROT_WRITE) == -1) {
|
||||
if (old_guard_p != 0
|
||||
&& mprotect(old_guard_p, GD_PAGESIZE, PROT_READ | PROT_WRITE) == -1) {
|
||||
return guard_armor;
|
||||
}
|
||||
|
||||
@ -45,6 +46,7 @@ guard_err _focus_guard()
|
||||
guard_p = stack_p + ((alloc_p - stack_p) / 2);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "guard: weird; stack and alloc pointers are equal\r\n");
|
||||
return guard_weird;
|
||||
}
|
||||
guard_p = (void *)((uintptr_t)guard_p & ~(GD_PAGESIZE - 1));
|
||||
@ -76,7 +78,7 @@ void _signal_handler(int sig, siginfo_t *si, void *unused)
|
||||
{
|
||||
switch (sig) {
|
||||
case SIGSEGV:
|
||||
fprintf(stderr, "guard: sigsegv\r\n");
|
||||
fprintf(stderr, "guard: sigsegv at %p\r\n", si->si_addr);
|
||||
err = _slash_guard(si->si_addr);
|
||||
break;
|
||||
case SIGINT:
|
||||
@ -88,6 +90,7 @@ void _signal_handler(int sig, siginfo_t *si, void *unused)
|
||||
}
|
||||
|
||||
if (err != guard_sound) {
|
||||
fprintf(stderr, "guard: error %d; long jumping\r\n", err);
|
||||
longjmp(env_buffer, 1);
|
||||
}
|
||||
}
|
||||
@ -118,8 +121,8 @@ guard_err guard(
|
||||
stack = (uint64_t**) stack_pp;
|
||||
alloc = (uint64_t**) alloc_pp;
|
||||
|
||||
fprintf(stderr, "guard: stack pointer at %p\r\n", (void *) *stack);
|
||||
fprintf(stderr, "guard: alloc pointer at %p\r\n", (void *) *alloc);
|
||||
// fprintf(stderr, "guard: stack pointer at %p\r\n", (void *) *stack);
|
||||
// fprintf(stderr, "guard: alloc pointer at %p\r\n", (void *) *alloc);
|
||||
|
||||
if (guard_p == 0) {
|
||||
guard_err install_err = _focus_guard();
|
||||
@ -129,7 +132,6 @@ guard_err guard(
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "guard: guard page installed at %p\r\n", (void *) guard_p);
|
||||
|
||||
if (_register_handler() != guard_sound) {
|
||||
err = guard_weird;
|
||||
@ -138,11 +140,9 @@ guard_err guard(
|
||||
|
||||
void *result;
|
||||
if (setjmp(env_buffer) == 0) {
|
||||
fprintf(stderr, "guard: calling f\r\n");
|
||||
result = f(user_data);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "guard: longjmp\r\n");
|
||||
if (err != guard_sound) {
|
||||
goto fail;
|
||||
}
|
||||
@ -150,11 +150,11 @@ guard_err guard(
|
||||
|
||||
*(void **)ret = result;
|
||||
|
||||
if (mprotect(guard_p, GD_PAGESIZE, PROT_READ | PROT_WRITE) == -1) {
|
||||
err = guard_armor;
|
||||
goto fail;
|
||||
}
|
||||
fprintf(stderr, "guard: sound; uninstalled guard page\r\n");
|
||||
// if (mprotect(guard_p, GD_PAGESIZE, PROT_READ | PROT_WRITE) == -1) {
|
||||
// err = guard_armor;
|
||||
// goto fail;
|
||||
// }
|
||||
// fprintf(stderr, "guard: sound; uninstalled guard page\r\n");
|
||||
|
||||
return guard_sound;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user