cleanup, prep for exec example
This commit is contained in:
parent
c388eb1fc5
commit
b14e4260b2
10
src/main.rs
10
src/main.rs
|
@ -3,7 +3,6 @@ mod platform;
|
||||||
mod result;
|
mod result;
|
||||||
mod system;
|
mod system;
|
||||||
|
|
||||||
use platform::Platform;
|
|
||||||
use result::Result;
|
use result::Result;
|
||||||
use system::dmesg;
|
use system::dmesg;
|
||||||
|
|
||||||
|
@ -48,12 +47,11 @@ fn init() -> Result<()> {
|
||||||
|
|
||||||
system::dmesg("EnclaveOS Booted");
|
system::dmesg("EnclaveOS Booted");
|
||||||
|
|
||||||
std::thread::sleep(std::time::Duration::from_secs(500));
|
|
||||||
|
|
||||||
/*
|
|
||||||
let command = &config.target;
|
let command = &config.target;
|
||||||
match config.mode {
|
match config.mode {
|
||||||
config::Mode::Spawn => {
|
config::Mode::Spawn => {
|
||||||
|
panic!("Spawn mode has not been tested.")
|
||||||
|
/*
|
||||||
// set up a process reaper. any time a child process dies, a SIGCHLD will be fired, and
|
// set up a process reaper. any time a child process dies, a SIGCHLD will be fired, and
|
||||||
// the signal handler will reap the processes
|
// the signal handler will reap the processes
|
||||||
eprintln!("installing signal handler");
|
eprintln!("installing signal handler");
|
||||||
|
@ -64,13 +62,13 @@ fn init() -> Result<()> {
|
||||||
eprintln!("Encountered error running {command}: {e}");
|
eprintln!("Encountered error running {command}: {e}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
config::Mode::Exec => {
|
config::Mode::Exec => {
|
||||||
eprintln!("pivoting to {command}");
|
dmesg("pivoting to {command}");
|
||||||
system::syscall::execv(command, &[])?;
|
system::syscall::execv(command, &[])?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ impl Aws {
|
||||||
)?;
|
)?;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
dmesg("heartbeat =>");
|
||||||
write(fd, &buf)?;
|
write(fd, &buf)?;
|
||||||
read(fd, &mut buf)?;
|
read(fd, &mut buf)?;
|
||||||
close(fd)?;
|
close(fd)?;
|
||||||
|
@ -54,6 +55,8 @@ impl Aws {
|
||||||
.context(format_args!("Bad value from heartbeat"));
|
.context(format_args!("Bad value from heartbeat"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dmesg("<= heartbeat");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,74 +66,9 @@ impl super::Platform for Aws {
|
||||||
std::fs::exists("/dev/nsm").context(format_args!("could not check if /dev/nsm exists"))
|
std::fs::exists("/dev/nsm").context(format_args!("could not check if /dev/nsm exists"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_modules(&self) -> Result<Vec<(String, String)>> {
|
|
||||||
Ok(vec![("/nsm.ko".into(), String::new())])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn init(&self) -> Result<()> {
|
fn init(&self) -> Result<()> {
|
||||||
Self::init_heartbeat()?;
|
Self::init_heartbeat()?;
|
||||||
// enclaveos_shim::init_platform();
|
// enclaveos_shim::init_platform();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod enclaveos_shim {
|
|
||||||
use super::dmesg;
|
|
||||||
|
|
||||||
mod system {
|
|
||||||
use super::dmesg;
|
|
||||||
use std::os::fd::AsRawFd;
|
|
||||||
|
|
||||||
pub fn insmod(path: &str) {
|
|
||||||
use libc::{syscall, SYS_finit_module};
|
|
||||||
let file = std::fs::File::open(path).unwrap();
|
|
||||||
let fd = file.as_raw_fd();
|
|
||||||
if unsafe { syscall(SYS_finit_module, fd, &[0u8; 1], 0) } < 0 {
|
|
||||||
dmesg(format!("bad insert kernel module: {path}"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn socket_connect(family: libc::c_int, port: u32, cid: u32) -> libc::c_int {
|
|
||||||
use libc::{connect, sockaddr, sockaddr_vm, socket, SOCK_STREAM};
|
|
||||||
let fd = unsafe { socket(family, SOCK_STREAM, 0) };
|
|
||||||
if unsafe {
|
|
||||||
let mut sa: sockaddr_vm = std::mem::zeroed();
|
|
||||||
sa.svm_family = family as _;
|
|
||||||
sa.svm_port = port;
|
|
||||||
sa.svm_cid = cid;
|
|
||||||
connect(
|
|
||||||
fd,
|
|
||||||
&sa as *const _ as *mut sockaddr,
|
|
||||||
size_of::<sockaddr_vm>() as _,
|
|
||||||
)
|
|
||||||
} < 0
|
|
||||||
{
|
|
||||||
panic!("yikes")
|
|
||||||
} else {
|
|
||||||
fd
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn init_platform() {
|
|
||||||
use system::insmod;
|
|
||||||
// TODO: error handling
|
|
||||||
nitro_heartbeat();
|
|
||||||
|
|
||||||
// eprintln!("Loading nsm.ko");
|
|
||||||
// insmod("/nsm.ko");
|
|
||||||
}
|
|
||||||
|
|
||||||
fn nitro_heartbeat() {
|
|
||||||
use libc::{close, read, write, AF_VSOCK};
|
|
||||||
use system::socket_connect;
|
|
||||||
let mut buf: [u8; 1] = [0; 1];
|
|
||||||
buf[0] = 0xB7; // AWS Nitro heartbeat value
|
|
||||||
let fd = socket_connect(AF_VSOCK, 9000, 3);
|
|
||||||
unsafe {
|
|
||||||
write(fd, buf.as_ptr() as _, 1);
|
|
||||||
read(fd, buf.as_ptr() as _, 1);
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
dmesg("Sent NSM heartbeat");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
use crate::{system::{self, Mount, MountType}, result::Result};
|
use crate::{
|
||||||
|
result::Result,
|
||||||
|
system::{self, Mount},
|
||||||
|
};
|
||||||
|
|
||||||
pub trait Platform: std::fmt::Debug {
|
pub trait Platform: std::fmt::Debug {
|
||||||
/// Whether the current Platform is the `Self` platform.
|
/// Whether the current Platform is the `Self` platform.
|
||||||
|
@ -14,26 +17,10 @@ pub trait Platform: std::fmt::Debug {
|
||||||
|
|
||||||
/// The configuration for mounting filesystems for the platform.
|
/// The configuration for mounting filesystems for the platform.
|
||||||
///
|
///
|
||||||
/// This normally includes filesystems such as `/dev` and `/proc` that are not
|
/// Filesystems such as `/proc` and `/dev` have already been mounted. This method should be
|
||||||
/// backed by physical media.
|
/// used to define additional mounts.
|
||||||
fn get_mounts(&self) -> Result<Vec<Mount>> {
|
fn get_mounts(&self) -> Result<Vec<Mount>> {
|
||||||
use libc::{MS_NODEV, MS_NOEXEC, MS_NOSUID};
|
Ok(vec![])
|
||||||
use MountType::{DevPts, DevTmpFs, Proc, Shm, SysFs, TmpFs};
|
|
||||||
|
|
||||||
let no_se = MS_NOSUID | MS_NOEXEC;
|
|
||||||
let no_dse = no_se | MS_NODEV;
|
|
||||||
|
|
||||||
let m755 = Some("mode=0755");
|
|
||||||
|
|
||||||
Ok(vec![
|
|
||||||
Mount::new(DevTmpFs, "/dev", DevTmpFs, no_se, m755),
|
|
||||||
Mount::new(DevPts, "/dev/pts", DevPts, no_se, None),
|
|
||||||
Mount::new(Shm, "/dev/shm", TmpFs, no_dse, m755),
|
|
||||||
Mount::new(Proc, "/proc", Proc, no_dse, m755),
|
|
||||||
Mount::new(TmpFs, "/tmp", TmpFs, no_dse, None),
|
|
||||||
Mount::new(SysFs, "/sys", SysFs, no_dse, None),
|
|
||||||
Mount::new("cgroup_root", "/sys/fs/cgroup", TmpFs, no_dse, m755),
|
|
||||||
])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialize all necessary requirements for the platform.
|
/// Initialize all necessary requirements for the platform.
|
||||||
|
@ -73,22 +60,18 @@ pub fn get_current_platform(name: Option<&str>) -> Result<Option<Box<dyn Platfor
|
||||||
|
|
||||||
#[cfg(feature = "aws")]
|
#[cfg(feature = "aws")]
|
||||||
if aws::Aws.is()? {
|
if aws::Aws.is()? {
|
||||||
return Ok(Some(Box::new(aws::Aws)))
|
return Ok(Some(Box::new(aws::Aws)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(platform: &dyn Platform) -> Result<()> {
|
pub fn init(platform: &dyn Platform) -> Result<()> {
|
||||||
// Error handling strategy: If a platform is compiled in and loaded, if platform
|
// TODO: Error handling strategy: If a platform is compiled in and loaded, if platform
|
||||||
// specific error handling doesn't work, fall back to generic.
|
// specific error handling doesn't work, fall back to generic?
|
||||||
|
|
||||||
// NOTE: We need to make get_mounts _additional_ beyond a base set.
|
|
||||||
// We need `/dev/nsm` to exist so Aws.is() works.
|
|
||||||
/*
|
|
||||||
platform.get_mounts().and_then(init_filesystems)?;
|
platform.get_mounts().and_then(init_filesystems)?;
|
||||||
platform.get_modules().and_then(init_modules)?;
|
platform.get_modules().and_then(init_modules)?;
|
||||||
*/
|
|
||||||
platform.init()?;
|
platform.init()?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -85,6 +85,7 @@ impl Mount {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::similar_names)]
|
||||||
pub fn mount_default_targets() -> Result<(), Vec<CtxError>> {
|
pub fn mount_default_targets() -> Result<(), Vec<CtxError>> {
|
||||||
let no_dse = MS_NODEV | MS_NOSUID | MS_NOEXEC;
|
let no_dse = MS_NODEV | MS_NOSUID | MS_NOEXEC;
|
||||||
let no_se = MS_NOSUID | MS_NOEXEC;
|
let no_se = MS_NOSUID | MS_NOEXEC;
|
||||||
|
|
|
@ -159,14 +159,12 @@ pub use libc::sockaddr_vm;
|
||||||
|
|
||||||
// This function is unsafe since we have to pass it a C-style union.
|
// This function is unsafe since we have to pass it a C-style union.
|
||||||
pub unsafe fn connect(fd: RawFd, sockaddr: *mut libc::sockaddr, size: usize) -> Result<()> {
|
pub unsafe fn connect(fd: RawFd, sockaddr: *mut libc::sockaddr, size: usize) -> Result<()> {
|
||||||
/*
|
|
||||||
let size = u32::try_from(size).context(format_args!(
|
let size = u32::try_from(size).context(format_args!(
|
||||||
"connect(..., size = {size}) has size > {}",
|
"connect(..., size = {size}) has size > {}",
|
||||||
u32::MAX
|
u32::MAX
|
||||||
))?;
|
))?;
|
||||||
*/
|
|
||||||
|
|
||||||
match unsafe { libc::connect(fd, sockaddr, size as u32) } {
|
match unsafe { libc::connect(fd, sockaddr, size) } {
|
||||||
0 => Ok(()),
|
0 => Ok(()),
|
||||||
-1 => ctx_os_error(format_args!("error calling connect({fd}, ...)")),
|
-1 => ctx_os_error(format_args!("error calling connect({fd}, ...)")),
|
||||||
n => unreachable!("connect({fd}, ...) returned bad value: {n}"),
|
n => unreachable!("connect({fd}, ...) returned bad value: {n}"),
|
||||||
|
|
Loading…
Reference in New Issue