Skip to content

Commit

Permalink
Merge pull request #211 from urbit/as/serf-guard
Browse files Browse the repository at this point in the history
guard page / `bail:meme`
  • Loading branch information
matthew-levan authored Feb 21, 2024
2 parents 888e604 + 7316368 commit 30e8a91
Show file tree
Hide file tree
Showing 25 changed files with 2,242 additions and 586 deletions.
Binary file added resources/pills/oom.pill
Binary file not shown.
81 changes: 81 additions & 0 deletions resources/pills/src/oom/oom.hoon
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) ~] ~ ~]
47 changes: 27 additions & 20 deletions rust/ares/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 5 additions & 4 deletions rust/ares/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ edition = "2018"

# Please keep these alphabetized
[dependencies]
ares_guard = { path = "../ares_guard" }
ares_crypto = { path = "../ares_crypto" }
ares_macros = { path = "../ares_macros" }
# Use this when debugging requires the debug printfs in the PMA
# ares_pma = { path = "../ares_pma", features=["debug_prints"] }
ares_pma = { path = "../ares_pma" }
assert_no_alloc = "1.1.2"
# use this when debugging requires allocation (e.g. eprintln)
# assert_no_alloc = {version="1.1.2", features=["warn_debug"]}
# assert_no_alloc = { path = "../rust-assert-no-alloc", features=["warn_debug"] }
assert_no_alloc = { path = "../rust-assert-no-alloc" }
bitvec = "1.0.0"
criterion = "0.4"
either = "1.9.0"
Expand All @@ -35,8 +36,8 @@ signal-hook = "0.3"
static_assertions = "1.1.0"

[build-dependencies]
autotools = "0.2.6"
cc = "1.0.79"
autotools = "0.2"
cc = "1.0"

[[bin]]
name = "ares"
Expand Down
97 changes: 97 additions & 0 deletions rust/ares/src/guard.rs
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);
}
}
}
}
}
Loading

0 comments on commit 30e8a91

Please sign in to comment.