diff --git a/rust/ares/src/interpreter.rs b/rust/ares/src/interpreter.rs index d2b5a65..8aadfe6 100644 --- a/rust/ares/src/interpreter.rs +++ b/rust/ares/src/interpreter.rs @@ -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::().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 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 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; } diff --git a/rust/ares_guard/c-src/guard.c b/rust/ares_guard/c-src/guard.c index 40f7f99..0357d5a 100644 --- a/rust/ares_guard/c-src/guard.c +++ b/rust/ares_guard/c-src/guard.c @@ -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;