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 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)();
permit_alloc(|| {
// eprint!("call_closure: v: {:?}\r\n", v); // eprint!("call_closure: v: {:?}\r\n", v);
let v_ptr = &mut v as *mut _ as *mut c_void; 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); // eprint!("call_closure: v_ptr: {:p}\r\n", v_ptr);
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;
} }

View File

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