Refactor init to cleaner/safer
This commit is contained in:
parent
562f549935
commit
fc4d8a3515
|
@ -1,7 +1,11 @@
|
|||
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
|
||||
dir /sys 0755 0 0
|
||||
dir /usr 0755 0 0
|
||||
dir /run 0755 0 0
|
||||
dir /tmp 0755 0 0
|
||||
dir /etc 0755 0 0
|
||||
dir /proc 0755 0 0
|
||||
dir /bin 0755 0 0
|
||||
|
|
128
src/init/init.rs
128
src/init/init.rs
|
@ -1,13 +1,12 @@
|
|||
extern crate libc;
|
||||
use libc::mount;
|
||||
use libc::c_ulong;
|
||||
use libc::c_int;
|
||||
use libc::read;
|
||||
use libc::write;
|
||||
use libc::close;
|
||||
use libc::reboot;
|
||||
use libc::socket;
|
||||
use libc::connect;
|
||||
use libc::freopen;
|
||||
use libc::fdopen;
|
||||
use libc::c_void;
|
||||
use libc::sockaddr;
|
||||
use libc::sockaddr_vm;
|
||||
|
@ -15,35 +14,81 @@ use libc::SOCK_STREAM;
|
|||
use libc::AF_VSOCK;
|
||||
use libc::MS_NOSUID;
|
||||
use libc::MS_NOEXEC;
|
||||
use libc::MS_NODEV;
|
||||
use libc::RB_AUTOBOOT;
|
||||
use std::mem::zeroed;
|
||||
use std::mem::size_of;
|
||||
use std::ffi::CString;
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
// Log errors to console
|
||||
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(
|
||||
b"devtmpfs\0".as_ptr() as _,
|
||||
b"/dev\0".as_ptr() as _,
|
||||
b"devtmpfs\0".as_ptr() as _,
|
||||
MS_NOSUID | MS_NOEXEC,
|
||||
b"mode=0755\0".as_ptr() as *const c_void,
|
||||
);
|
||||
freopen(
|
||||
b"/dev/console\0".as_ptr() as _,
|
||||
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 _,
|
||||
src_cs.as_ptr(),
|
||||
target_cs.as_ptr(),
|
||||
fstype_cs.as_ptr(),
|
||||
flags,
|
||||
data_cs.as_ptr() as *const c_void
|
||||
)
|
||||
} != 0 {
|
||||
error(format!("Failed to mount: {}", target));
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
sa.svm_family = AF_VSOCK as _;
|
||||
sa.svm_port = 9000;
|
||||
|
@ -54,12 +99,37 @@ fn main() {
|
|||
&sa as *const _ as *mut sockaddr,
|
||||
size_of::<sockaddr_vm>() as _,
|
||||
);
|
||||
let mut buf: [u8; 1] = [0; 1];
|
||||
buf[0] = 0xB7;
|
||||
write(fd, buf.as_ptr() as _, 1);
|
||||
read(fd, buf.as_ptr() as _, 1);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue