Refactor init to cleaner/safer

This commit is contained in:
Lance Vick 2022-10-07 13:33:52 -07:00
parent 562f549935
commit fc4d8a3515
Signed by: lrvick
GPG Key ID: 8E47A1EC35A1551D
2 changed files with 103 additions and 29 deletions

View File

@ -1,7 +1,11 @@
dir /dev 0755 0 0 dir /dev 0755 0 0
dir /dev/shm 0755 0 0
dir /dev/pts 0755 0 0
nod /dev/console 0600 0 0 c 5 1 nod /dev/console 0600 0 0 c 5 1
dir /sys 0755 0 0 dir /sys 0755 0 0
dir /usr 0755 0 0 dir /usr 0755 0 0
dir /run 0755 0 0
dir /tmp 0755 0 0
dir /etc 0755 0 0 dir /etc 0755 0 0
dir /proc 0755 0 0 dir /proc 0755 0 0
dir /bin 0755 0 0 dir /bin 0755 0 0

View File

@ -1,13 +1,12 @@
extern crate libc; extern crate libc;
use libc::mount; use libc::c_ulong;
use libc::c_int;
use libc::read; use libc::read;
use libc::write; use libc::write;
use libc::close; use libc::close;
use libc::reboot; use libc::reboot;
use libc::socket; use libc::socket;
use libc::connect; use libc::connect;
use libc::freopen;
use libc::fdopen;
use libc::c_void; use libc::c_void;
use libc::sockaddr; use libc::sockaddr;
use libc::sockaddr_vm; use libc::sockaddr_vm;
@ -15,35 +14,81 @@ use libc::SOCK_STREAM;
use libc::AF_VSOCK; use libc::AF_VSOCK;
use libc::MS_NOSUID; use libc::MS_NOSUID;
use libc::MS_NOEXEC; use libc::MS_NOEXEC;
use libc::MS_NODEV;
use libc::RB_AUTOBOOT; use libc::RB_AUTOBOOT;
use std::mem::zeroed; use std::mem::zeroed;
use std::mem::size_of; use std::mem::size_of;
use std::ffi::CString;
fn main() { // Log errors to console
unsafe { pub fn error(message: String){
eprintln!("{} {}", boot_time(), message);
}
// Log info to console
pub fn info(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()
}
// libc::mount casting/error wrapper
pub fn mount(
src: &str,
target: &str,
fstype: &str,
flags: c_ulong,
data: &str,
) {
use libc::mount;
let src_cs = CString::new(src).unwrap();
let target_cs = CString::new(target).unwrap();
let fstype_cs = CString::new(fstype).unwrap();
let data_cs = CString::new(data).unwrap();
if unsafe {
mount( mount(
b"devtmpfs\0".as_ptr() as _, src_cs.as_ptr(),
b"/dev\0".as_ptr() as _, target_cs.as_ptr(),
b"devtmpfs\0".as_ptr() as _, fstype_cs.as_ptr(),
MS_NOSUID | MS_NOEXEC, flags,
b"mode=0755\0".as_ptr() as *const c_void, data_cs.as_ptr() as *const c_void
); )
freopen( } != 0 {
b"/dev/console\0".as_ptr() as _, error(format!("Failed to mount: {}", target));
b"r\0".as_ptr() as _, }
fdopen(0, b"r\0".as_ptr() as *const i8) }
);
freopen(
b"/dev/console\0".as_ptr() as _,
b"w\0".as_ptr() as _,
fdopen(1, b"w\0".as_ptr() as *const i8)
);
freopen(
b"/dev/console\0".as_ptr() as _,
b"w\0".as_ptr() as _,
fdopen(2, b"w\0".as_ptr() as *const i8) // libc::freopen casting/error wrapper
); pub fn freopen(
filename: &str,
mode: &str,
file: c_int,
) {
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() {
error(format!("Failed to freopen: {}", filename));
}
}
// Signal to hypervisor that booting was successful
pub fn heartbeat(){
let mut buf: [u8; 1] = [0; 1];
buf[0] = 0xB7; // AWS Nitro heartbeat value
unsafe {
let mut sa: sockaddr_vm = zeroed(); let mut sa: sockaddr_vm = zeroed();
sa.svm_family = AF_VSOCK as _; sa.svm_family = AF_VSOCK as _;
sa.svm_port = 9000; sa.svm_port = 9000;
@ -54,12 +99,37 @@ fn main() {
&sa as *const _ as *mut sockaddr, &sa as *const _ as *mut sockaddr,
size_of::<sockaddr_vm>() as _, size_of::<sockaddr_vm>() as _,
); );
let mut buf: [u8; 1] = [0; 1];
buf[0] = 0xB7;
write(fd, buf.as_ptr() as _, 1); write(fd, buf.as_ptr() as _, 1);
read(fd, buf.as_ptr() as _, 1); read(fd, buf.as_ptr() as _, 1);
close(fd); close(fd);
println!("Hello World from Rust init!"); }
}
// Initialize console with stdin/stdout/stderr
pub fn init_console() {
freopen("/dev/console", "r", 0);
freopen("/dev/console", "w", 1);
freopen("/dev/console", "w", 2);
}
// Mount common filesystems with conservative permissions
pub fn init_rootfs() {
mount("devtmpfs", "/dev", "devtmpfs", MS_NOSUID | MS_NOEXEC, "mode=0755");
mount("proc", "/proc", "proc", MS_NODEV | MS_NOSUID | MS_NOEXEC, "hidepid=2");
mount("tmpfs", "/run", "tmpfs", MS_NODEV | MS_NOSUID | MS_NOEXEC, "mode=0755");
mount("tmpfs", "/tmp", "tmpfs", MS_NODEV | MS_NOSUID | MS_NOEXEC, "");
mount("shm", "/dev/shm", "tmpfs", MS_NODEV | MS_NOSUID | MS_NOEXEC, "mode=0755");
mount("devpts", "/dev/pts", "devpts", MS_NOSUID | MS_NOEXEC, "");
mount("sysfs", "/sys", "sysfs", MS_NODEV | MS_NOSUID | MS_NOEXEC, "");
mount("cgroup_root", "/sys/fs/cgroup", "tmpfs", MS_NODEV | MS_NOSUID | MS_NOEXEC, "mode=0755");
}
fn main() {
init_rootfs();
init_console();
heartbeat();
info("EnclaveOS Booted".to_string());
unsafe {
reboot(RB_AUTOBOOT); reboot(RB_AUTOBOOT);
} }
} }