Import init code from EnclaveOS to build standalone

This commit is contained in:
Lance Vick 2025-06-17 23:21:32 -07:00
commit 3005596663
Signed by: lrvick
GPG Key ID: 8E47A1EC35A1551D
12 changed files with 357 additions and 0 deletions

16
Containerfile Normal file
View File

@ -0,0 +1,16 @@
FROM stagex/pallet-rust@sha256:740b9ed5f2a897d45cafdc806976d84231aa50a64998610750b42a48f8daacab as build
ENV TARGET=x86_64-unknown-linux-musl
ENV RUSTFLAGS="-C target-feature=+crt-static"
ENV CARGOFLAGS="--locked --no-default-features --release --target ${TARGET}"
ADD . /src
WORKDIR /src/init
RUN cargo build ${CARGOFLAGS}
WORKDIR /rootfs
RUN cp /src/init/target/${TARGET}/release/init .
FROM scratch as package
COPY --from=build /rootfs .

5
LICENSE.md Normal file
View File

@ -0,0 +1,5 @@
Copyright 2024 Distrust, Inc.
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

13
Makefile Normal file
View File

@ -0,0 +1,13 @@
.PHONY: default
default: out/init
out:
mkdir out
out/init: out
docker build \
--tag local/init \
--progress=plain \
--output type=local,rewrite-timestamp=true,dest=out\
-f Containerfile \
src/

24
src/aws/Cargo.lock generated Normal file
View File

@ -0,0 +1,24 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aws"
version = "0.1.0"
dependencies = [
"libc",
"system",
]
[[package]]
name = "libc"
version = "0.2.174"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
[[package]]
name = "system"
version = "0.1.0"
dependencies = [
"libc",
]

10
src/aws/Cargo.toml Normal file
View File

@ -0,0 +1,10 @@
[package]
name = "aws"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
libc = "0.2.134"
system = { path = "../system"}

34
src/aws/src/lib.rs Normal file
View File

@ -0,0 +1,34 @@
use system::{dmesg, SystemError};
// Signal to Nitro hypervisor that booting was successful
fn nitro_heartbeat() {
use system::socket_connect;
use libc::{write, read, close, AF_VSOCK};
let mut buf: [u8; 1] = [0; 1];
buf[0] = 0xB7; // AWS Nitro heartbeat value
let fd = match socket_connect(AF_VSOCK, 9000, 3) {
Ok(f)=> f,
Err(e)=> {
eprintln!("{}", e);
return
},
};
unsafe {
write(fd, buf.as_ptr() as _, 1);
read(fd, buf.as_ptr() as _, 1);
close(fd);
}
dmesg(format!("Sent NSM heartbeat"));
}
// Initialize nitro device
pub fn init_platform(){
use system::insmod;
// TODO: error handling
nitro_heartbeat();
match insmod("/nsm.ko") {
Ok(())=> dmesg(format!("Loaded nsm.ko")),
Err(e)=> eprintln!("{}", e)
};
}

33
src/init/Cargo.lock generated Normal file
View File

@ -0,0 +1,33 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aws"
version = "0.1.0"
dependencies = [
"libc",
"system",
]
[[package]]
name = "init"
version = "0.1.0"
dependencies = [
"aws",
"libc",
"system",
]
[[package]]
name = "libc"
version = "0.2.134"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "329c933548736bc49fd575ee68c89e8be4d260064184389a5b77517cddd99ffb"
[[package]]
name = "system"
version = "0.1.0"
dependencies = [
"libc",
]

14
src/init/Cargo.toml Normal file
View File

@ -0,0 +1,14 @@
[package]
name = "init"
version = "0.1.0"
edition = "2021"
[dependencies]
libc = "0.2.134"
aws = { path = "../aws"}
system = { path = "../system"}
[[bin]]
name = "init"
path = "init.rs"

54
src/init/init.rs Normal file
View File

@ -0,0 +1,54 @@
use system::{reboot, freopen, mount, dmesg};
use aws::{init_platform};
// Mount common filesystems with conservative permissions
fn init_rootfs() {
use libc::{MS_NOSUID, MS_NOEXEC, MS_NODEV };
let no_dse = MS_NODEV | MS_NOSUID | MS_NOEXEC;
let no_se = MS_NOSUID | MS_NOEXEC;
let args = [
("devtmpfs", "/dev", "devtmpfs", no_se, "mode=0755"),
("devtmpfs", "/dev", "devtmpfs", no_se, "mode=0755"),
("devpts", "/dev/pts", "devpts", no_se, ""),
("shm", "/dev/shm", "tmpfs", no_dse, "mode=0755"),
("proc", "/proc", "proc", no_dse, "hidepid=2"),
("tmpfs", "/run", "tmpfs", no_dse, "mode=0755"),
("tmpfs", "/tmp", "tmpfs", no_dse, ""),
("sysfs", "/sys", "sysfs", no_dse, ""),
("cgroup_root", "/sys/fs/cgroup", "tmpfs", no_dse, "mode=0755"),
];
for (src, target, fstype, flags, data) in args {
match mount(src, target, fstype, flags, data) {
Ok(())=> dmesg(format!("Mounted {}", target)),
Err(e)=> eprintln!("{}", e),
}
}
}
// Initialize console with stdin/stdout/stderr
fn init_console() {
let args = [
("/dev/console", "r", 0),
("/dev/console", "w", 1),
("/dev/console", "w", 2),
];
for (filename, mode, file) in args {
match freopen(filename, mode, file) {
Ok(())=> {},
Err(e)=> eprintln!("{}", e),
}
}
}
fn boot(){
init_rootfs();
init_console();
init_platform();
}
fn main() {
boot();
dmesg("System booted".to_string());
reboot();
}

16
src/system/Cargo.lock generated Normal file
View File

@ -0,0 +1,16 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "libc"
version = "0.2.174"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
[[package]]
name = "system"
version = "0.1.0"
dependencies = [
"libc",
]

9
src/system/Cargo.toml Normal file
View File

@ -0,0 +1,9 @@
[package]
name = "system"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
libc = "0.2.134"

129
src/system/src/lib.rs Normal file
View File

@ -0,0 +1,129 @@
use libc::{ c_ulong, c_int, c_void };
use std::{
mem::{zeroed, size_of},
ffi::CString,
fs::File,
os::unix::io::AsRawFd,
fmt,
};
pub struct SystemError {
pub message: String,
}
impl fmt::Display for SystemError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} {}", boot_time(), self.message)
}
}
// Log dmesg formatted log to console
pub fn dmesg(message: String){
println!("{} {}", boot_time(), message);
}
// Dmesg formatted seconds since boot
pub fn boot_time() -> String {
use libc::{clock_gettime, timespec, CLOCK_BOOTTIME};
let mut t = timespec { tv_sec: 0, tv_nsec: 0 };
unsafe { clock_gettime(CLOCK_BOOTTIME, &mut t as *mut timespec); }
format!("[ {: >4}.{}]", t.tv_sec, t.tv_nsec / 1000).to_string()
}
// Unconditionally reboot the system now
pub fn reboot(){
use libc::{reboot, RB_AUTOBOOT};
unsafe {
reboot(RB_AUTOBOOT);
}
}
// libc::mount casting/error wrapper
pub fn mount(
src: &str,
target: &str,
fstype: &str,
flags: c_ulong,
data: &str,
) -> Result<(), SystemError> {
use libc::mount;
let src_cs = CString::new(src).unwrap();
let fstype_cs = CString::new(fstype).unwrap();
let data_cs = CString::new(data).unwrap();
let target_cs = CString::new(target).unwrap();
if unsafe {
mount(
src_cs.as_ptr(),
target_cs.as_ptr(),
fstype_cs.as_ptr(),
flags,
data_cs.as_ptr() as *const c_void
)
} != 0 {
Err(SystemError { message: format!("Failed to mount: {}", target) })
} else {
Ok(())
}
}
// libc::freopen casting/error wrapper
pub fn freopen(
filename: &str,
mode: &str,
file: c_int,
) -> Result<(), SystemError> {
use libc::{freopen, fdopen};
let filename_cs = CString::new(filename).unwrap();
let mode_cs = CString::new(mode).unwrap();
if unsafe {
freopen(
filename_cs.as_ptr(),
mode_cs.as_ptr(),
fdopen(file, mode_cs.as_ptr() as *const i8)
)
}.is_null() {
Err(SystemError { message: format!("Failed to freopen: {}", filename) })
} else {
Ok(())
}
}
// Insert kernel module into memory
pub fn insmod(path: &str) -> Result<(), SystemError> {
use libc::{syscall, SYS_finit_module};
let file = File::open(path).unwrap();
let fd = file.as_raw_fd();
if unsafe { syscall(SYS_finit_module, fd, &[0u8; 1], 0) } < 0 {
Err(SystemError {
message: format!("Failed to insert kernel module: {}", path)
})
} else {
Ok(())
}
}
// Instantiate a socket
pub fn socket_connect(
family: c_int,
port: u32,
cid: u32,
) -> Result<c_int, SystemError> {
use libc::{connect, socket, sockaddr, sockaddr_vm, SOCK_STREAM};
let fd = unsafe { socket(family, SOCK_STREAM, 0) };
if unsafe {
let mut sa: sockaddr_vm = 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 {
Err(SystemError {
message: format!("Failed to connect to socket: {}", family)
})
} else {
Ok(fd)
}
}