-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #211 from urbit/as/serf-guard
guard page / `bail:meme`
- Loading branch information
Showing
25 changed files
with
2,242 additions
and
586 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
:: A working pill designed to force bail:meme OOM errors. Requires | ||
:: playpen.hoon, originally used by the toddler pill. | ||
:: | ||
/+ playpen | ||
!. | ||
=/ core | ||
=> playpen | ||
!= | ||
=> | ||
|% | ||
+$ card (cask) | ||
++ cask |$ [a] (pair mark a) | ||
+$ goof [mote=term =tang] | ||
+$ mark @tas | ||
+$ ovum [=wire =card] | ||
+$ vere [[non=@ta rev=path] kel=wynn] | ||
+$ wire path | ||
+$ wasp | ||
:: %crud: reroute $ovum with $goof | ||
:: %wack: iterate entropy | ||
:: %wyrd: check/record runtime kelvin stack | ||
:: | ||
$% [%crud =goof =ovum] | ||
[%wack p=@uvJ] | ||
[%wyrd p=vere] | ||
== | ||
+$ weft [lal=@tas num=@ud] | ||
+$ wynn (list weft) | ||
-- => | ||
:: | ||
=| counter=@u | ||
|% | ||
++ load !! | ||
++ peek _~ | ||
++ wish !! | ||
++ poke | ||
|= [now=@da ovo=ovum] | ||
^- ^ | ||
:: | ||
?. ?=(?(%crud %wack %wyrd) p.card.ovo) | ||
?: (gte counter 20) | ||
~> %slog.[0 %leaf .=(~ =|(i=@ |-(?:(=(i ^~((bex 32))) ~ [i $(i +(i))])))) 0] | ||
[~ ..poke] | ||
~> %slog.[0 leaf+(scow %ud counter)] | ||
=. counter +(counter) | ||
[~ ..poke] | ||
:: | ||
=/ buz | ||
~> %mean.'pith: bad wasp' | ||
;;(wasp card.ovo) | ||
?+ -.buz | ||
~> %slog.[0 leaf+"%wack / %wyrd"] | ||
[~ ..poke] | ||
:: | ||
%crud | ||
=/ tang tang.goof.buz | ||
|- | ||
?~ tang | ||
[~ ..poke] | ||
~> %slog.[0 -.tang] | ||
$(tang +.tang) | ||
== | ||
-- | ||
:: | ||
|= [now=@da ovo=ovum] | ||
^- * | ||
.(+> +:(poke now ovo)) | ||
:: | ||
|% | ||
++ aeon | ||
^- * | ||
=> *[arvo=* epic=*] | ||
!= | ||
|- ^- * | ||
?@ epic arvo | ||
%= $ | ||
epic +.epic | ||
arvo .*([arvo -.epic] [%9 2 %10 [6 %0 3] %0 2]) | ||
== | ||
-- | ||
[%pill %toddler [aeon .*(playpen core) ~] ~ ~] |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
use crate::interpreter::{Error, Mote, Result}; | ||
use crate::noun::D; | ||
use ares_guard::*; | ||
use assert_no_alloc::permit_alloc; | ||
use std::ffi::c_void; | ||
use std::marker::PhantomData; | ||
|
||
#[derive(Debug)] | ||
pub enum GuardError { | ||
MemoryProtection, | ||
NullPointer, | ||
OutOfMemory, | ||
Setup, | ||
Unknown, | ||
} | ||
|
||
impl From<u32> for GuardError { | ||
fn from(value: u32) -> Self { | ||
match value { | ||
GUARD_NULL => Self::NullPointer, | ||
GUARD_OOM => Self::OutOfMemory, | ||
x if (x & GUARD_MPROTECT) != 0 => Self::MemoryProtection, | ||
x if (x & (GUARD_MALLOC | GUARD_SIGACTION)) != 0 => Self::Setup, | ||
_ => Self::Unknown, | ||
} | ||
} | ||
} | ||
|
||
pub struct CCallback<'closure> { | ||
pub function: unsafe extern "C" fn(*mut c_void) -> *mut c_void, | ||
pub input: *mut c_void, | ||
// without this it's too easy to accidentally drop the closure too soon | ||
_lifetime: PhantomData<&'closure mut c_void>, | ||
} | ||
|
||
impl<'closure> CCallback<'closure> { | ||
pub fn new<F>(closure: &'closure mut F) -> Self | ||
where | ||
F: FnMut() -> Result, | ||
{ | ||
let function: unsafe extern "C" fn(*mut c_void) -> *mut c_void = Self::call_closure::<F>; | ||
|
||
Self { | ||
function, | ||
input: closure as *mut F as *mut c_void, | ||
_lifetime: PhantomData, | ||
} | ||
} | ||
|
||
unsafe extern "C" fn call_closure<F>(input: *mut c_void) -> *mut c_void | ||
where | ||
F: FnMut() -> Result, | ||
{ | ||
let cb: &mut F = input.cast::<F>().as_mut().unwrap(); | ||
let v = (*cb)(); | ||
permit_alloc(|| { | ||
let v_box = Box::new(v); | ||
let v_ptr = Box::into_raw(v_box); | ||
v_ptr as *mut c_void | ||
}) | ||
} | ||
} | ||
|
||
pub fn call_with_guard<F: FnMut() -> Result>( | ||
stack_pp: *const *const u64, | ||
alloc_pp: *const *const u64, | ||
closure: &mut F, | ||
) -> Result { | ||
let cb = CCallback::new(closure); | ||
let mut ret_p: *mut c_void = std::ptr::null_mut(); | ||
let ret_pp = &mut ret_p as *mut *mut c_void; | ||
|
||
unsafe { | ||
let res = guard( | ||
Some(cb.function as unsafe extern "C" fn(*mut c_void) -> *mut c_void), | ||
cb.input, | ||
stack_pp as *const usize, | ||
alloc_pp as *const usize, | ||
ret_pp, | ||
); | ||
|
||
if res == 0 { | ||
permit_alloc(|| { | ||
let result_box = Box::from_raw(ret_p as *mut Result); | ||
*result_box | ||
}) | ||
} else { | ||
let err = GuardError::from(res); | ||
match err { | ||
GuardError::OutOfMemory => Err(Error::NonDeterministic(Mote::Meme, D(0))), | ||
_ => { | ||
panic!("serf: guard: unexpected error {:?} {}", err, res); | ||
} | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.