Initial commit
This commit is contained in:
92
src/agent.rs
Normal file
92
src/agent.rs
Normal file
@@ -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<Self> {
|
||||
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::<c_void>(),
|
||||
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::<u8>(),
|
||||
ptr::null::<u8>(),
|
||||
0,
|
||||
);
|
||||
|
||||
// wait for agent to be finished
|
||||
syscall(
|
||||
SYS_futex,
|
||||
self.sync_mem,
|
||||
FUTEX_WAIT,
|
||||
0,
|
||||
ptr::null::<u8>(),
|
||||
ptr::null::<u8>(),
|
||||
0,
|
||||
);
|
||||
}
|
||||
}
|
||||
25
src/lib.rs
Normal file
25
src/lib.rs
Normal file
@@ -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<Mutex<Agent>> = 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()]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user