Skip to content

Commit

Permalink
Initial monitor state management overhaul (#196)
Browse files Browse the repository at this point in the history
* Monitor setup and stubbing.

* Add lock_api to Cargo.toml.
  • Loading branch information
dbittman authored Aug 20, 2024
1 parent 66a561f commit 6380071
Show file tree
Hide file tree
Showing 17 changed files with 651 additions and 14 deletions.
55 changes: 47 additions & 8 deletions Cargo.lock

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

5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ initrd = [
"crate:netmgr",
"crate:nettest",
"crate:pager",
"lib:twz-rt",
"lib:monitor",
"crate:mnemosyne",
"crate:stdfs_demo",
#"lib:twz-rt",
#"lib:monitor",
#"third-party:hello-world-rs"
]

Expand All @@ -64,3 +64,4 @@ async-executor = { git = "https://github.com/twizzler-operating-system/async-exe
twizzler-futures = { path = "src/lib/twizzler-futures" }
twizzler-abi = { path = "src/lib/twizzler-abi" }
parking_lot = { git = "https://github.com/twizzler-operating-system/parking_lot.git", branch = "twizzler" }
lock_api = { git = "https://github.com/twizzler-operating-system/parking_lot.git", branch = "twizzler" }
4 changes: 4 additions & 0 deletions src/lib/twizzler-abi/src/runtime/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,8 @@ impl DebugRuntime for MinimalRuntime {
) -> core::ffi::c_int {
0
}

fn next_library_id(&self, _id: LibraryId) -> Option<LibraryId> {
None
}
}
25 changes: 24 additions & 1 deletion src/lib/twizzler-abi/src/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ use core::sync::atomic::{AtomicU64, Ordering};
#[cfg(not(feature = "kernel"))]
use core::time::Duration;

use crate::marker::BaseType;
#[cfg(not(feature = "kernel"))]
use crate::syscall::*;
use crate::{
marker::BaseType,
syscall::{ThreadSyncFlags, ThreadSyncOp, ThreadSyncReference, ThreadSyncSleep},
};
#[allow(unused_imports)]
use crate::{
object::{ObjID, Protections},
Expand Down Expand Up @@ -125,6 +128,26 @@ impl ThreadRepr {
}
}

/// Create a [ThreadSyncSleep] that will wait until the thread's state matches `state`.
pub fn waitable(&self, state: ExecutionState) -> ThreadSyncSleep {
ThreadSyncSleep::new(
ThreadSyncReference::Virtual(&self.status),
state as u64,
ThreadSyncOp::Equal,
ThreadSyncFlags::empty(),
)
}

/// Create a [ThreadSyncSleep] that will wait until the thread's state is _not_ `state`.
pub fn waitable_until_not(&self, state: ExecutionState) -> ThreadSyncSleep {
ThreadSyncSleep::new(
ThreadSyncReference::Virtual(&self.status),
state as u64,
ThreadSyncOp::Equal,
ThreadSyncFlags::INVERT,
)
}

#[cfg(not(feature = "kernel"))]
/// Wait for a thread's status to change, optionally timing out. Return value is None if timeout
/// occurs, or Some((ExecutionState, code)) otherwise.
Expand Down
4 changes: 4 additions & 0 deletions src/lib/twizzler-runtime-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,10 @@ pub trait DebugRuntime {
fn get_full_mapping(&self, lib: &Library) -> Option<ObjectHandle>;
/// Handler for calls to the dl_iterate_phdr call.
fn iterate_phdr(&self, f: &mut dyn FnMut(DlPhdrInfo) -> core::ffi::c_int) -> core::ffi::c_int;
/// Get the library ID immediately following the given one.
fn next_library_id(&self, id: LibraryId) -> Option<LibraryId> {
Some(LibraryId(id.0 + 1))
}
}

#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq)]
Expand Down
20 changes: 19 additions & 1 deletion src/runtime/monitor-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use std::{
};

use dynlink::tls::{Tcb, TlsRegion};
use twizzler_abi::object::ObjID;
use twizzler_abi::object::{ObjID, MAX_SIZE, NULLPAGE_SIZE};

mod gates {
include! {"../../monitor/secapi/gates.rs"}
Expand Down Expand Up @@ -163,3 +163,21 @@ impl SharedCompConfig {
}

pub use gates::LibraryInfo;

/// Contains raw mapping addresses, for use when translating to object handles for the runtime.
#[derive(Copy, Clone, PartialEq, PartialOrd, Ord, Eq)]
pub struct MappedObjectAddrs {
pub slot: usize,
pub start: usize,
pub meta: usize,
}

impl MappedObjectAddrs {
pub fn new(slot: usize) -> Self {
Self {
start: slot * MAX_SIZE,
meta: (slot + 1) * MAX_SIZE - NULLPAGE_SIZE,
slot,
}
}
}
2 changes: 2 additions & 0 deletions src/runtime/monitor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ monitor-api = { path = "../monitor-api" }
static_assertions = "1.1"
lazy_static = "1.4"
talc = "3.1"
happylock = "0.3"
parking_lot = "*"

[features]
secgate-impl = []
Expand Down
4 changes: 4 additions & 0 deletions src/runtime/monitor/src/api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
use twizzler_runtime_api::ObjID;

/// Reserved instance ID for the security monitor.
pub const MONITOR_INSTANCE_ID: ObjID = ObjID::new(0);
6 changes: 5 additions & 1 deletion src/runtime/monitor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#![feature(thread_local)]
#![feature(c_str_literals)]
#![feature(new_uninit)]
#![feature(hash_extract_if)]

use std::sync::{Arc, Mutex};

Expand Down Expand Up @@ -29,6 +30,9 @@ mod state;
mod thread;
mod upcall;

mod api;
mod mon;

#[path = "../secapi/gates.rs"]
mod gates;

Expand Down Expand Up @@ -95,7 +99,7 @@ fn monitor_init(state: Arc<Mutex<MonitorState>>) -> miette::Result<()> {
}
}

load_hello_world_test(&state).unwrap();
//load_hello_world_test(&state).unwrap();

Ok(())
}
Expand Down
1 change: 1 addition & 0 deletions src/runtime/monitor/src/mon/compartment.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub struct CompartmentMgr {}
38 changes: 38 additions & 0 deletions src/runtime/monitor/src/mon/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use std::sync::OnceLock;

use happylock::RwLock;

use self::space::Unmapper;

pub(crate) mod compartment;
pub(crate) mod space;
pub(crate) mod thread;

/// A security monitor instance. All monitor logic is implemented as methods for this type.
/// We split the state into the following components: 'space', managing the virtual memory space and
/// mapping objects, 'thread_mgr', which manages all threads owned by the monitor (typically, all
/// threads started by compartments), 'compartments', which manages compartment state, and
/// 'dynlink', which contains the dynamic linker state. The unmapper allows for background unmapping
/// and cleanup of objects and handles.
pub struct Monitor {
space: RwLock<space::Space>,
thread_mgr: RwLock<thread::ThreadMgr>,
compartments: RwLock<compartment::CompartmentMgr>,
dynlink: RwLock<dynlink::context::Context>,
unmapper: Unmapper,
}

static MONITOR: OnceLock<Monitor> = OnceLock::new();

/// Get the monitor instance. Panics if called before first call to [set_monitor].
pub fn get_monitor() -> &'static Monitor {
MONITOR.get().unwrap()
}

/// Set the monitor instance. Can only be called once. Must be called before any call to
/// [get_monitor].
pub fn set_monitor(monitor: Monitor) {
if MONITOR.set(monitor).is_err() {
panic!("second call to set_monitor");
}
}
Loading

0 comments on commit 6380071

Please sign in to comment.