Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Security montitor (1) #199

Merged
merged 6 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,5 @@ 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 comes from the parking_lot repo
lock_api = { git = "https://github.com/twizzler-operating-system/parking_lot.git", branch = "twizzler" }
12 changes: 12 additions & 0 deletions src/lib/twizzler-abi/src/arch/aarch64/upcall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,18 @@ impl UpcallFrame {
pub fn bp(&self) -> usize {
self.fp as usize
}

/// Build a new frame set up to enter a context at a start point.
pub fn new_entry_frame(
stack_base: usize,
stack_size: usize,
tp: usize,
ctx: crate::object::ObjID,
entry: usize,
arg: usize,
) -> Self {
todo!()
}
}

#[no_mangle]
Expand Down
35 changes: 35 additions & 0 deletions src/lib/twizzler-abi/src/arch/x86_64/upcall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,41 @@ impl UpcallFrame {
pub fn bp(&self) -> usize {
self.rbp as usize
}

/// Build a new frame set up to enter a context at a start point.
pub fn new_entry_frame(
stack_base: usize,
stack_size: usize,
tp: usize,
ctx: crate::object::ObjID,
entry: usize,
arg: usize,
) -> Self {
Self {
xsave_region: [0; XSAVE_LEN],
rip: entry as u64,
// Default has the interrupt enabled flag set, and the reserved bit.
rflags: 0x202,
rsp: (stack_base + stack_size - 8) as u64,
rbp: 0,
rax: 0,
rbx: 0,
rcx: 0,
rdx: 0,
rdi: arg as u64,
rsi: 0,
r8: 0,
r9: 0,
r10: 0,
r11: 0,
r12: 0,
r13: 0,
r14: 0,
r15: 0,
thread_ptr: tp as u64,
prior_ctx: ctx,
}
}
}

#[no_mangle]
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/monitor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,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
66 changes: 65 additions & 1 deletion src/runtime/monitor/src/mon/compartment.rs
Original file line number Diff line number Diff line change
@@ -1 +1,65 @@
pub struct CompartmentMgr {}
use std::collections::HashMap;

use twizzler_runtime_api::ObjID;

use self::runcomp::RunComp;
use crate::api::MONITOR_INSTANCE_ID;

mod compconfig;
mod compthread;
mod runcomp;

/// Manages compartments.
pub struct CompartmentMgr {
names: HashMap<String, ObjID>,
instances: HashMap<ObjID, RunComp>,
}

impl CompartmentMgr {
/// Get a [RunComp] by instance ID.
pub fn get(&self, id: ObjID) -> Option<&RunComp> {
self.instances.get(&id)
}

/// Get a [RunComp] by name.
pub fn get_name(&self, name: &str) -> Option<&RunComp> {
let id = self.names.get(name)?;
self.get(*id)
}

/// Get a [RunComp] by instance ID.
pub fn get_mut(&mut self, id: ObjID) -> Option<&mut RunComp> {
self.instances.get_mut(&id)
}

/// Get a [RunComp] by name.
pub fn get_name_mut(&mut self, name: &str) -> Option<&mut RunComp> {
let id = self.names.get(name)?;
self.get_mut(*id)
}

/// Insert a [RunComp].
pub fn insert(&mut self, rc: RunComp) {
self.names.insert(rc.name.clone(), rc.instance);
self.instances.insert(rc.instance, rc);
}

/// Remove a [RunComp].
pub fn remove(&mut self, id: ObjID) -> Option<RunComp> {
let rc = self.instances.remove(&id)?;
self.names.remove(&rc.name);
Some(rc)
}

/// Get the [RunComp] for the monitor.
pub fn get_monitor(&self) -> &RunComp {
// Unwrap-Ok: this instance is always present.
self.get(MONITOR_INSTANCE_ID).unwrap()
}

/// Get the [RunComp] for the monitor.
pub fn get_monitor_mut(&mut self) -> &mut RunComp {
// Unwrap-Ok: this instance is always present.
self.get_mut(MONITOR_INSTANCE_ID).unwrap()
}
}
54 changes: 54 additions & 0 deletions src/runtime/monitor/src/mon/compartment/compconfig.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use monitor_api::SharedCompConfig;
use talc::Span;
use twizzler_abi::object::{MAX_SIZE, NULLPAGE_SIZE};

use crate::mon::space::MapHandle;

/// Manages a compartment configuration object.
pub struct CompConfigObject {
handle: MapHandle,
}

impl CompConfigObject {
/// Create a new CompConfigObject from a handle. Initializes the comp config.
pub fn new(handle: MapHandle, init_val: SharedCompConfig) -> Self {
let mut this = Self { handle };
this.write_config(init_val);
this
}

/// Write a comp config to this object.
pub fn write_config(&mut self, val: SharedCompConfig) {
// Safety: only the monitor can write to a comp config object, and we have a mutable
// reference to it.
unsafe {
let base = self.handle.monitor_data_base();
(base as *mut SharedCompConfig).write(val);
}
}

/// Read the comp config data.
pub(crate) fn read_comp_config(&self) -> SharedCompConfig {
// Safety: no other compartment can write this.
unsafe { self.get_comp_config().read() }
}

/// Get a pointer to this comp config data.
pub fn get_comp_config(&self) -> *const SharedCompConfig {
self.handle.monitor_data_base() as *const SharedCompConfig
}

/// Return a span that can be used for allocations in the comp config object.
pub fn alloc_span(&self) -> Span {
let offset_from_base =
core::mem::size_of::<SharedCompConfig>().next_multiple_of(NULLPAGE_SIZE);
assert!(offset_from_base < MAX_SIZE / 2);
// Safety: the pointers stay in-bounds (in an object).
unsafe {
Span::new(
self.handle.monitor_data_base().add(offset_from_base),
self.handle.monitor_data_start().add(MAX_SIZE / 2),
)
}
}
}
70 changes: 70 additions & 0 deletions src/runtime/monitor/src/mon/compartment/compthread.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use twizzler_abi::{object::MAX_SIZE, upcall::UpcallFrame};
use twizzler_runtime_api::ObjID;

use crate::mon::{
space::MapHandle,
thread::{ManagedThread, DEFAULT_STACK_SIZE, STACK_SIZE_MIN_ALIGN},
};

pub(super) struct CompThread {
stack_object: StackObject,
thread: ManagedThread,
}

impl CompThread {
/// Start a new thread using the given stack, in the provided security context instance, using
/// the start function.
pub fn new(
stack: StackObject,
instance: ObjID,
start: impl FnOnce() + Send + 'static,
) -> miette::Result<Self> {
todo!()
}

/// Get the entry frame for this thread into a given compartment.
pub fn get_entry_frame(&self, ctx: ObjID, entry: usize, arg: usize) -> UpcallFrame {
UpcallFrame::new_entry_frame(
self.stack_object.initial_stack_ptr(),
self.stack_object.stack_size(),
0,
ctx,
entry,
arg,
)
}
}

pub(crate) struct StackObject {
handle: MapHandle,
stack_size: usize,
}

impl StackObject {
/// Make a new stack object from a given handle and stack size.
pub fn new(handle: MapHandle, stack_size: usize) -> miette::Result<Self> {
// Find the stack size, with max and min values, and correct alignment.
let stack_size = std::cmp::max(std::cmp::min(stack_size, MAX_SIZE / 2), DEFAULT_STACK_SIZE)
.next_multiple_of(STACK_SIZE_MIN_ALIGN);

Ok(Self { handle, stack_size })
}

/// Get the start start address for the compartment.
pub fn stack_comp_start(&self) -> usize {
self.handle.addrs().start
}

/// Get the stack size.
pub fn stack_size(&self) -> usize {
self.stack_size
}

// This works for architectures where the stack grows down. If your architecture does not use a
// downward-growing stack, implement this function differently.
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
/// Get the initial stack pointer.
pub fn initial_stack_ptr(&self) -> usize {
self.stack_comp_start() + self.stack_size
}
}
Loading
Loading