Skip to content

Commit

Permalink
Naming Secure Gate Service (#239)
Browse files Browse the repository at this point in the history
* Switch init to use new runtime.

* Cleanup tests.

* Reorg.

* Added secure gate naming library

* reverted changes

* refactored naming service

* removed changes in main

* did fmt

* removed unnecessary dependency

---------

Co-authored-by: Daniel Bittman <[email protected]>
  • Loading branch information
CPTforever and dbittman authored Jan 10, 2025
1 parent d4f72af commit 1af27f3
Show file tree
Hide file tree
Showing 9 changed files with 363 additions and 0 deletions.
28 changes: 28 additions & 0 deletions Cargo.lock

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

5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ members = [
"src/srv/pager-srv",
"src/bin/logboi-test",
"src/lib/virtio-net",
"src/lib/naming",
"src/srv/naming-srv",
"src/bin/naming-test",
"src/bin/object-store-test",
"src/lib/pager",
]
Expand All @@ -63,6 +66,8 @@ initrd = [
"crate:random_validation",
"crate:randtest",
"crate:genrandom",
"lib:naming-srv",
"crate:naming-test",
"crate:object-store-test",
"lib:twz-rt",
"lib:montest-lib",
Expand Down
15 changes: 15 additions & 0 deletions src/bin/init/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,21 @@ fn main() {
tracing::info!("logboi ready");
std::mem::forget(lbcomp);

let nmcomp: CompartmentHandle = CompartmentLoader::new(
"naming",
"libnaming_srv.so",
NewCompartmentFlags::EXPORT_GATES,
)
.args(&["naming"])
.load()
.unwrap();
let mut flags = nmcomp.info().flags;
while !flags.contains(CompartmentFlags::READY) {
flags = nmcomp.wait(flags);
}
tracing::info!("naming ready");
std::mem::forget(nmcomp);

let create = ObjectCreate::new(
BackingType::Normal,
LifetimeType::Volatile,
Expand Down
7 changes: 7 additions & 0 deletions src/bin/naming-test/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "naming-test"
version = "0.1.0"
edition = "2021"

[dependencies]
naming = { path = "../../lib/naming" }
18 changes: 18 additions & 0 deletions src/bin/naming-test/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use std::fs::File;

use naming::NamingHandle;

fn main() {
let mut handle = NamingHandle::new().unwrap();

match handle.get(&"hello world!") {
Some(x) => {
handle.put(&"hello world!", x - 1);
println!("{} bottles of beer on the wall. {} bottles of beer! Take one down pass it around you got {} bottles of beer on the wall", x, x, x-1);
}
None => {
handle.put(&"hello world!", 99);
println!("No more bottles of beer on the wall, no more bottles of beer! Go to the store and buy some more, {} bottles of beer on the wall...", 99);
}
}
}
12 changes: 12 additions & 0 deletions src/lib/naming/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "naming"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["rlib"]

[dependencies]
naming-srv = { path = "../../srv/naming-srv" }
secgate = { path = "../../lib/secgate" }
twizzler-rt-abi = "0.99"
86 changes: 86 additions & 0 deletions src/lib/naming/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#[link(name = "naming_srv")]
extern "C" {}

use naming_srv::{Schema, MAX_KEY_SIZE};
use secgate::util::{Descriptor, Handle, SimpleBuffer};
use twizzler_rt_abi::object::MapFlags;

pub struct NamingHandle {
desc: Descriptor,
buffer: SimpleBuffer,
}

impl Handle for NamingHandle {
type OpenError = ();

type OpenInfo = ();

fn open(_info: Self::OpenInfo) -> Result<Self, Self::OpenError>
where
Self: Sized,
{
let (desc, id) = naming_srv::open_handle().ok().flatten().ok_or(())?;
let handle =
twizzler_rt_abi::object::twz_rt_map_object(id, MapFlags::READ | MapFlags::WRITE)
.map_err(|_| ())?;
let sb = SimpleBuffer::new(handle);
Ok(Self { desc, buffer: sb })
}

fn release(&mut self) {
naming_srv::close_handle(self.desc);
}
}

impl Drop for NamingHandle {
fn drop(&mut self) {
self.release()
}
}

impl NamingHandle {
/// Open a new logging handle.
pub fn new() -> Option<Self> {
Self::open(()).ok()
}

pub fn put(&mut self, key: &str, val: u128) {
let mut buffer = [0u8; MAX_KEY_SIZE];
let key_bytes = key.as_bytes();

let length = key_bytes.len().min(MAX_KEY_SIZE);
buffer[..length].copy_from_slice(&key_bytes[..length]);

// I should write directly to the simple buffer
let mut s = naming_srv::Schema { key: buffer, val };

// Interpret schema as a slice
let bytes =
unsafe { std::mem::transmute::<Schema, [u8; std::mem::size_of::<Schema>()]>(s) };

let handle = self.buffer.write(&bytes);

naming_srv::put(self.desc);
}

pub fn get(&mut self, key: &str) -> Option<u128> {
let mut buffer = [0u8; MAX_KEY_SIZE];
let key_bytes = key.as_bytes();

let length = key_bytes.len().min(MAX_KEY_SIZE);
buffer[..length].copy_from_slice(&key_bytes[..length]);

// I should write directly to the simple buffer
let mut s = naming_srv::Schema {
key: buffer,
val: 0,
};

// Interpret schema as a slice
let bytes =
unsafe { std::mem::transmute::<Schema, [u8; std::mem::size_of::<Schema>()]>(s) };
let handle = self.buffer.write(&bytes);

naming_srv::get(self.desc).unwrap()
}
}
18 changes: 18 additions & 0 deletions src/srv/naming-srv/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "naming-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]
lazy_static = "1.5.0"
secgate = { path = "../../lib/secgate" }
twizzler-runtime = { path = "../../rt" }
twizzler-rt-abi = { path = "../../abi/rt-abi" }
twizzler-abi = { path = "../../lib/twizzler-abi" }

[features]
174 changes: 174 additions & 0 deletions src/srv/naming-srv/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
#![feature(naked_functions)]
#![feature(linkage)]

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

use lazy_static::lazy_static;
use secgate::{
secure_gate,
util::{Descriptor, HandleMgr, SimpleBuffer},
};
use twizzler_abi::{
aux::KernelInitInfo,
object::{ObjID, MAX_SIZE, NULLPAGE_SIZE},
syscall::{sys_object_create, BackingType, LifetimeType, ObjectCreate, ObjectCreateFlags},
};
use twizzler_rt_abi::object::MapFlags;

fn get_kernel_init_info() -> &'static KernelInitInfo {
unsafe {
(((twizzler_abi::slot::RESERVED_KERNEL_INIT * MAX_SIZE) + NULLPAGE_SIZE)
as *const KernelInitInfo)
.as_ref()
.unwrap()
}
}

pub struct NamespaceClient {
buffer: SimpleBuffer,
}

impl NamespaceClient {
fn new() -> Option<Self> {
// Create and map a handle for the simple buffer.
let id = sys_object_create(
ObjectCreate::new(
BackingType::Normal,
LifetimeType::Volatile,
None,
ObjectCreateFlags::empty(),
),
&[],
&[],
)
.ok()?;
let handle =
twizzler_rt_abi::object::twz_rt_map_object(id, MapFlags::WRITE | MapFlags::READ)
.ok()?;
let buffer = SimpleBuffer::new(handle);
Some(Self { buffer })
}

fn sbid(&self) -> ObjID {
self.buffer.handle().id()
}
}

pub const MAX_KEY_SIZE: usize = 256;

#[repr(C)]
pub struct Schema {
pub key: [u8; MAX_KEY_SIZE],
pub val: u128,
}

struct Namer {
handles: HandleMgr<NamespaceClient>,
names: Vec<Schema>,
count: usize,
}

impl Namer {
const fn new() -> Self {
Self {
handles: HandleMgr::new(None),
names: Vec::<Schema>::new(),
count: 0,
}
}
}

struct NamerSrv {
inner: Mutex<Namer>,
}

lazy_static! {
static ref NAMINGSERVICE: NamerSrv = {
let mut namer = Namer::new();

let init_info = get_kernel_init_info();

for n in init_info.names() {
let mut s = Schema {
key: [0u8; 256],
val: 0,
};
let bytes = n.name().as_bytes();
s.key[..bytes.len()].copy_from_slice(&bytes[..bytes.len()]);
s.val = n.id().raw();
namer.names.push(s);
}

NamerSrv {
inner: Mutex::new(namer),
}
};
}

#[secure_gate(options(info))]
pub fn put(info: &secgate::GateCallInfo, desc: Descriptor) {
let mut namer = NAMINGSERVICE.inner.lock().unwrap();
let Some(client) = namer
.handles
.lookup(info.source_context().unwrap_or(0.into()), desc)
else {
return;
};

// should use buffer rather than copying
let mut buf = [0u8; std::mem::size_of::<Schema>()];
client.buffer.read(&mut buf);
let provided =
unsafe { std::mem::transmute::<[u8; std::mem::size_of::<Schema>()], Schema>(buf) };

let foo = namer
.names
.iter_mut()
.find(|search| search.key == provided.key);
match foo {
Some(found) => found.val = provided.val,
None => namer.names.push(provided),
};
}

#[secure_gate(options(info))]
pub fn get(info: &secgate::GateCallInfo, desc: Descriptor) -> Option<u128> {
let mut namer = NAMINGSERVICE.inner.lock().unwrap();
let Some(client) = namer
.handles
.lookup(info.source_context().unwrap_or(0.into()), desc)
else {
return None;
};

let mut buf = [0u8; std::mem::size_of::<Schema>()];
client.buffer.read(&mut buf);
let provided =
unsafe { std::mem::transmute::<[u8; std::mem::size_of::<Schema>()], Schema>(buf) };

let foo: Option<&Schema> = namer.names.iter().find(|search| search.key == provided.key);
match foo {
Some(found) => Some(found.val),
None => None,
}
}

#[secure_gate(options(info))]
pub fn open_handle(info: &secgate::GateCallInfo) -> Option<(Descriptor, ObjID)> {
let mut namer = NAMINGSERVICE.inner.lock().ok()?;
let client = NamespaceClient::new()?;
let id = client.sbid();
let desc = namer
.handles
.insert(info.source_context().unwrap_or(0.into()), client)?;

Some((desc, id))
}

#[secure_gate(options(info))]
pub fn close_handle(info: &secgate::GateCallInfo, desc: Descriptor) {
let mut namer = NAMINGSERVICE.inner.lock().unwrap();
namer
.handles
.remove(info.source_context().unwrap_or(0.into()), desc);
}

0 comments on commit 1af27f3

Please sign in to comment.