From 5dfcdff61f08d409f39dfc53e5246ec72a70f22d Mon Sep 17 00:00:00 2001 From: Daniel Bittman Date: Mon, 2 Dec 2024 17:24:49 -0800 Subject: [PATCH] Add example logging service for monitor secure gates (#223) * Fixing linking errors. * Allow self-reference for monitor. * Reorg and cleanup. --- Cargo.lock | 25 +++++++ Cargo.toml | 5 ++ src/bin/bootstrap/src/main.rs | 4 +- src/kernel/src/initrd.rs | 2 +- src/runtime/dynlink/src/context/load.rs | 21 ++++-- src/runtime/dynlink/src/context/syms.rs | 14 ++-- src/runtime/dynlink/src/library.rs | 75 ++++++++++++++++--- src/runtime/dynlink/src/symbol.rs | 2 +- src/runtime/monitor-api/src/lib.rs | 1 + src/runtime/monitor/src/main.rs | 43 ++++++++++- .../monitor/src/mon/compartment/loader.rs | 12 ++- .../monitor/tests/montest-lib/Cargo.toml | 2 +- .../monitor/tests/montest-lib/src/lib.rs | 1 + src/runtime/monitor/tests/montest/src/main.rs | 23 ++---- src/runtime/secgate/secgate-macros/src/lib.rs | 36 +++++---- src/srv/logboi/Cargo.toml | 12 +++ src/srv/logboi/logboi-srv/Cargo.toml | 15 ++++ src/srv/logboi/logboi-srv/src/lib.rs | 18 +++++ src/srv/logboi/logboi-test/Cargo.toml | 8 ++ src/srv/logboi/logboi-test/src/main.rs | 4 + src/srv/logboi/src/lib.rs | 4 + tools/xtask/src/build.rs | 3 + tools/xtask/src/toolchain.rs | 4 +- 23 files changed, 269 insertions(+), 65 deletions(-) create mode 100644 src/srv/logboi/Cargo.toml create mode 100644 src/srv/logboi/logboi-srv/Cargo.toml create mode 100644 src/srv/logboi/logboi-srv/src/lib.rs create mode 100644 src/srv/logboi/logboi-test/Cargo.toml create mode 100644 src/srv/logboi/logboi-test/src/main.rs create mode 100644 src/srv/logboi/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index bea3e82c..751f88f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3067,6 +3067,31 @@ version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +[[package]] +name = "logboi" +version = "0.1.0" +dependencies = [ + "logboi-srv", + "secgate", + "twizzler-runtime", +] + +[[package]] +name = "logboi-srv" +version = "0.1.0" +dependencies = [ + "secgate", + "twizzler-runtime", +] + +[[package]] +name = "logboi-test" +version = "0.1.0" +dependencies = [ + "logboi", + "twizzler-runtime", +] + [[package]] name = "lru" version = "0.12.5" diff --git a/Cargo.toml b/Cargo.toml index 44334ce4..c8085ab4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,6 +32,9 @@ members = [ "src/runtime/minruntime", "src/abi/rt-abi", "src/abi/types", + "src/srv/logboi", + "src/srv/logboi/logboi-srv", + "src/srv/logboi/logboi-test", ] exclude = ["toolchain/src/rust"] @@ -51,6 +54,8 @@ initrd = [ "lib:montest-lib", "crate:mnemosyne", "crate:stdfs_demo", + "crate:logboi-test", + "lib:logboi-srv", #"third-party:hello-world-rs" ] diff --git a/src/bin/bootstrap/src/main.rs b/src/bin/bootstrap/src/main.rs index a05548d1..87449099 100644 --- a/src/bin/bootstrap/src/main.rs +++ b/src/bin/bootstrap/src/main.rs @@ -4,7 +4,7 @@ use dynlink::{ compartment::MONITOR_COMPARTMENT_ID, context::{runtime::RuntimeInitInfo, NewCompartmentFlags}, engines::{Backing, ContextEngine}, - library::UnloadedLibrary, + library::{AllowedGates, UnloadedLibrary}, symbol::LookupFlags, DynlinkError, DynlinkErrorKind, }; @@ -74,7 +74,7 @@ fn start_runtime(_runtime_monitor: ObjID, _runtime_library: ObjID) -> ! { .unwrap(); let monitor_id = ctx - .load_library_in_compartment(monitor_comp_id, unlib, true) + .load_library_in_compartment(monitor_comp_id, unlib, AllowedGates::PublicInclSelf) .unwrap()[0] .lib; diff --git a/src/kernel/src/initrd.rs b/src/kernel/src/initrd.rs index dbb0513c..de4c5eb9 100644 --- a/src/kernel/src/initrd.rs +++ b/src/kernel/src/initrd.rs @@ -65,7 +65,7 @@ pub fn init(modules: &[BootModule]) { } let obj = Arc::new(obj); obj::register_object(obj.clone()); - if e.filename().as_str() == "bootstrap" { + if e.filename().as_str() == "init" { boot_objects.init = Some(obj.clone()); } boot_objects diff --git a/src/runtime/dynlink/src/context/load.rs b/src/runtime/dynlink/src/context/load.rs index 4b91d231..a1751f05 100644 --- a/src/runtime/dynlink/src/context/load.rs +++ b/src/runtime/dynlink/src/context/load.rs @@ -15,7 +15,7 @@ use crate::{ compartment::{Compartment, CompartmentId}, context::NewCompartmentFlags, engines::{LoadDirective, LoadFlags}, - library::{Library, LibraryId, SecgateInfo, UnloadedLibrary}, + library::{AllowedGates, Library, LibraryId, SecgateInfo, UnloadedLibrary}, tls::TlsModule, DynlinkError, DynlinkErrorKind, HeaderError, }; @@ -128,7 +128,7 @@ impl Context { comp_id: CompartmentId, unlib: UnloadedLibrary, idx: NodeIndex, - allows_gates: bool, + allowed_gates: AllowedGates, ) -> Result { let backing = self.engine.load_object(&unlib)?; let elf = backing.get_elf()?; @@ -279,7 +279,7 @@ impl Context { tls_id, ctor_info, secgate_info, - allows_gates, + allowed_gates, )) } @@ -340,7 +340,7 @@ impl Context { comp_id: CompartmentId, root_unlib: UnloadedLibrary, idx: NodeIndex, - allows_gates: bool, + allowed_gates: AllowedGates, ) -> Result, DynlinkError> { let root_comp_name = self.get_compartment(comp_id)?.name.clone(); debug!( @@ -350,7 +350,7 @@ impl Context { let mut ids = vec![]; // First load the main library. let lib = self - .load(comp_id, root_unlib.clone(), idx, allows_gates) + .load(comp_id, root_unlib.clone(), idx, allowed_gates) .map_err(|e| { DynlinkError::new_collect( DynlinkErrorKind::LibraryLoadFail { @@ -418,8 +418,13 @@ impl Context { let comp = self.get_compartment_mut(load_comp)?; comp.library_names.insert(dep_unlib.name.clone(), idx); + let allowed_gates = if comp.id == comp_id { + AllowedGates::Private + } else { + AllowedGates::Public + }; let mut recs = self - .load_library(load_comp, dep_unlib.clone(), idx, false) + .load_library(load_comp, dep_unlib.clone(), idx, allowed_gates) .map_err(|e| { DynlinkError::new_collect( DynlinkErrorKind::LibraryLoadFail { @@ -453,7 +458,7 @@ impl Context { &mut self, comp_id: CompartmentId, unlib: UnloadedLibrary, - allows_gates: bool, + allowed_gates: AllowedGates, ) -> Result, DynlinkError> { let idx = self.add_library(unlib.clone()); // Step 1: insert into the compartment's library names. @@ -469,6 +474,6 @@ impl Context { comp.library_names.insert(unlib.name.clone(), idx); // Step 2: load the library. This call recurses on dependencies. - self.load_library(comp_id, unlib.clone(), idx, allows_gates) + self.load_library(comp_id, unlib.clone(), idx, allowed_gates) } } diff --git a/src/runtime/dynlink/src/context/syms.rs b/src/runtime/dynlink/src/context/syms.rs index 7f016539..a80b4e8b 100644 --- a/src/runtime/dynlink/src/context/syms.rs +++ b/src/runtime/dynlink/src/context/syms.rs @@ -1,5 +1,3 @@ -use tracing::trace; - use super::{Context, LoadedOrUnloaded}; use crate::{ library::{Library, LibraryId}, @@ -21,7 +19,7 @@ impl Context { let start_lib = self.get_library(start_id)?; // First try looking up within ourselves. if !lookup_flags.contains(LookupFlags::SKIP_SELF) { - if let Ok(sym) = start_lib.lookup_symbol(name, allow_weak) { + if let Ok(sym) = start_lib.lookup_symbol(name, allow_weak, false) { return Ok(sym); } } @@ -40,7 +38,9 @@ impl Context { { let allow_weak = allow_weak && dep.in_same_compartment_as(start_lib); - if let Ok(sym) = dep.lookup_symbol(name, allow_weak) { + let try_prefix = + dep.in_same_compartment_as(start_lib) || dep.allows_gates(); + if let Ok(sym) = dep.lookup_symbol(name, allow_weak, try_prefix) { return Ok(sym); } } @@ -52,7 +52,7 @@ impl Context { // Fall back to global search. if !lookup_flags.contains(LookupFlags::SKIP_GLOBAL) { - trace!("falling back to global search for {}", name); + tracing::trace!("falling back to global search for {}", name); let res = self.lookup_symbol_global(start_lib, name, lookup_flags); if res.is_ok() { @@ -89,7 +89,9 @@ impl Context { { let allow_weak = lookup_flags.contains(LookupFlags::ALLOW_WEAK) && dep.in_same_compartment_as(start_lib); - if let Ok(sym) = dep.lookup_symbol(name, allow_weak) { + let try_prefix = (idx != start_lib.id().0 || dep.allows_self_gates()) + && (dep.allows_gates() || dep.in_same_compartment_as(start_lib)); + if let Ok(sym) = dep.lookup_symbol(name, allow_weak, try_prefix) { return Ok(sym); } } diff --git a/src/runtime/dynlink/src/library.rs b/src/runtime/dynlink/src/library.rs index 37bbff79..765eb9f4 100644 --- a/src/runtime/dynlink/src/library.rs +++ b/src/runtime/dynlink/src/library.rs @@ -30,6 +30,16 @@ pub(crate) enum RelocState { Relocated, } +#[derive(PartialEq, PartialOrd, Ord, Eq, Debug, Clone, Copy)] +pub enum AllowedGates { + /// Gates are not exported + Private, + /// Gates are exported to other compartments only + Public, + /// Gates are exported to all compartments + PublicInclSelf, +} + #[repr(C)] /// An unloaded library. It's just a name, really. #[derive(Debug, Clone, PartialEq, PartialOrd, Ord, Eq, Hash)] @@ -84,7 +94,7 @@ pub struct Library { pub full_obj: Backing, /// State of relocation. pub(crate) reloc_state: RelocState, - allows_gates: bool, + allowed_gates: AllowedGates, pub backings: Vec, @@ -108,7 +118,7 @@ impl Library { tls_id: Option, ctors: CtorSet, secgate_info: SecgateInfo, - allows_gates: bool, + allowed_gates: AllowedGates, ) -> Self { Self { name, @@ -121,11 +131,16 @@ impl Library { comp_id, comp_name, secgate_info, - allows_gates, + allowed_gates, } } + pub fn allows_gates(&self) -> bool { - self.allows_gates + self.allowed_gates != AllowedGates::Private + } + + pub fn allows_self_gates(&self) -> bool { + self.allowed_gates == AllowedGates::PublicInclSelf } pub fn is_binary(&self) -> bool { @@ -228,13 +243,29 @@ impl Library { })) } - pub(crate) fn lookup_symbol( + fn do_lookup_symbol( &self, name: &str, allow_weak: bool, ) -> Result, DynlinkError> { let elf = self.get_elf()?; let common = elf.find_common_data()?; + tracing::trace!("lookup {} in {}", name, self.name); + + /* + if self.is_relocated() { + if let Some(gates) = self.iter_secgates() { + for sc in gates { + if let Ok(gname) = sc.name().to_str() { + if gname == name { + tracing::info!("found as secure gate"); + return Ok(RelocatedSymbol::new_sc(sc.imp, self)); + } + } + } + } + } + */ // Try the GNU hash table, if present. if let Some(h) = &common.gnu_hash { @@ -258,7 +289,10 @@ impl Library { { if !sym.is_undefined() { // TODO: proper weak symbol handling. - if sym.st_bind() != STB_WEAK || allow_weak { + if sym.st_bind() != STB_WEAK + || allow_weak + || (self.is_relocated() && self.is_secgate(name)) + { return Ok(RelocatedSymbol::new(sym, self)); } else { tracing::debug!("lookup symbol {} skipping weak binding in {}", name, self); @@ -295,7 +329,10 @@ impl Library { { if !sym.is_undefined() { // TODO: proper weak symbol handling. - if sym.st_bind() != STB_WEAK { + if sym.st_bind() != STB_WEAK + || allow_weak + || (self.is_relocated() && self.is_secgate(name)) + { return Ok(RelocatedSymbol::new(sym, self)); } else { tracing::info!("lookup symbol {} skipping weak binding in {}", name, self); @@ -305,21 +342,41 @@ impl Library { } } } + Err(DynlinkErrorKind::NameNotFound { name: name.to_string(), } .into()) } + pub(crate) fn lookup_symbol( + &self, + name: &str, + allow_weak: bool, + allow_prefix: bool, + ) -> Result, DynlinkError> { + let ret = self.do_lookup_symbol(&name, allow_weak); + if allow_prefix && ret.is_err() && !name.starts_with("__TWIZZLER_SECURE_GATE_") { + let name = format!("__TWIZZLER_SECURE_GATE_{}", name); + if let Ok(o) = self.do_lookup_symbol(&name, allow_weak) { + return Ok(o); + } + } + ret + } + pub(crate) fn is_local_or_secgate_from(&self, other: &Library, name: &str) -> bool { - self.in_same_compartment_as(other) - || (self.reloc_state == RelocState::Relocated && self.is_secgate(name)) + self.in_same_compartment_as(other) || (self.is_relocated() && self.is_secgate(name)) } pub(crate) fn in_same_compartment_as(&self, other: &Library) -> bool { other.comp_id == self.comp_id } + pub fn is_relocated(&self) -> bool { + self.reloc_state == RelocState::Relocated + } + fn is_secgate(&self, name: &str) -> bool { self.iter_secgates() .map(|gates| { diff --git a/src/runtime/dynlink/src/symbol.rs b/src/runtime/dynlink/src/symbol.rs index a43b4a17..35fb3830 100644 --- a/src/runtime/dynlink/src/symbol.rs +++ b/src/runtime/dynlink/src/symbol.rs @@ -17,7 +17,7 @@ impl<'lib> RelocatedSymbol<'lib> { /// Returns the relocated address of the symbol, i.e. the value of the symbol added to the base /// address of the library it comes from. pub fn reloc_value(&self) -> u64 { - self.sym.st_value + self.lib.base_addr() as u64 + self.raw_value() + self.lib.base_addr() as u64 } /// Returns the raw symbol value (unrelocated). diff --git a/src/runtime/monitor-api/src/lib.rs b/src/runtime/monitor-api/src/lib.rs index 02587076..6780577e 100644 --- a/src/runtime/monitor-api/src/lib.rs +++ b/src/runtime/monitor-api/src/lib.rs @@ -3,6 +3,7 @@ //! dependency. #![feature(naked_functions)] +#![feature(linkage)] #![feature(result_flattening)] #![feature(thread_local)] #![feature(pointer_is_aligned_to)] diff --git a/src/runtime/monitor/src/main.rs b/src/runtime/monitor/src/main.rs index 4ebccf10..2418c67a 100644 --- a/src/runtime/monitor/src/main.rs +++ b/src/runtime/monitor/src/main.rs @@ -3,8 +3,7 @@ #![feature(hash_extract_if)] #![feature(new_zeroed_alloc)] #![feature(iterator_try_collect)] - -use std::time::Duration; +#![feature(linkage)] use dynlink::context::NewCompartmentFlags; use miette::IntoDiagnostic; @@ -114,6 +113,46 @@ fn monitor_init() -> miette::Result<()> { } } info!("monitor early init completed, starting init"); + + // Load and wait for tests to complete + let lbcomp: CompartmentHandle = CompartmentLoader::new( + "logboi", + "liblogboi_srv.so", + NewCompartmentFlags::EXPORT_GATES, + ) + .args(&["logboi"]) + .load() + .into_diagnostic()?; + let mut flags = lbcomp.info().flags; + while !flags.contains(CompartmentFlags::READY) { + flags = lbcomp.wait(flags); + } + info!("logboi ready"); + std::mem::forget(lbcomp); + + info!("running logboi test"); + // Load and wait for tests to complete + let comp: CompartmentHandle = + CompartmentLoader::new("logboi-test", "logboi-test", NewCompartmentFlags::empty()) + .args(&["logboi-test"]) + .load() + .into_diagnostic()?; + let mut flags = comp.info().flags; + while !flags.contains(CompartmentFlags::EXITED) { + flags = comp.wait(flags); + } + info!("running logboi test again"); + // Load and wait for tests to complete + let comp: CompartmentHandle = + CompartmentLoader::new("logboi-test", "logboi-test", NewCompartmentFlags::empty()) + .args(&["logboi-test"]) + .load() + .into_diagnostic()?; + let mut flags = comp.info().flags; + while !flags.contains(CompartmentFlags::EXITED) { + flags = comp.wait(flags); + } + // TODO: start init... Ok(()) diff --git a/src/runtime/monitor/src/mon/compartment/loader.rs b/src/runtime/monitor/src/mon/compartment/loader.rs index 0c1746d7..ffa9ca0c 100644 --- a/src/runtime/monitor/src/mon/compartment/loader.rs +++ b/src/runtime/monitor/src/mon/compartment/loader.rs @@ -3,7 +3,7 @@ use std::{collections::HashSet, ffi::CStr, ptr::null_mut}; use dynlink::{ compartment::CompartmentId, context::{Context, LoadIds, NewCompartmentFlags}, - library::{LibraryId, UnloadedLibrary}, + library::{AllowedGates, LibraryId, UnloadedLibrary}, DynlinkError, }; use happylock::ThreadKey; @@ -135,7 +135,8 @@ impl RunCompLoader { } let rt_unlib = UnloadedLibrary::new(RUNTIME_NAME); - let loads = dynlink.load_library_in_compartment(comp_id, rt_unlib, false)?; + let loads = + dynlink.load_library_in_compartment(comp_id, rt_unlib, AllowedGates::Private)?; dynlink.add_manual_dependency(root_id, loads[0].lib); Ok(loads[0].lib) } @@ -155,10 +156,15 @@ impl RunCompLoader { } } let root_comp_id = dynlink.add_compartment(comp_name, new_comp_flags)?; + let allowed_gates = if new_comp_flags.contains(NewCompartmentFlags::EXPORT_GATES) { + AllowedGates::Public + } else { + AllowedGates::Private + }; let loads = UnloadOnDrop(dynlink.load_library_in_compartment( root_comp_id, root_unlib.clone(), - new_comp_flags.contains(NewCompartmentFlags::EXPORT_GATES), + allowed_gates, )?); // The dynamic linker gives us a list of loaded libraries, and which compartments they ended diff --git a/src/runtime/monitor/tests/montest-lib/Cargo.toml b/src/runtime/monitor/tests/montest-lib/Cargo.toml index 061d3a8f..8273e216 100644 --- a/src/runtime/monitor/tests/montest-lib/Cargo.toml +++ b/src/runtime/monitor/tests/montest-lib/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "rlib"] [dependencies] secgate = { path = "../../../secgate" } diff --git a/src/runtime/monitor/tests/montest-lib/src/lib.rs b/src/runtime/monitor/tests/montest-lib/src/lib.rs index e99d8efb..8a13bc5d 100644 --- a/src/runtime/monitor/tests/montest-lib/src/lib.rs +++ b/src/runtime/monitor/tests/montest-lib/src/lib.rs @@ -1,5 +1,6 @@ #![feature(naked_functions)] #![feature(thread_local)] +#![feature(linkage)] extern crate twizzler_runtime; diff --git a/src/runtime/monitor/tests/montest/src/main.rs b/src/runtime/monitor/tests/montest/src/main.rs index 27c3018c..6bbea6d2 100644 --- a/src/runtime/monitor/tests/montest/src/main.rs +++ b/src/runtime/monitor/tests/montest/src/main.rs @@ -1,29 +1,20 @@ +#![feature(linkage)] +#![feature(native_link_modifiers_as_needed)] + use std::sync::atomic::{AtomicBool, Ordering}; +extern crate montest_lib; extern crate secgate; secgate::secgate_prelude!(); +#[link(name = "montest_lib", kind = "dylib", modifiers = "-as-needed")] +extern "C" {} + extern crate tracing; extern crate tracing_subscriber; extern crate twizzler_runtime; -mod montest_lib { - #[link(name = "montest_lib")] - extern "C" {} - #[secgate::secure_gate(options(info, api))] - pub fn test_was_ctor_run(info: &GateCallInfo) -> bool {} - - #[secgate::secure_gate(options(info, api))] - pub fn test_internal_panic(info: &GateCallInfo, catch_it: bool) -> usize {} - - #[secgate::secure_gate(options(info, api))] - pub fn test_global_call_count(info: &GateCallInfo) -> usize {} - - #[secgate::secure_gate(options(info, api))] - pub fn test_thread_local_call_count(info: &GateCallInfo) -> usize {} -} - fn main() { setup_logging(); montest_lib::test_global_call_count(); diff --git a/src/runtime/secgate/secgate-macros/src/lib.rs b/src/runtime/secgate/secgate-macros/src/lib.rs index f1f59dba..ca39a03b 100644 --- a/src/runtime/secgate/secgate-macros/src/lib.rs +++ b/src/runtime/secgate/secgate-macros/src/lib.rs @@ -32,6 +32,7 @@ struct Info { pub fn_name: Ident, pub internal_fn_name: Ident, pub trampoline_name: Ident, + pub trampoline_name_without_prefix: Ident, pub entry_name: Ident, pub struct_name: Ident, pub entry_type_name: Ident, @@ -57,7 +58,8 @@ fn build_names( Info { mod_name: Ident::new(&format!("{}{}_mod", PREFIX, base), base.span()), struct_name: Ident::new(&format!("{}_info", base).to_uppercase(), base.span()), - trampoline_name: Ident::new(&format!("{}", base), base.span()), + trampoline_name: Ident::new(&format!("__TWIZZLER_SECURE_GATE_{}", base), base.span()), + trampoline_name_without_prefix: Ident::new(&format!("{}", base), base.span()), entry_name: Ident::new(&format!("{}_entry", base), base.span()), internal_fn_name: Ident::new(&format!("{}_direct", base), base.span()), entry_type_name: Ident::new(&format!("{}_EntryType", base), base.span()), @@ -195,8 +197,12 @@ fn handle_secure_gate( #struct_def #types_def // trampoline text - #link_section_text - #trampoline + mod trampoline_impl { + use super::*; + #link_section_text + #trampoline + } + #extern_trampoline } #public_call_point }) @@ -222,8 +228,7 @@ fn build_trampoline(tree: &ItemFn, names: &Info) -> Result Result Result Result { @@ -282,8 +290,6 @@ fn build_entry(tree: &ItemFn, names: &Info) -> Result Result Result Result { Ok(quote! { #[allow(non_camel_case_types)] - type #entry_type_name = #ty; + pub type #entry_type_name = #ty; pub type Args = #arg_types; pub type Ret = secgate::Return<#ret_type>; pub const ARGS_SIZE: usize = core::mem::size_of::(); diff --git a/src/srv/logboi/Cargo.toml b/src/srv/logboi/Cargo.toml new file mode 100644 index 00000000..14b4bab1 --- /dev/null +++ b/src/srv/logboi/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "logboi" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["rlib"] + +[dependencies] +secgate = { path = "../../runtime/secgate" } +twizzler-runtime = { path = "../../runtime/rt" } +logboi-srv = { path = "logboi-srv" } diff --git a/src/srv/logboi/logboi-srv/Cargo.toml b/src/srv/logboi/logboi-srv/Cargo.toml new file mode 100644 index 00000000..63a896cf --- /dev/null +++ b/src/srv/logboi/logboi-srv/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "logboi-srv" +version = "0.1.0" +edition = "2021" + +# Important: this should be compiled as both an rlib, for exporting the trampoline, +# and as a cdylib, as the actual .so file that will be exporting the gates. +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +secgate = { path = "../../../runtime/secgate" } +twizzler-runtime = { path = "../../../runtime/rt" } + +[features] diff --git a/src/srv/logboi/logboi-srv/src/lib.rs b/src/srv/logboi/logboi-srv/src/lib.rs new file mode 100644 index 00000000..bdafd0cb --- /dev/null +++ b/src/srv/logboi/logboi-srv/src/lib.rs @@ -0,0 +1,18 @@ +#![feature(naked_functions)] +#![feature(linkage)] + +use std::sync::atomic::AtomicUsize; + +extern crate twizzler_runtime; + +static NRCALL: AtomicUsize = AtomicUsize::new(0); + +pub type Bar = u32; +#[secgate::secure_gate] +pub fn foo(bar: Bar) { + println!( + "FOO: {}, {}", + bar, + NRCALL.fetch_add(1, std::sync::atomic::Ordering::SeqCst) + ); +} diff --git a/src/srv/logboi/logboi-test/Cargo.toml b/src/srv/logboi/logboi-test/Cargo.toml new file mode 100644 index 00000000..17bd0285 --- /dev/null +++ b/src/srv/logboi/logboi-test/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "logboi-test" +version = "0.1.0" +edition = "2021" + +[dependencies] +twizzler-runtime = { path = "../../../runtime/rt" } +logboi = { path = "../" } diff --git a/src/srv/logboi/logboi-test/src/main.rs b/src/srv/logboi/logboi-test/src/main.rs new file mode 100644 index 00000000..a212c11a --- /dev/null +++ b/src/srv/logboi/logboi-test/src/main.rs @@ -0,0 +1,4 @@ +fn main() { + println!("Hello, world!"); + logboi::foo(3); +} diff --git a/src/srv/logboi/src/lib.rs b/src/srv/logboi/src/lib.rs new file mode 100644 index 00000000..ec78f214 --- /dev/null +++ b/src/srv/logboi/src/lib.rs @@ -0,0 +1,4 @@ +pub use logboi_srv::{foo, Bar}; + +#[link(name = "logboi_srv")] +extern "C" {} diff --git a/tools/xtask/src/build.rs b/tools/xtask/src/build.rs index e16e37e9..2b5cd3c9 100644 --- a/tools/xtask/src/build.rs +++ b/tools/xtask/src/build.rs @@ -305,6 +305,9 @@ fn maybe_build_tests_static<'a>( "twizzler-queue" => None, "montest-lib" => None, "montest" => None, + "logboi" => None, + "logboi-srv" => None, + "logboi-test" => None, _ => Some(p.name().to_string()), }) .collect(), diff --git a/tools/xtask/src/toolchain.rs b/tools/xtask/src/toolchain.rs index 0ac05987..8b34af0f 100644 --- a/tools/xtask/src/toolchain.rs +++ b/tools/xtask/src/toolchain.rs @@ -287,9 +287,11 @@ pub(crate) fn do_bootstrap(cli: BootstrapOptions) -> anyhow::Result<()> { } pub fn set_dynamic() { + // This is a bit of a cursed linker line, but it's needed to work around some limitations in + // rust's linkage support. std::env::set_var( "RUSTFLAGS", - "-C prefer-dynamic=y -Z staticlib-prefer-dynamic=y -C link-arg=--allow-shlib-undefined", + "-C prefer-dynamic=y -Z staticlib-prefer-dynamic=y -C link-arg=--allow-shlib-undefined -C link-arg=--undefined-glob=__TWIZZLER_SECURE_GATE_* -C link-arg=--export-dynamic-symbol=__TWIZZLER_SECURE_GATE_* -C link-arg=--warn-unresolved-symbols", ); std::env::set_var("CARGO_TARGET_DIR", "target/dynamic"); }