Skip to content

Commit

Permalink
Cleanup.
Browse files Browse the repository at this point in the history
  • Loading branch information
dbittman committed Sep 2, 2024
1 parent 60a3517 commit 3502a4f
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 30 deletions.
46 changes: 36 additions & 10 deletions src/runtime/monitor-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,25 +221,38 @@ impl LibraryHandle {
.unwrap(),
)
}

/// Get the descriptor for this handle.
pub fn desc(&self) -> Descriptor {
self.desc
}
}

/// A builder-type for loading libraries.
pub struct LibraryLoader {
pub struct LibraryLoader<'a> {
id: ObjID,
comp: Option<&'a CompartmentHandle>,
}

impl LibraryLoader {
impl<'a> LibraryLoader<'a> {
/// Make a new LibraryLoader.
pub fn new(id: ObjID) -> Self {
Self { id }
Self { id, comp: None }
}

/// Load the library in the given compartment.
pub fn in_compartment(&'a mut self, comp: &'a CompartmentHandle) -> &'a mut Self {
self.comp = Some(comp);
self
}

/// Load the library.
pub fn load(&self) -> Result<LibraryHandle, gates::LoadLibraryError> {
let desc: Descriptor = gates::monitor_rt_load_library(self.id)
.ok()
.ok_or(gates::LoadLibraryError::Unknown)
.flatten()?;
let desc: Descriptor =
gates::monitor_rt_load_library(self.comp.map(|comp| comp.desc).flatten(), self.id)
.ok()
.ok_or(gates::LoadLibraryError::Unknown)
.flatten()?;
Ok(LibraryHandle { desc })
}
}
Expand All @@ -259,6 +272,11 @@ impl CompartmentHandle {
.unwrap(),
)
}

/// Get the descriptor for this handle, or None if the handle refers to the current compartment.
pub fn desc(&self) -> Option<Descriptor> {
self.desc
}
}

/// A builder-type for loading compartments.
Expand All @@ -272,7 +290,6 @@ impl CompartmentLoader {
Self { id }
}

// TODO: err
/// Load the compartment.
pub fn load(&self) -> Result<CompartmentHandle, gates::LoadCompartmentError> {
let desc = gates::monitor_rt_load_compartment(self.id)
Expand Down Expand Up @@ -366,6 +383,7 @@ impl<'a> CompartmentInfo<'a> {
}

impl CompartmentHandle {
/// Get a handle to the current compartment.
pub fn current() -> Self {
Self { desc: None }
}
Expand Down Expand Up @@ -393,7 +411,7 @@ pub struct LibraryIter<'a> {
}

impl<'a> LibraryIter<'a> {
pub fn new(comp: &'a CompartmentHandle) -> Self {
fn new(comp: &'a CompartmentHandle) -> Self {
Self { n: 0, comp }
}
}
Expand All @@ -417,7 +435,7 @@ pub struct CompartmentDepsIter<'a> {
}

impl<'a> CompartmentDepsIter<'a> {
pub fn new(comp: &'a CompartmentHandle) -> Self {
fn new(comp: &'a CompartmentHandle) -> Self {
Self { n: 0, comp }
}
}
Expand All @@ -443,6 +461,7 @@ bitflags::bitflags! {
/// Compartment state flags.
#[derive(Clone, Debug, Copy, PartialEq, PartialOrd, Ord, Eq, Hash)]
pub struct CompartmentFlags : u64 {
/// Compartment is ready (libraries relocated and constructors run).
const READY = 0x1;
}
}
Expand All @@ -466,6 +485,9 @@ impl MappedObjectAddrs {
}

mod lazy_sb {
//! A per-thread per-compartment simple buffer used for transferring strings between
//! compartments and the monitor. This is necessary because the monitor runs at too low of a
//! level for us to use nice shared memory techniques. This is simpler and more secure.
use std::cell::OnceCell;

use secgate::util::SimpleBuffer;
Expand Down Expand Up @@ -513,13 +535,17 @@ mod lazy_sb {

pub(super) fn read_string_from_sb(len: usize) -> String {
let mut buf = vec![0u8; len];
// Safety: this is per thread, and we only ever create the reference here or in the other
// read function below.
let len = unsafe { LAZY_SB.read(&mut buf) };
String::from_utf8_lossy(&buf[0..len]).to_string()
}

pub(super) fn read_bytes_from_sb(len: usize) -> Vec<u8> {
let mut buf = vec![0u8; len];
// Safety: see above.
let len = unsafe { LAZY_SB.read(&mut buf) };
buf.truncate(len);
buf
}
}
3 changes: 2 additions & 1 deletion src/runtime/monitor/secapi/gates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,12 +184,13 @@ pub fn monitor_rt_drop_compartment_handle(info: &secgate::GateCallInfo, desc: De
)]
pub fn monitor_rt_load_library(
info: &secgate::GateCallInfo,
compartment: Option<Descriptor>,
id: ObjID,
) -> Result<Descriptor, LoadLibraryError> {
use crate::api::MONITOR_INSTANCE_ID;
let monitor = crate::mon::get_monitor();
let caller = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
monitor.load_library(caller, id)
monitor.load_library(caller, id, compartment)
}

#[derive(Clone, Copy, Debug)]
Expand Down
16 changes: 13 additions & 3 deletions src/runtime/monitor/src/mon/compartment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,17 +71,20 @@ impl CompartmentMgr {
self.get_mut(MONITOR_INSTANCE_ID).unwrap()
}

/// Get an iterator over all compartments.
pub fn compartments(&self) -> impl Iterator<Item = &RunComp> {
self.instances.values()
}

/// Get an iterator over all compartments (mutable).
pub fn compartments_mut(&mut self) -> impl Iterator<Item = &mut RunComp> {
self.instances.values_mut()
}
}

impl super::Monitor {
//#[tracing::instrument(skip(self), ret)]
/// Get CompartmentInfo for this caller. Note that this will write to the compartment-thread's
/// simple buffer.
pub fn get_compartment_info(
&self,
instance: ObjID,
Expand All @@ -107,7 +110,7 @@ impl super::Monitor {
})
}

//#[tracing::instrument(skip(self), ret)]
/// Open a compartment handle for this caller compartment.
pub fn get_compartment_handle(&self, caller: ObjID, compartment: ObjID) -> Option<Descriptor> {
self.compartment_handles
.write(ThreadKey::get().unwrap())
Expand All @@ -123,6 +126,7 @@ impl super::Monitor {
)
}

/// Open a handle to the n'th dependency compartment of a given compartment.
pub fn get_compartment_deps(
&self,
caller: ObjID,
Expand All @@ -132,6 +136,7 @@ impl super::Monitor {
todo!()
}

/// Load a new compartment with a root library ID, and return a compartment handle.
pub fn load_compartment(
&self,
caller: ObjID,
Expand All @@ -140,10 +145,15 @@ impl super::Monitor {
todo!()
}

//#[tracing::instrument(skip(self), ret)]
/// Drop a compartment handle.
pub fn drop_compartment_handle(&self, caller: ObjID, desc: Descriptor) {
self.compartment_handles
.write(ThreadKey::get().unwrap())
.remove(caller, desc);
}
}

/// A handle to a compartment.
pub struct CompartmentHandle {
pub instance: ObjID,
}
16 changes: 12 additions & 4 deletions src/runtime/monitor/src/mon/library.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ use twizzler_runtime_api::{AddrRange, ObjID};
use super::Monitor;
use crate::gates::{LibraryInfo, LoadLibraryError};

/// A handle to a library.
pub struct LibraryHandle {
comp: ObjID,
id: LibraryId,
}

impl Monitor {
//#[tracing::instrument(skip(self), ret)]
/// Get LibraryInfo for a given library handle. Note that this will write to the
/// compartment-thread's simple buffer.
pub fn get_library_info(
&self,
instance: ObjID,
Expand Down Expand Up @@ -49,7 +51,7 @@ impl Monitor {
})
}

//#[tracing::instrument(skip(self), ret)]
/// Open a handle to the n'th library for a compartment.
pub fn get_library_handle(
&self,
caller: ObjID,
Expand All @@ -67,11 +69,17 @@ impl Monitor {
handles.insert(comp_id, LibraryHandle { comp: comp_id, id })
}

pub fn load_library(&self, caller: ObjID, id: ObjID) -> Result<Descriptor, LoadLibraryError> {
/// Load a library in the given compartment.
pub fn load_library(
&self,
caller: ObjID,
id: ObjID,
comp: Option<Descriptor>,
) -> Result<Descriptor, LoadLibraryError> {
todo!()
}

//#[tracing::instrument(skip(self), ret)]
/// Drop a library handle.
pub fn drop_library_handle(&self, caller: ObjID, desc: Descriptor) {
self.library_handles
.write(ThreadKey::get().unwrap())
Expand Down
17 changes: 5 additions & 12 deletions src/runtime/monitor/src/mon/mod.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,25 @@
use std::{ptr::NonNull, sync::OnceLock, thread::Thread};
use std::{ptr::NonNull, sync::OnceLock};

use dynlink::compartment::MONITOR_COMPARTMENT_ID;
use happylock::{LockCollection, RwLock, ThreadKey};
use monitor_api::{SharedCompConfig, TlsTemplateInfo};
use secgate::util::HandleMgr;
use twizzler_abi::upcall::UpcallFrame;
use twizzler_runtime_api::{LibraryId, MapError, MapFlags, ObjID, SpawnError, ThreadSpawnArgs};
use twizzler_runtime_api::{MapError, MapFlags, ObjID, SpawnError, ThreadSpawnArgs};
use twz_rt::{RuntimeState, RuntimeThreadControl, OUR_RUNTIME};

use self::{
compartment::{CompConfigObject, RunComp},
compartment::{CompConfigObject, CompartmentHandle, RunComp},
space::{MapHandle, MapInfo, Unmapper},
thread::{ManagedThread, ThreadCleaner},
};
use crate::{
api::MONITOR_INSTANCE_ID,
gates::{CompartmentInfo, LibraryInfo, LoadCompartmentError, LoadLibraryError},
init::InitDynlinkContext,
};
use crate::{api::MONITOR_INSTANCE_ID, init::InitDynlinkContext};

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

pub struct CompartmentHandle {
instance: ObjID,
}

/// 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
Expand Down Expand Up @@ -187,6 +179,7 @@ impl Monitor {
Ok(handle)
}

/// Get the object ID for this compartment-thread's simple buffer.
pub fn get_thread_simple_buffer(&self, sctx: ObjID, thread: ObjID) -> Option<ObjID> {
let mut locks = self.locks.lock(ThreadKey::get().unwrap());
let (ref mut space, _, ref mut comps, _, _, _) = *locks;
Expand Down

0 comments on commit 3502a4f

Please sign in to comment.