guard: boots a baby pill and sigint works too; uses box

This commit is contained in:
Matthew LeVan 2024-01-24 13:24:48 -05:00
parent a28137d472
commit a0ddc1f89c
2 changed files with 28 additions and 37 deletions

View File

@ -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;
}

View File

@ -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;