use secgate::{util::Descriptor, Crossing};
use twizzler_runtime_api::{
AddrRange, DlPhdrInfo, LibraryId, MapError, ObjID, SpawnError, ThreadSpawnArgs,
};
#[cfg_attr(feature = "secgate-impl", secgate::secure_gate(options(info)))]
#[cfg_attr(
not(feature = "secgate-impl"),
secgate::secure_gate(options(info, api))
)]
pub fn monitor_rt_spawn_thread(
info: &secgate::GateCallInfo,
args: ThreadSpawnArgs,
thread_pointer: usize,
stack_pointer: usize,
) -> Result<ObjID, SpawnError> {
let monitor = crate::mon::get_monitor();
monitor.spawn_compartment_thread(
info.source_context().unwrap_or(0.into()),
args,
stack_pointer,
thread_pointer,
)
}
#[cfg_attr(feature = "secgate-impl", secgate::secure_gate(options(info)))]
#[cfg_attr(
not(feature = "secgate-impl"),
secgate::secure_gate(options(info, api))
)]
pub fn monitor_rt_get_comp_config(info: &secgate::GateCallInfo) -> usize {
use crate::api::MONITOR_INSTANCE_ID;
let monitor = crate::mon::get_monitor();
monitor
.get_comp_config(info.source_context().unwrap_or(MONITOR_INSTANCE_ID))
.map(|ptr| ptr as usize)
.unwrap_or(0)
}
#[cfg_attr(feature = "secgate-impl", secgate::secure_gate(options(info)))]
#[cfg_attr(
not(feature = "secgate-impl"),
secgate::secure_gate(options(info, api))
)]
pub fn monitor_rt_get_library_info(
info: &secgate::GateCallInfo,
desc: Descriptor,
) -> Option<LibraryInfo> {
use crate::api::MONITOR_INSTANCE_ID;
let monitor = crate::mon::get_monitor();
let instance = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
let thread = info.thread_id();
monitor.get_library_info(instance, thread, desc)
}
#[cfg_attr(feature = "secgate-impl", secgate::secure_gate(options(info)))]
#[cfg_attr(
not(feature = "secgate-impl"),
secgate::secure_gate(options(info, api))
)]
pub fn monitor_rt_get_library_handle(
info: &secgate::GateCallInfo,
compartment: Option<Descriptor>,
lib_n: usize,
) -> Option<Descriptor> {
use crate::api::MONITOR_INSTANCE_ID;
let monitor = crate::mon::get_monitor();
let caller = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
monitor.get_library_handle(caller, compartment, lib_n)
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct LibraryInfo {
pub name_len: usize,
pub compartment_id: ObjID,
pub objid: ObjID,
pub slot: usize,
pub range: AddrRange,
pub dl_info: DlPhdrInfo,
pub desc: Descriptor,
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct CompartmentInfo {
pub name_len: usize,
pub id: ObjID,
pub sctx: ObjID,
pub flags: u64,
}
#[cfg_attr(feature = "secgate-impl", secgate::secure_gate(options(info)))]
#[cfg_attr(
not(feature = "secgate-impl"),
secgate::secure_gate(options(info, api))
)]
pub fn monitor_rt_get_compartment_handle(
info: &secgate::GateCallInfo,
compartment: ObjID,
) -> Option<Descriptor> {
use crate::api::MONITOR_INSTANCE_ID;
let monitor = crate::mon::get_monitor();
let caller = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
let compartment = if compartment.as_u128() == 0 {
caller
} else {
compartment
};
monitor.get_compartment_handle(caller, compartment)
}
#[cfg_attr(feature = "secgate-impl", secgate::secure_gate(options(info)))]
#[cfg_attr(
not(feature = "secgate-impl"),
secgate::secure_gate(options(info, api))
)]
pub fn monitor_rt_get_compartment_info(
info: &secgate::GateCallInfo,
desc: Option<Descriptor>,
) -> Option<CompartmentInfo> {
use crate::api::MONITOR_INSTANCE_ID;
let monitor = crate::mon::get_monitor();
let caller = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
monitor.get_compartment_info(caller, info.thread_id(), desc)
}
#[cfg_attr(feature = "secgate-impl", secgate::secure_gate(options(info)))]
#[cfg_attr(
not(feature = "secgate-impl"),
secgate::secure_gate(options(info, api))
)]
pub fn monitor_rt_get_compartment_deps(
info: &secgate::GateCallInfo,
desc: Option<Descriptor>,
dep_n: usize,
) -> Option<Descriptor> {
use crate::api::MONITOR_INSTANCE_ID;
let monitor = crate::mon::get_monitor();
let caller = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
monitor.get_compartment_deps(caller, desc, dep_n)
}
unsafe impl Crossing for LibraryInfo {}
#[cfg_attr(feature = "secgate-impl", secgate::secure_gate(options(info)))]
#[cfg_attr(
not(feature = "secgate-impl"),
secgate::secure_gate(options(info, api))
)]
pub fn monitor_rt_load_compartment(
info: &secgate::GateCallInfo,
root_id: ObjID,
) -> Result<Descriptor, LoadCompartmentError> {
use crate::api::MONITOR_INSTANCE_ID;
let monitor = crate::mon::get_monitor();
let caller = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
monitor.load_compartment(caller, root_id)
}
#[derive(Clone, Copy, Debug)]
pub enum LoadCompartmentError {
Unknown,
}
#[cfg_attr(feature = "secgate-impl", secgate::secure_gate(options(info)))]
#[cfg_attr(
not(feature = "secgate-impl"),
secgate::secure_gate(options(info, api))
)]
pub fn monitor_rt_drop_compartment_handle(info: &secgate::GateCallInfo, desc: Descriptor) {
use crate::api::MONITOR_INSTANCE_ID;
let monitor = crate::mon::get_monitor();
let caller = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
monitor.drop_compartment_handle(caller, desc)
}
#[cfg_attr(feature = "secgate-impl", secgate::secure_gate(options(info)))]
#[cfg_attr(
not(feature = "secgate-impl"),
secgate::secure_gate(options(info, api))
)]
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, compartment)
}
#[derive(Clone, Copy, Debug)]
pub enum LoadLibraryError {
Unknown,
}
#[cfg_attr(feature = "secgate-impl", secgate::secure_gate(options(info)))]
#[cfg_attr(
not(feature = "secgate-impl"),
secgate::secure_gate(options(info, api))
)]
pub fn monitor_rt_drop_library_handle(info: &secgate::GateCallInfo, desc: Descriptor) {
use crate::api::MONITOR_INSTANCE_ID;
let monitor = crate::mon::get_monitor();
let caller = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
monitor.drop_library_handle(caller, desc)
}
#[cfg_attr(feature = "secgate-impl", secgate::secure_gate(options(info)))]
#[cfg_attr(
not(feature = "secgate-impl"),
secgate::secure_gate(options(info, api))
)]
pub fn monitor_rt_object_map(
info: &secgate::GateCallInfo,
id: ObjID,
flags: twizzler_runtime_api::MapFlags,
) -> Result<crate::MappedObjectAddrs, MapError> {
use twz_rt::{RuntimeState, OUR_RUNTIME};
use crate::{api::MONITOR_INSTANCE_ID, mon::space::MapInfo};
if OUR_RUNTIME.state().contains(RuntimeState::READY) {
let is_monitor_recursed =
{ happylock::ThreadKey::get().is_none() && info.source_context().is_none() };
if is_monitor_recursed {
tracing::debug!(
"performing early object mapping (recursed), {} {:?}",
id,
flags
);
return Ok(crate::mon::early_object_map(MapInfo { id, flags }));
}
let monitor = crate::mon::get_monitor();
monitor
.map_object(
info.source_context().unwrap_or(MONITOR_INSTANCE_ID),
MapInfo { id, flags },
)
.map(|handle| handle.addrs())
} else {
tracing::debug!("performing early object mapping, {} {:?}", id, flags);
Ok(crate::mon::early_object_map(MapInfo { id, flags }))
}
}
#[cfg_attr(feature = "secgate-impl", secgate::secure_gate(options(info)))]
#[cfg_attr(
not(feature = "secgate-impl"),
secgate::secure_gate(options(info, api))
)]
pub fn monitor_rt_object_unmap(
info: &secgate::GateCallInfo,
_slot: usize,
id: ObjID,
flags: twizzler_runtime_api::MapFlags,
) {
use twz_rt::{RuntimeState, OUR_RUNTIME};
if OUR_RUNTIME.state().contains(RuntimeState::READY) {
let monitor = crate::mon::get_monitor();
let key = happylock::ThreadKey::get().unwrap();
monitor
.comp_mgr
.write(key)
.get_mut(
info.source_context()
.unwrap_or(crate::api::MONITOR_INSTANCE_ID),
)
.unwrap()
.unmap_object(crate::mon::space::MapInfo { id, flags })
}
}
#[cfg_attr(feature = "secgate-impl", secgate::secure_gate(options(info)))]
#[cfg_attr(
not(feature = "secgate-impl"),
secgate::secure_gate(options(info, api))
)]
pub fn monitor_rt_get_thread_simple_buffer(info: &secgate::GateCallInfo) -> Option<ObjID> {
use crate::api::MONITOR_INSTANCE_ID;
let monitor = crate::mon::get_monitor();
let caller = info.source_context().unwrap_or(MONITOR_INSTANCE_ID);
monitor.get_thread_simple_buffer(caller, info.thread_id())
}