mirror of
https://github.com/urbit/ares.git
synced 2024-11-26 20:58:02 +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 crate::unifying_equality::unifying_equality;
|
||||||
use ares_guard::*;
|
use ares_guard::*;
|
||||||
use ares_macros::tas;
|
use ares_macros::tas;
|
||||||
|
use assert_no_alloc::permit_alloc;
|
||||||
use assert_no_alloc::{assert_no_alloc, ensure_alloc_counters};
|
use assert_no_alloc::{assert_no_alloc, ensure_alloc_counters};
|
||||||
use bitvec::prelude::{BitSlice, Lsb0};
|
use bitvec::prelude::{BitSlice, Lsb0};
|
||||||
use either::*;
|
use either::*;
|
||||||
@ -420,36 +421,27 @@ impl<'closure> CCallback<'closure> {
|
|||||||
F: FnMut() -> Result,
|
F: FnMut() -> Result,
|
||||||
{
|
{
|
||||||
let cb: &mut F = user_data.cast::<F>().as_mut().unwrap();
|
let cb: &mut F = user_data.cast::<F>().as_mut().unwrap();
|
||||||
let mut v = (*cb)();
|
let v = (*cb)();
|
||||||
// eprint!("call_closure: v: {:?}\r\n", v);
|
permit_alloc(|| {
|
||||||
let v_ptr = &mut v as *mut _ as *mut c_void;
|
// eprint!("call_closure: v: {:?}\r\n", v);
|
||||||
// eprint!("call_closure: v_ptr: {:p}\r\n", v_ptr);
|
let v_box = Box::new(v);
|
||||||
v_ptr
|
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>(
|
pub fn call_with_guard<F: FnMut() -> Result>(
|
||||||
f: &mut F,
|
f: &mut F,
|
||||||
stack: *const *mut c_void,
|
stack: *const *mut c_void,
|
||||||
alloc: *const *mut c_void,
|
alloc: *const *mut c_void,
|
||||||
) -> Result {
|
) -> Result {
|
||||||
let c = CCallback::new(f);
|
let c = CCallback::new(f);
|
||||||
let mut result: Result = Ok(D(0));
|
let mut ret: Result = Ok(D(0));
|
||||||
let res_ptr = &mut result as *mut _ as *mut c_void;
|
let ret_p = &mut ret as *mut _ as *mut c_void;
|
||||||
let res_ptr_ptr = &res_ptr as *const *mut c_void;
|
let ret_pp = &ret_p as *const *mut c_void;
|
||||||
// eprint!("call_with_guard: before res_ptr: {:p}\r\n", res_ptr);
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let err = guard(
|
let err = guard(
|
||||||
@ -457,15 +449,14 @@ pub fn call_with_guard<F: FnMut() -> Result>(
|
|||||||
c.user_data as *mut c_void,
|
c.user_data as *mut c_void,
|
||||||
stack,
|
stack,
|
||||||
alloc,
|
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) {
|
if let Ok(err) = GuardError::try_from(err) {
|
||||||
match err {
|
match err {
|
||||||
GuardError::GuardSound => {
|
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);
|
// eprint!("call_with_guard: result: {:?}\r\n", result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,8 @@ guard_err _focus_guard()
|
|||||||
|
|
||||||
// Unmark the old guard page.
|
// Unmark the old guard page.
|
||||||
void *old_guard_p = guard_p;
|
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;
|
return guard_armor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,6 +46,7 @@ guard_err _focus_guard()
|
|||||||
guard_p = stack_p + ((alloc_p - stack_p) / 2);
|
guard_p = stack_p + ((alloc_p - stack_p) / 2);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
fprintf(stderr, "guard: weird; stack and alloc pointers are equal\r\n");
|
||||||
return guard_weird;
|
return guard_weird;
|
||||||
}
|
}
|
||||||
guard_p = (void *)((uintptr_t)guard_p & ~(GD_PAGESIZE - 1));
|
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) {
|
switch (sig) {
|
||||||
case SIGSEGV:
|
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);
|
err = _slash_guard(si->si_addr);
|
||||||
break;
|
break;
|
||||||
case SIGINT:
|
case SIGINT:
|
||||||
@ -88,6 +90,7 @@ void _signal_handler(int sig, siginfo_t *si, void *unused)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (err != guard_sound) {
|
if (err != guard_sound) {
|
||||||
|
fprintf(stderr, "guard: error %d; long jumping\r\n", err);
|
||||||
longjmp(env_buffer, 1);
|
longjmp(env_buffer, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -118,8 +121,8 @@ guard_err guard(
|
|||||||
stack = (uint64_t**) stack_pp;
|
stack = (uint64_t**) stack_pp;
|
||||||
alloc = (uint64_t**) alloc_pp;
|
alloc = (uint64_t**) alloc_pp;
|
||||||
|
|
||||||
fprintf(stderr, "guard: stack pointer at %p\r\n", (void *) *stack);
|
// 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: alloc pointer at %p\r\n", (void *) *alloc);
|
||||||
|
|
||||||
if (guard_p == 0) {
|
if (guard_p == 0) {
|
||||||
guard_err install_err = _focus_guard();
|
guard_err install_err = _focus_guard();
|
||||||
@ -129,7 +132,6 @@ guard_err guard(
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fprintf(stderr, "guard: guard page installed at %p\r\n", (void *) guard_p);
|
|
||||||
|
|
||||||
if (_register_handler() != guard_sound) {
|
if (_register_handler() != guard_sound) {
|
||||||
err = guard_weird;
|
err = guard_weird;
|
||||||
@ -138,11 +140,9 @@ guard_err guard(
|
|||||||
|
|
||||||
void *result;
|
void *result;
|
||||||
if (setjmp(env_buffer) == 0) {
|
if (setjmp(env_buffer) == 0) {
|
||||||
fprintf(stderr, "guard: calling f\r\n");
|
|
||||||
result = f(user_data);
|
result = f(user_data);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "guard: longjmp\r\n");
|
|
||||||
if (err != guard_sound) {
|
if (err != guard_sound) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@ -150,11 +150,11 @@ guard_err guard(
|
|||||||
|
|
||||||
*(void **)ret = result;
|
*(void **)ret = result;
|
||||||
|
|
||||||
if (mprotect(guard_p, GD_PAGESIZE, PROT_READ | PROT_WRITE) == -1) {
|
// if (mprotect(guard_p, GD_PAGESIZE, PROT_READ | PROT_WRITE) == -1) {
|
||||||
err = guard_armor;
|
// err = guard_armor;
|
||||||
goto fail;
|
// goto fail;
|
||||||
}
|
// }
|
||||||
fprintf(stderr, "guard: sound; uninstalled guard page\r\n");
|
// fprintf(stderr, "guard: sound; uninstalled guard page\r\n");
|
||||||
|
|
||||||
return guard_sound;
|
return guard_sound;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user