From 35a2e4d002f244b7b97ddf6be847ffc86ed73e34 Mon Sep 17 00:00:00 2001 From: Aaron Kaiser Date: Thu, 18 Apr 2024 15:41:29 +0200 Subject: [PATCH] Initial commit --- .gitignore | 1 + Cargo.lock | 31 +++++++++++++++ Cargo.toml | 11 ++++++ rust-toolchain.toml | 2 + src/agent.rs | 92 +++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 25 ++++++++++++ 6 files changed, 162 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 rust-toolchain.toml create mode 100644 src/agent.rs create mode 100644 src/lib.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..de82d80 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,31 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "agent_lib" +version = "0.1.0" +dependencies = [ + "anyhow", + "libc", + "shared_memory_heap", +] + +[[package]] +name = "anyhow" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "shared_memory_heap" +version = "0.1.0" +dependencies = [ + "libc", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..f17db80 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "agent_lib" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0.82" +libc = "0.2.153" +shared_memory_heap = { path = "../shared_memory_heap" } diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..5d56faf --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly" diff --git a/src/agent.rs b/src/agent.rs new file mode 100644 index 0000000..490b565 --- /dev/null +++ b/src/agent.rs @@ -0,0 +1,92 @@ +use anyhow::{bail, Result}; +use libc::{ + c_char, c_void, execve, fork, ftruncate, memfd_create, mmap, syscall, SYS_futex, FUTEX_WAIT, + FUTEX_WAKE, MAP_SHARED, PROT_READ, +}; +use shared_memory_heap::get_shared_mem_fd; +use std::{ffi::CString, path::Path, ptr, usize}; + +pub struct Agent { + sync_mem: *mut usize, +} + +unsafe impl Send for Agent {} + +impl Agent { + pub(crate) unsafe fn new(path: &Path) -> Result { + let data_fd = get_shared_mem_fd(); + let sync_fd = memfd_create("sync\x00".as_ptr() as *const c_char, 0); + + let err = ftruncate(sync_fd, 1024); + if err != 0 { + bail!("ftruncate failed"); + } + + let sync_mem = mmap( + ptr::null_mut::(), + 1024, + PROT_READ | PROT_READ, + MAP_SHARED, + sync_fd, + 0, + ) as *mut usize; + + if sync_mem == ptr::null_mut() { + bail!("mmap failed"); + } + + let child = fork(); + + if child == 0 { + // child + + let data_fd = CString::new(data_fd.to_string()).unwrap(); + let sync_fd = CString::new(sync_fd.to_string()).unwrap(); + let args = [data_fd.as_ptr(), sync_fd.as_ptr()]; + + execve( + path.as_os_str().as_encoded_bytes().as_ptr() as *const c_char, + args.as_ptr(), + ptr::null(), + ); + + panic!("execve failed"); + } + + // parent + + Ok(Agent { + sync_mem, + }) + } + + pub(crate) unsafe fn perform_ipc_call(&mut self, call_id: usize, ptrs: &[usize]) { + *self.sync_mem.add(1) = call_id; + + for (i, ptr) in ptrs.iter().enumerate() { + *self.sync_mem.add(i + 1) = *ptr; + } + + // wake agent + syscall( + SYS_futex, + self.sync_mem, + FUTEX_WAKE, + 1, + ptr::null::(), + ptr::null::(), + 0, + ); + + // wait for agent to be finished + syscall( + SYS_futex, + self.sync_mem, + FUTEX_WAIT, + 0, + ptr::null::(), + ptr::null::(), + 0, + ); + } +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..1148e8b --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,25 @@ +#![feature(lazy_cell)] + +mod agent; + +pub use shared_memory_heap::sharedptr::SharedPtr; + +use agent::Agent; +use std::{ + path::Path, + sync::{LazyLock, Mutex}, +}; + +static AGENT: LazyLock> = LazyLock::new(|| { + let agent_path = std::env::var("AGENT_PATH").expect("AGENT_PATH environment variable missing"); + let agent = unsafe { Agent::new(Path::new(&agent_path)).expect("Agent failed to start") }; + Mutex::new(agent) +}); + +pub fn x25519(out: &mut SharedPtr, pk: &SharedPtr, sk: &SharedPtr) { + let mut agent = AGENT.lock().unwrap(); + + unsafe { + agent.perform_ipc_call(1, &[out.get_offset(), pk.get_offset(), sk.get_offset()]); + } +}