Format all Rust code with cargo fmt

In addition, to ensure that all future Rust code complies with
`cargo fmt`, we add a Git post-commit hook that generates warnings
if the commited code is not formated consistently.
This commit is contained in:
Tate, Hongliang Tian 2019-08-17 07:38:16 +00:00
parent dff0dbf77d
commit 7001b32a4a
22 changed files with 314 additions and 259 deletions

@ -1,50 +1,61 @@
use super::*;
use serde::{Deserialize, Serialize};
use std::sgxfs::{SgxFile};
use std::path::{Path, PathBuf};
use std::sgxfs::SgxFile;
const LIBOS_CONFIG_PATH : &str = "Occlum.json.protected";
const LIBOS_CONFIG_PATH: &str = "Occlum.json.protected";
lazy_static! {
pub static ref LIBOS_CONFIG: Config = {
let mut config_file = {
let config_file = match SgxFile::open_integrity_only(LIBOS_CONFIG_PATH) {
Err(_) => panic!("Failed to find or open Occlum's config file: {}",
LIBOS_CONFIG_PATH),
Err(_) => panic!(
"Failed to find or open Occlum's config file: {}",
LIBOS_CONFIG_PATH
),
Ok(file) => file,
};
let actual_mac = match config_file.get_mac() {
Err(_) => panic!("Failed to get the MAC of Occlum's config file: {}",
LIBOS_CONFIG_PATH),
Err(_) => panic!(
"Failed to get the MAC of Occlum's config file: {}",
LIBOS_CONFIG_PATH
),
Ok(mac) => mac,
};
let expected_mac = conf_get_hardcoded_file_mac();
if actual_mac != expected_mac {
panic!("The MAC of Occlum's config file is not as expected: {}",
LIBOS_CONFIG_PATH);
panic!(
"The MAC of Occlum's config file is not as expected: {}",
LIBOS_CONFIG_PATH
);
}
config_file
};
let config_json = {
let mut config_json = String::new();
config_file.read_to_string(&mut config_json)
.map_err(|_| {
panic!("Failed to read from Occlum's config file: {}",
LIBOS_CONFIG_PATH);
});
config_file.read_to_string(&mut config_json).map_err(|_| {
panic!(
"Failed to read from Occlum's config file: {}",
LIBOS_CONFIG_PATH
);
});
config_json
};
let config_input: InputConfig = match serde_json::from_str(&config_json) {
Err(_) => panic!("Failed to parse JSON from Occlum's config file: {}",
LIBOS_CONFIG_PATH),
Ok(config_input) => config_input
Err(_) => panic!(
"Failed to parse JSON from Occlum's config file: {}",
LIBOS_CONFIG_PATH
),
Ok(config_input) => config_input,
};
let config = match Config::from_input(&config_input) {
Err(_) => panic!("Found invalid config in Occlum's config file: {}",
LIBOS_CONFIG_PATH),
Ok(config) => config
Err(_) => panic!(
"Found invalid config in Occlum's config file: {}",
LIBOS_CONFIG_PATH
),
Ok(config) => config,
};
config
};
@ -61,20 +72,19 @@ fn conf_get_hardcoded_file_mac() -> sgx_aes_gcm_128bit_tag_t {
.to_str()
.expect("Invalid MAC")
};
let mac = parse_mac(mac_str)
.expect("Invalid MAC");
let mac = parse_mac(mac_str).expect("Invalid MAC");
mac
}
fn parse_mac(mac_str: &str) -> Result<sgx_aes_gcm_128bit_tag_t, Error> {
let bytes_str_vec = {
let bytes_str_vec : Vec<&str> = mac_str.split("-").collect();
let bytes_str_vec: Vec<&str> = mac_str.split("-").collect();
if bytes_str_vec.len() != 16 {
return errno!(EINVAL, "The length or format of MAC string is invalid");
}
bytes_str_vec
};
let mut mac : sgx_aes_gcm_128bit_tag_t = Default::default();
let mut mac: sgx_aes_gcm_128bit_tag_t = Default::default();
for (byte_i, byte_str) in bytes_str_vec.iter().enumerate() {
mac[byte_i] = u8::from_str_radix(byte_str, 16)
.map_err(|_| Error::new(Errno::EINVAL, "The format of MAC string is invalid"))?;
@ -82,7 +92,6 @@ fn parse_mac(mac_str: &str) -> Result<sgx_aes_gcm_128bit_tag_t, Error> {
Ok(mac)
}
#[derive(Debug)]
pub struct Config {
pub vm: ConfigVM,
@ -92,7 +101,7 @@ pub struct Config {
#[derive(Debug)]
pub struct ConfigVM {
pub user_space_size : usize,
pub user_space_size: usize,
}
#[derive(Debug)]
@ -124,7 +133,6 @@ pub struct ConfigMountOptions {
pub mac: Option<sgx_aes_gcm_128bit_tag_t>,
}
impl Config {
fn from_input(input: &InputConfig) -> Result<Config, Error> {
let vm = ConfigVM::from_input(&input.vm)?;
@ -162,7 +170,7 @@ impl ConfigProcess {
impl ConfigMount {
fn from_input(input: &InputConfigMount) -> Result<ConfigMount, Error> {
const ALL_FS_TYPES : [&str; 3] = [ "sefs", "hostfs", "ramfs" ];
const ALL_FS_TYPES: [&str; 3] = ["sefs", "hostfs", "ramfs"];
let type_ = match input.type_.as_str() {
"sefs" => ConfigMountFsType::TYPE_SEFS,
@ -181,28 +189,34 @@ impl ConfigMount {
};
let source = input.source.as_ref().map(|s| PathBuf::from(s));
let options = ConfigMountOptions::from_input(&input.options)?;
Ok(ConfigMount { type_, target, source, options, })
Ok(ConfigMount {
type_,
target,
source,
options,
})
}
}
impl ConfigMountOptions {
fn from_input(input: &InputConfigMountOptions) -> Result<ConfigMountOptions, Error> {
let (integrity_only, mac) =
if !input.integrity_only {
(false, None)
} else {
if input.mac.is_none() {
return errno!(EINVAL, "MAC is expected");
}
(true, Some(parse_mac(&input.mac.as_ref().unwrap())?))
};
Ok(ConfigMountOptions { integrity_only, mac })
let (integrity_only, mac) = if !input.integrity_only {
(false, None)
} else {
if input.mac.is_none() {
return errno!(EINVAL, "MAC is expected");
}
(true, Some(parse_mac(&input.mac.as_ref().unwrap())?))
};
Ok(ConfigMountOptions {
integrity_only,
mac,
})
}
}
fn parse_memory_size(mem_str: &str) -> Result<usize, Error> {
const UNIT2FACTOR : [(&str, usize); 5]= [
const UNIT2FACTOR: [(&str, usize); 5] = [
("KB", 1024),
("MB", 1024 * 1024),
("GB", 1024 * 1024 * 1024),
@ -216,18 +230,16 @@ fn parse_memory_size(mem_str: &str) -> Result<usize, Error> {
.position(|(unit, _)| mem_str.ends_with(unit))
.ok_or_else(|| Error::new(Errno::EINVAL, "No unit"))
.map(|unit_i| &UNIT2FACTOR[unit_i])?;
let number =
match mem_str[0..mem_str.len() - unit.len()]
.trim()
.parse::<usize>()
{
Err(_) => return errno!(EINVAL, "No number"),
Ok(number) => number
};
let number = match mem_str[0..mem_str.len() - unit.len()]
.trim()
.parse::<usize>()
{
Err(_) => return errno!(EINVAL, "No number"),
Ok(number) => number,
};
Ok(number * factor)
}
#[derive(Deserialize, Debug)]
#[serde(deny_unknown_fields)]
struct InputConfig {
@ -243,7 +255,7 @@ struct InputConfig {
#[serde(deny_unknown_fields)]
struct InputConfigVM {
#[serde(default = "InputConfigVM::get_user_space_size")]
pub user_space_size : String,
pub user_space_size: String,
}
impl InputConfigVM {
@ -255,7 +267,7 @@ impl InputConfigVM {
impl Default for InputConfigVM {
fn default() -> InputConfigVM {
InputConfigVM {
user_space_size: InputConfigVM::get_user_space_size()
user_space_size: InputConfigVM::get_user_space_size(),
}
}
}

@ -81,9 +81,7 @@ fn do_boot(path_str: &str, argv: &Vec<CString>) -> Result<(), Error> {
util::mpx_util::mpx_enable()?;
// The default environment variables
let envp = vec![
CString::new("OCCLUM=yes").unwrap()
];
let envp = vec![CString::new("OCCLUM=yes").unwrap()];
let file_actions = Vec::new();
let parent = &process::IDLE_PROCESS;
process::do_spawn(&path_str, argv, &envp, &file_actions, parent)?;

@ -31,9 +31,8 @@ impl File for DevRandom {
}
Err(e) => {
if total_nbytes > 0 {
break
}
else {
break;
} else {
return Err(e);
}
}

@ -7,32 +7,32 @@ use {process, std};
use super::*;
pub use self::access::{do_access, do_faccessat, AccessFlags, AccessModes, AT_FDCWD};
use self::dev_null::DevNull;
use self::dev_random::DevRandom;
use self::dev_zero::DevZero;
pub use self::file::{File, FileRef, SgxFile, StdinFile, StdoutFile};
pub use self::file_table::{FileDesc, FileTable};
use self::inode_file::OpenOptions;
pub use self::inode_file::{INodeExt, INodeFile};
pub use self::root_inode::{ROOT_INODE};
pub use self::io_multiplexing::*;
use self::dev_null::DevNull;
use self::dev_zero::DevZero;
use self::dev_random::DevRandom;
pub use self::pipe::Pipe;
pub use self::root_inode::ROOT_INODE;
pub use self::socket_file::{AsSocket, SocketFile};
pub use self::unix_socket::{AsUnixSocket, UnixSocketFile};
use std::any::Any;
use std::mem::uninitialized;
mod access;
mod dev_null;
mod dev_random;
mod dev_zero;
mod file;
mod file_table;
mod hostfs;
mod inode_file;
mod root_inode;
mod io_multiplexing;
mod dev_null;
mod dev_zero;
mod dev_random;
mod pipe;
mod root_inode;
mod sgx_impl;
mod socket_file;
mod unix_socket;

@ -1,14 +1,14 @@
use super::*;
use super::hostfs::HostFS;
use super::sgx_impl::SgxStorage;
use super::*;
use config::{ConfigMount, ConfigMountFsType};
use std::path::{Path, PathBuf};
use rcore_fs::vfs::{FileSystem, FileType, FsError, INode};
use rcore_fs_sefs::SEFS;
use rcore_fs_sefs::dev::*;
use rcore_fs_mountfs::{MountFS, MNode};
use rcore_fs_mountfs::{MNode, MountFS};
use rcore_fs_ramfs::RamFS;
use rcore_fs_sefs::dev::*;
use rcore_fs_sefs::SEFS;
lazy_static! {
/// The root of file system
@ -26,42 +26,53 @@ lazy_static! {
};
}
fn open_or_create_root_fs_according_to(mount_config: &Vec<ConfigMount>)
-> Result<Arc<MountFS>, Error>
{
fn open_or_create_root_fs_according_to(
mount_config: &Vec<ConfigMount>,
) -> Result<Arc<MountFS>, Error> {
let root_sefs_source = {
let root_mount_config = mount_config
.iter()
.find(|m| m.target == Path::new("/"))
.ok_or_else(|| Error::new(Errno::ENOENT, "The mount point at / is not specified"))?;
if root_mount_config.type_ != ConfigMountFsType::TYPE_SEFS {
if root_mount_config.type_ != ConfigMountFsType::TYPE_SEFS {
return errno!(EINVAL, "The mount point at / must be SEFS");
}
if root_mount_config.options.integrity_only {
return errno!(EINVAL, "The root SEFS at / must be encrypted (i.e., integrity-only is not enough)");
return errno!(
EINVAL,
"The root SEFS at / must be encrypted (i.e., integrity-only is not enough)"
);
}
if root_mount_config.source.is_none() {
return errno!(EINVAL, "The root SEFS must be given a source path (on host)");
return errno!(
EINVAL,
"The root SEFS must be given a source path (on host)"
);
}
root_mount_config.source.as_ref().unwrap()
};
let root_sefs = {
SEFS::open(Box::new(SgxStorage::new(root_sefs_source, false)),
&time::OcclumTimeProvider)
SEFS::open(
Box::new(SgxStorage::new(root_sefs_source, false)),
&time::OcclumTimeProvider,
)
}
.or_else(|_| {
SEFS::create(Box::new(SgxStorage::new(root_sefs_source, false)),
&time::OcclumTimeProvider)
SEFS::create(
Box::new(SgxStorage::new(root_sefs_source, false)),
&time::OcclumTimeProvider,
)
})?;
let root_mountable_sefs = MountFS::new(root_sefs);
Ok(root_mountable_sefs)
}
fn mount_nonroot_fs_according_to(mount_config: &Vec<ConfigMount>, root: &MNode)
-> Result<(), Error>
{
fn mount_nonroot_fs_according_to(
mount_config: &Vec<ConfigMount>,
root: &MNode,
) -> Result<(), Error> {
for mc in mount_config {
if mc.target == Path::new("/") {
continue;
@ -79,10 +90,13 @@ fn mount_nonroot_fs_according_to(mount_config: &Vec<ConfigMount>, root: &MNode)
match mc.type_ {
TYPE_SEFS => {
if !mc.options.integrity_only {
return errno!(EINVAL, "Must be integrity-only SEFS")
return errno!(EINVAL, "Must be integrity-only SEFS");
}
if mc.source.is_none() {
return errno!(EINVAL, "Source is expected for integrity-only SEFS is supported")
return errno!(
EINVAL,
"Source is expected for integrity-only SEFS is supported"
);
}
let source_path = mc.source.as_ref().unwrap();
@ -93,28 +107,26 @@ fn mount_nonroot_fs_according_to(mount_config: &Vec<ConfigMount>, root: &MNode)
};
let sefs = SEFS::open(device, &time::OcclumTimeProvider)?;
mount_fs_at(sefs, &root, target_dirname)?;
},
}
TYPE_HOSTFS => {
if mc.source.is_none() {
return errno!(EINVAL, "Source is expected for HostFS")
return errno!(EINVAL, "Source is expected for HostFS");
}
let source_path = mc.source.as_ref().unwrap();
let hostfs = HostFS::new(source_path);
mount_fs_at(hostfs, &root, target_dirname)?;
},
}
TYPE_RAMFS => {
let ramfs = RamFS::new();
mount_fs_at(ramfs, &root, target_dirname)?;
},
}
}
}
Ok(())
}
fn mount_fs_at(fs: Arc<dyn FileSystem>, parent_inode: &MNode, dirname: &str)
-> Result<(), Error>
{
fn mount_fs_at(fs: Arc<dyn FileSystem>, parent_inode: &MNode, dirname: &str) -> Result<(), Error> {
let mount_dir = match parent_inode.find(false, dirname) {
Ok(existing_dir) => {
if existing_dir.metadata()?.type_ != FileType::Dir {
@ -122,9 +134,7 @@ fn mount_fs_at(fs: Arc<dyn FileSystem>, parent_inode: &MNode, dirname: &str)
}
existing_dir
}
Err(_) => {
parent_inode.create(dirname, FileType::Dir, 0o777)?
}
Err(_) => parent_inode.create(dirname, FileType::Dir, 0o777)?,
};
mount_dir.mount(fs);
Ok(())

@ -1,4 +1,4 @@
use super::{sgx_aes_gcm_128bit_tag_t};
use super::sgx_aes_gcm_128bit_tag_t;
use rcore_fs::dev::TimeProvider;
use rcore_fs::vfs::Timespec;
use rcore_fs_sefs::dev::*;
@ -31,7 +31,11 @@ impl SgxStorage {
/// It lookups cache first, if miss, then call `open_fn` to open one,
/// and add it to cache before return.
#[cfg(feature = "sgx_file_cache")]
fn get(&self, file_id: usize, open_fn: impl FnOnce(&Self) -> DevResult<LockedFile>) -> DevResult<LockedFile> {
fn get(
&self,
file_id: usize,
open_fn: impl FnOnce(&Self) -> DevResult<LockedFile>,
) -> DevResult<LockedFile> {
// query cache
let mut caches = self.file_cache.lock().unwrap();
if let Some(locked_file) = caches.get(&file_id) {
@ -46,7 +50,11 @@ impl SgxStorage {
}
/// Get file by `file_id` without cache.
#[cfg(not(feature = "sgx_file_cache"))]
fn get(&self, file_id: usize, open_fn: impl FnOnce(&Self) -> DevResult<LockedFile>) -> LockedFile {
fn get(
&self,
file_id: usize,
open_fn: impl FnOnce(&Self) -> DevResult<LockedFile>,
) -> LockedFile {
open_fn(self)
}
@ -84,11 +92,13 @@ impl Storage for SgxStorage {
// Check the MAC of the root file against the given root MAC of the storage
if file_id == 0 && self.root_mac.is_some() {
let root_file_mac = file.get_mac()
.expect("Failed to get mac");
let root_file_mac = file.get_mac().expect("Failed to get mac");
if root_file_mac != self.root_mac.unwrap() {
println!("Expected MAC = {:#?}, actual MAC = {:?}",
self.root_mac.unwrap(), root_file_mac);
println!(
"Expected MAC = {:#?}, actual MAC = {:?}",
self.root_mac.unwrap(),
root_file_mac
);
return Err(DeviceError);
}
}

@ -23,9 +23,9 @@ extern crate lazy_static;
#[macro_use]
extern crate log;
extern crate rcore_fs;
extern crate rcore_fs_sefs;
extern crate rcore_fs_ramfs;
extern crate rcore_fs_mountfs;
extern crate rcore_fs_ramfs;
extern crate rcore_fs_sefs;
#[macro_use]
extern crate derive_builder;
extern crate serde;
@ -39,9 +39,9 @@ use std::panic;
#[macro_use]
mod prelude;
mod errno;
mod entry;
mod config;
mod entry;
mod errno;
mod fs;
mod misc;
mod process;

@ -3,11 +3,11 @@ pub use self::exit::{do_exit, do_wait4, ChildProcessFilter};
pub use self::futex::{futex_op_and_flags_from_u32, futex_wait, futex_wake, FutexFlags, FutexOp};
pub use self::process::{Status, IDLE_PROCESS};
pub use self::process_table::get;
pub use self::sched::{do_sched_getaffinity, do_sched_setaffinity, CpuSet};
pub use self::spawn::{do_spawn, FileAction};
pub use self::task::{current_pid, get_current, run_task};
pub use self::thread::{do_clone, do_set_tid_address, CloneFlags, ThreadGroup};
pub use self::wait::{WaitQueue, Waiter};
pub use self::sched::{CpuSet, do_sched_getaffinity, do_sched_setaffinity};
#[allow(non_camel_case_types)]
pub type pid_t = u32;
@ -71,14 +71,14 @@ mod exit;
mod futex;
mod process;
mod process_table;
mod sched;
mod spawn;
mod task;
mod thread;
mod wait;
mod sched;
use self::task::Task;
use super::*;
use fs::{File, FileRef, FileTable};
use misc::ResourceLimitsRef;
use vm::{ProcessVM};
use vm::ProcessVM;

@ -1,7 +1,7 @@
use super::task::Task;
use super::*;
use fs::{File, FileRef, FileTable};
use vm::{ProcessVM};
use vm::ProcessVM;
lazy_static! {
// Dummy object to make all processes having a parent

@ -1,8 +1,20 @@
use super::*;
extern "C" {
fn ocall_sched_getaffinity(ret: *mut i32, errno: *mut i32, pid: i32, cpusetsize: size_t, mask: *mut c_uchar) -> sgx_status_t;
fn ocall_sched_setaffinity(ret: *mut i32, errno: *mut i32, pid: i32, cpusetsize: size_t, mask: *const c_uchar) -> sgx_status_t;
fn ocall_sched_getaffinity(
ret: *mut i32,
errno: *mut i32,
pid: i32,
cpusetsize: size_t,
mask: *mut c_uchar,
) -> sgx_status_t;
fn ocall_sched_setaffinity(
ret: *mut i32,
errno: *mut i32,
pid: i32,
cpusetsize: size_t,
mask: *const c_uchar,
) -> sgx_status_t;
}
pub struct CpuSet {
@ -11,13 +23,17 @@ pub struct CpuSet {
impl CpuSet {
pub fn new(len: usize) -> CpuSet {
let mut cpuset = CpuSet { vec: Vec::with_capacity(len) };
let mut cpuset = CpuSet {
vec: Vec::with_capacity(len),
};
cpuset.vec.resize(len, 0);
cpuset
}
pub fn from_raw_buf(ptr: *const u8, cpusize: usize) -> CpuSet {
let mut cpuset = CpuSet { vec: Vec::with_capacity(cpusize) };
let mut cpuset = CpuSet {
vec: Vec::with_capacity(cpusize),
};
let buf_slice = unsafe { std::slice::from_raw_parts(ptr, cpusize) };
cpuset.vec.extend_from_slice(buf_slice);
cpuset
@ -63,11 +79,7 @@ impl std::fmt::UpperHex for CpuSet {
}
fn find_host_tid(pid: pid_t) -> Result<pid_t, Error> {
let process_ref = if pid == 0 {
get_current()
} else {
get(pid)?
};
let process_ref = if pid == 0 { get_current() } else { get(pid)? };
let mut process = process_ref.lock().unwrap();
let host_tid = process.get_host_tid();
Ok(host_tid)

@ -86,8 +86,7 @@ impl StackBuf {
})
}
pub fn put(&self, val: u64) -> Result<*const u64, Error>
{
pub fn put(&self, val: u64) -> Result<*const u64, Error> {
let val_ptr = self.alloc(8, 8)? as *mut u64;
unsafe {
ptr::write(val_ptr, val);
@ -206,14 +205,14 @@ pub enum AuxKey {
AT_CLKTCK = 17, /* frequency at which times() increments */
/* 18...22 not used */
AT_SECURE = 23, /* secure mode boolean */
AT_SECURE = 23, /* secure mode boolean */
AT_BASE_PLATFORM = 24, /* string identifying real platform, may
* differ from AT_PLATFORM. */
AT_RANDOM = 25, /* address of 16 random bytes */
AT_HWCAP2 = 26, /* extension of AT_HWCAP */
AT_RANDOM = 25, /* address of 16 random bytes */
AT_HWCAP2 = 26, /* extension of AT_HWCAP */
/* 28...30 not used */
AT_EXECFN = 31, /* filename of program */
AT_EXECFN = 31, /* filename of program */
AT_SYSINFO = 32,
/* Occlum-specific entries */
@ -238,7 +237,8 @@ impl AuxTable {
if key == AuxKey::AT_NULL || key == AuxKey::AT_IGNORE {
return errno!(EINVAL, "Illegal key");
}
self.table.entry(key)
self.table
.entry(key)
.and_modify(|val_mut| *val_mut = val)
.or_insert(val);
Ok(())
@ -248,7 +248,7 @@ impl AuxTable {
self.table.get(&key).map(|val_ref| *val_ref)
}
pub fn del(&mut self, key: AuxKey) -> Option<u64>{
pub fn del(&mut self, key: AuxKey) -> Option<u64> {
self.table.remove(&key)
}

@ -7,7 +7,7 @@ pub fn do_init(
elf_file: &ElfFile,
elf_buf: &[u8],
ldso_elf_file: &ElfFile,
ldso_elf_buf: &[u8]
ldso_elf_buf: &[u8],
) -> Result<ProcessVM, Error> {
// Alloc all virtual memory areas
let mut code_seg = get_code_segment(elf_file)?;
@ -24,7 +24,10 @@ pub fn do_init(
let ldso_code_start = 0;
let ldso_code_end = align_down(ldso_data_seg.get_mem_addr(), ldso_data_seg.get_mem_align());
let ldso_data_start = ldso_code_end;
let ldso_data_end = align_up(ldso_data_seg.get_mem_addr() + ldso_data_seg.get_mem_size(), 4096);
let ldso_data_end = align_up(
ldso_data_seg.get_mem_addr() + ldso_data_seg.get_mem_size(),
4096,
);
let ldso_code_size = ldso_code_end - ldso_code_start;
let ldso_data_size = ldso_data_end - ldso_data_start;

@ -64,8 +64,8 @@ pub fn do_spawn<P: AsRef<Path>>(
};
let ldso_elf_file = {
let ldso_elf_file =
ElfFile::new(&ldso_elf_buf).map_err(|e| (Errno::ENOEXEC, "Failed to parse the ELF file"))?;
let ldso_elf_file = ElfFile::new(&ldso_elf_buf)
.map_err(|e| (Errno::ENOEXEC, "Failed to parse the ELF file"))?;
header::sanity_check(&ldso_elf_file)
.map_err(|e| (Errno::ENOEXEC, "Failed to parse the ELF file"))?;
/*
@ -78,15 +78,13 @@ pub fn do_spawn<P: AsRef<Path>>(
let (new_pid, new_process_ref) = {
let cwd = parent_ref.lock().unwrap().get_cwd().to_owned();
let vm = init_vm::do_init(&elf_file, &elf_buf[..],
&ldso_elf_file, &ldso_elf_buf[..])?;
let vm = init_vm::do_init(&elf_file, &elf_buf[..], &ldso_elf_file, &ldso_elf_buf[..])?;
let base_addr = vm.get_base_addr();
let auxtbl = init_auxtbl(&vm, &elf_file)?;
let task = {
let ldso_entry = {
let ldso_base_addr = vm.get_ldso_code_range().start();
let ldso_entry = ldso_base_addr +
elf_helper::get_start_address(&ldso_elf_file)?;
let ldso_entry = ldso_base_addr + elf_helper::get_start_address(&ldso_elf_file)?;
if !vm.get_ldso_code_range().contains(ldso_entry) {
return errno!(EINVAL, "Invalid program entry");
}
@ -96,8 +94,13 @@ pub fn do_spawn<P: AsRef<Path>>(
let user_stack_limit = vm.get_stack_limit();
let user_rsp = init_stack::do_init(user_stack_base, 4096, argv, envp, &auxtbl)?;
unsafe {
Task::new(ldso_entry, user_rsp,
user_stack_base, user_stack_limit, None)?
Task::new(
ldso_entry,
user_rsp,
user_stack_base,
user_stack_limit,
None,
)?
}
};
let vm_ref = Arc::new(SgxMutex::new(vm));
@ -167,10 +170,7 @@ fn init_files(parent_ref: &ProcessRef, file_actions: &[FileAction]) -> Result<Fi
Ok(file_table)
}
fn init_auxtbl(
process_vm: &ProcessVM,
elf_file: &ElfFile,
) -> Result<AuxTable, Error> {
fn init_auxtbl(process_vm: &ProcessVM, elf_file: &ElfFile) -> Result<AuxTable, Error> {
let mut auxtbl = AuxTable::new();
auxtbl.set(AuxKey::AT_PAGESZ, 4096)?;
auxtbl.set(AuxKey::AT_UID, 0)?;

@ -40,7 +40,8 @@ impl Segment {
return Err((
Errno::EINVAL,
"Memory address and file offset is not equal, per modulo",
).into());
)
.into());
}
if ph64.mem_size < ph64.file_size {
return Err((Errno::EINVAL, "Memory size must be greater than file size").into());

@ -52,7 +52,6 @@ impl Task {
}
}
lazy_static! {
static ref NEW_PROCESS_QUEUE: SgxMutex<VecDeque<ProcessRef>> =
{ SgxMutex::new(VecDeque::new()) };

@ -1,5 +1,5 @@
use super::vm::VMRange;
use super::*;
use super::vm::{VMRange};
pub struct ThreadGroup {
threads: Vec<ProcessRef>,
@ -64,9 +64,13 @@ pub fn do_clone(
let user_stack_base = user_stack_range.end();
let user_stack_limit = user_stack_range.start();
unsafe {
Task::new(thread_entry, user_rsp,
user_stack_base, user_stack_limit,
new_tls)?
Task::new(
thread_entry,
user_rsp,
user_stack_base,
user_stack_limit,
new_tls,
)?
}
};
let files_ref = current.get_files().clone();
@ -119,11 +123,9 @@ fn guess_user_stack_bound(vm: &ProcessVM, user_rsp: usize) -> Result<&VMRange, E
// The next three cases are very unlikely, but valid
else if vm.get_stack_range().contains(user_rsp) {
Ok(vm.get_stack_range())
}
else if vm.get_heap_range().contains(user_rsp) {
} else if vm.get_heap_range().contains(user_rsp) {
Ok(vm.get_heap_range())
}
else if vm.get_data_range().contains(user_rsp) {
} else if vm.get_data_range().contains(user_rsp) {
Ok(vm.get_data_range())
}
// Invalid

@ -10,12 +10,12 @@
use fs::*;
use misc::{resource_t, rlimit_t, utsname_t};
use prelude::*;
use process::{pid_t, ChildProcessFilter, CloneFlags, FileAction, FutexFlags, FutexOp, CpuSet};
use process::{pid_t, ChildProcessFilter, CloneFlags, CpuSet, FileAction, FutexFlags, FutexOp};
use std::ffi::{CStr, CString};
use std::ptr;
use time::{timeval_t, clockid_t, timespec_t};
use time::{clockid_t, timespec_t, timeval_t};
use util::mem_util::from_user::*;
use vm::{VMPerms, MMapFlags};
use vm::{MMapFlags, VMPerms};
use {fs, process, std, vm};
use super::*;
@ -175,8 +175,12 @@ pub extern "C" fn dispatch_syscall(
),
SYS_ARCH_PRCTL => do_arch_prctl(arg0 as u32, arg1 as *mut usize),
SYS_SET_TID_ADDRESS => do_set_tid_address(arg0 as *mut pid_t),
SYS_SCHED_GETAFFINITY => do_sched_getaffinity(arg0 as pid_t, arg1 as size_t, arg2 as *mut c_uchar),
SYS_SCHED_SETAFFINITY => do_sched_setaffinity(arg0 as pid_t, arg1 as size_t, arg2 as *const c_uchar),
SYS_SCHED_GETAFFINITY => {
do_sched_getaffinity(arg0 as pid_t, arg1 as size_t, arg2 as *mut c_uchar)
}
SYS_SCHED_SETAFFINITY => {
do_sched_setaffinity(arg0 as pid_t, arg1 as size_t, arg2 as *const c_uchar)
}
// memory
SYS_MMAP => do_mmap(
@ -803,7 +807,6 @@ fn do_clock_gettime(clockid: clockid_t, ts_u: *mut timespec_t) -> Result<isize,
Ok(0)
}
// FIXME: use this
const MAP_FAILED: *const c_void = ((-1) as i64) as *const c_void;
@ -962,7 +965,7 @@ fn do_set_tid_address(tidptr: *mut pid_t) -> Result<isize, Error> {
process::do_set_tid_address(tidptr).map(|tid| tid as isize)
}
fn do_sched_getaffinity(pid: pid_t, cpusize: size_t, buf: *mut c_uchar) -> Result<isize, Error> {
fn do_sched_getaffinity(pid: pid_t, cpusize: size_t, buf: *mut c_uchar) -> Result<isize, Error> {
// Construct safe Rust types
let mut buf_slice = {
check_mut_array(buf, cpusize)?;
@ -983,7 +986,7 @@ fn do_sched_getaffinity(pid: pid_t, cpusize: size_t, buf: *mut c_uchar) -> Resu
Ok(ret as isize)
}
fn do_sched_setaffinity(pid: pid_t, cpusize: size_t, buf: *const c_uchar) -> Result<isize, Error> {
fn do_sched_setaffinity(pid: pid_t, cpusize: size_t, buf: *const c_uchar) -> Result<isize, Error> {
// Convert unsafe C types into safe Rust types
let cpuset = {
check_array(buf, cpusize)?;

@ -35,7 +35,6 @@ extern "C" {
fn ocall_gettimeofday(sec: *mut time_t, usec: *mut suseconds_t) -> sgx_status_t;
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
#[allow(non_camel_case_types)]
@ -50,14 +49,14 @@ pub type clockid_t = i32;
#[derive(Debug, Copy, Clone)]
#[allow(non_camel_case_types)]
pub enum ClockID {
CLOCK_REALTIME = 0,
CLOCK_MONOTONIC = 1,
CLOCK_REALTIME = 0,
CLOCK_MONOTONIC = 1,
CLOCK_PROCESS_CPUTIME_ID = 2,
CLOCK_THREAD_CPUTIME_ID = 3,
CLOCK_MONOTONIC_RAW = 4,
CLOCK_REALTIME_COARSE = 5,
CLOCK_MONOTONIC_COARSE = 6,
CLOCK_BOOTTIME = 7,
CLOCK_THREAD_CPUTIME_ID = 3,
CLOCK_MONOTONIC_RAW = 4,
CLOCK_REALTIME_COARSE = 5,
CLOCK_MONOTONIC_COARSE = 6,
CLOCK_BOOTTIME = 7,
}
impl ClockID {
@ -81,7 +80,11 @@ pub fn do_clock_gettime(clockid: ClockID) -> Result<timespec_t, Error> {
let mut sec = 0;
let mut nsec = 0;
unsafe {
ocall_clock_gettime(clockid as clockid_t, &mut sec as *mut time_t, &mut nsec as *mut i64);
ocall_clock_gettime(
clockid as clockid_t,
&mut sec as *mut time_t,
&mut nsec as *mut i64,
);
}
Ok(timespec_t { sec, nsec })
}
@ -90,7 +93,6 @@ extern "C" {
fn ocall_clock_gettime(clockid: clockid_t, sec: *mut time_t, ns: *mut i64) -> sgx_status_t;
}
// For SEFS
pub struct OcclumTimeProvider;

@ -1,14 +1,14 @@
use fs::{File, FileDesc, FileRef};
use prelude::*;
use process::{get_current, Process, ProcessRef};
use fs::{FileDesc, FileRef, File};
use std::fmt;
mod vm_manager;
mod user_space_vm;
mod process_vm;
mod user_space_vm;
mod vm_manager;
pub use self::process_vm::{ProcessVM, ProcessVMBuilder, MMapFlags, VMPerms};
pub use self::vm_manager::{VMRange};
pub use self::process_vm::{MMapFlags, ProcessVM, ProcessVMBuilder, VMPerms};
pub use self::vm_manager::VMRange;
pub fn do_mmap(
addr: usize,

@ -1,10 +1,11 @@
use super::*;
use super::vm_manager::{VMRange, VMManager, VMMapOptionsBuilder, VMMapOptions, VMMapAddr, VMInitializer};
use super::user_space_vm::{UserSpaceVMManager, UserSpaceVMRange, USER_SPACE_VM_MANAGER};
use super::super::config;
use super::user_space_vm::{UserSpaceVMManager, UserSpaceVMRange, USER_SPACE_VM_MANAGER};
use super::vm_manager::{
VMInitializer, VMManager, VMMapAddr, VMMapOptions, VMMapOptionsBuilder, VMRange,
};
use super::*;
use std::slice;
#[derive(Debug, Default)]
pub struct ProcessVMBuilder {
code_size: usize,
@ -47,17 +48,23 @@ impl ProcessVMBuilder {
let data_size = self.data_size;
let ldso_code_size = self.ldso_code_size.unwrap_or(0);
let ldso_data_size = self.ldso_data_size.unwrap_or(0);
let heap_size = self.heap_size.unwrap_or(
config::LIBOS_CONFIG.process.default_heap_size);
let stack_size = self.stack_size.unwrap_or(
config::LIBOS_CONFIG.process.default_stack_size);
let mmap_size = self.mmap_size.unwrap_or(
config::LIBOS_CONFIG.process.default_mmap_size);
let heap_size = self
.heap_size
.unwrap_or(config::LIBOS_CONFIG.process.default_heap_size);
let stack_size = self
.stack_size
.unwrap_or(config::LIBOS_CONFIG.process.default_stack_size);
let mmap_size = self
.mmap_size
.unwrap_or(config::LIBOS_CONFIG.process.default_mmap_size);
let range_sizes = vec![
code_size, data_size,
ldso_code_size, ldso_data_size,
heap_size, stack_size,
mmap_size
code_size,
data_size,
ldso_code_size,
ldso_data_size,
heap_size,
stack_size,
mmap_size,
];
let process_range = {
@ -109,7 +116,6 @@ impl ProcessVMBuilder {
}
}
/// The per-process virtual memory
#[derive(Debug)]
pub struct ProcessVM {
@ -212,7 +218,7 @@ impl ProcessVM {
perms: VMPerms,
flags: MMapFlags,
fd: FileDesc,
offset: usize
offset: usize,
) -> Result<usize, Error> {
let addr_option = {
if flags.contains(MMapFlags::MAP_FIXED) {
@ -235,7 +241,10 @@ impl ProcessVM {
let current_ref = get_current();
let current_process = current_ref.lock().unwrap();
let file_ref = current_process.get_files().lock().unwrap().get(fd)?;
VMInitializer::LoadFromFile { file: file_ref, offset: offset }
VMInitializer::LoadFromFile {
file: file_ref,
offset: offset,
}
}
};
let mmap_options = VMMapOptionsBuilder::default()
@ -256,7 +265,6 @@ impl ProcessVM {
}
}
bitflags! {
pub struct MMapFlags : u32 {
const MAP_FILE = 0x0;
@ -283,12 +291,10 @@ bitflags! {
impl MMapFlags {
pub fn from_u32(bits: u32) -> Result<MMapFlags, Error> {
// TODO: detect non-supporting flags
MMapFlags::from_bits(bits)
.ok_or_else(|| (Errno::EINVAL, "Unknown mmap flags").into())
MMapFlags::from_bits(bits).ok_or_else(|| (Errno::EINVAL, "Unknown mmap flags").into())
}
}
bitflags! {
pub struct VMPerms : u32 {
const READ = 0x1;
@ -311,12 +317,10 @@ impl VMPerms {
}
pub fn from_u32(bits: u32) -> Result<VMPerms, Error> {
VMPerms::from_bits(bits)
.ok_or_else(|| (Errno::EINVAL, "Unknown permission bits").into())
VMPerms::from_bits(bits).ok_or_else(|| (Errno::EINVAL, "Unknown permission bits").into())
}
}
unsafe fn fill_zeros(addr: usize, size: usize) {
let ptr = addr as *mut u8;
let buf = slice::from_raw_parts_mut(ptr, size);
@ -324,4 +328,3 @@ unsafe fn fill_zeros(addr: usize, size: usize) {
*b = 0;
}
}

@ -1,5 +1,5 @@
use super::vm_manager::{VMManager, VMMapOptions, VMMapOptionsBuilder, VMRange};
use super::*;
use super::vm_manager::{VMRange, VMManager, VMMapOptionsBuilder, VMMapOptions};
/// The virtual memory manager for the entire user space
#[derive(Debug)]
@ -10,28 +10,25 @@ pub struct UserSpaceVMManager {
impl UserSpaceVMManager {
pub unsafe fn from(addr: usize, size: usize) -> Result<UserSpaceVMManager, Error> {
let vm_manager = Arc::new(SgxMutex::new(VMManager::from(addr, size)?));
Ok(UserSpaceVMManager {
vm_manager,
})
Ok(UserSpaceVMManager { vm_manager })
}
pub fn alloc(&self, size: usize) -> Result<UserSpaceVMRange, Error> {
let user_vm_range = unsafe {
let mmap_options = VMMapOptionsBuilder::default()
.size(size)
.build()?;
let mmap_options = VMMapOptionsBuilder::default().size(size).build()?;
let mut vm_manager = self.vm_manager.lock().unwrap();
let user_vm_addr = vm_manager.mmap(&mmap_options)?;
VMRange::from_unchecked(user_vm_addr, user_vm_addr + size)
};
Ok(UserSpaceVMRange::new(user_vm_range, self.vm_manager.clone()))
Ok(UserSpaceVMRange::new(
user_vm_range,
self.vm_manager.clone(),
))
}
pub fn alloc_dummy(&self) -> UserSpaceVMRange {
let empty_user_vm_range = unsafe {
VMRange::from_unchecked(0, 0)
};
let empty_user_vm_range = unsafe { VMRange::from_unchecked(0, 0) };
UserSpaceVMRange::new(empty_user_vm_range, self.vm_manager.clone())
}
}
@ -58,7 +55,6 @@ extern "C" {
pub fn vm_get_preallocated_user_space_memory(addr: &mut usize, size: &mut usize);
}
#[derive(Debug)]
pub struct UserSpaceVMRange {
vm_range: VMRange,
@ -82,8 +78,12 @@ impl Drop for UserSpaceVMRange {
fn drop(&mut self) {
let addr = self.vm_range.start();
let size = self.vm_range.size();
if size == 0 { return; }
if size == 0 {
return;
}
let mut vm_manager = self.vm_manager.lock().unwrap();
vm_manager.munmap(addr, size).expect("munmap should always succeed");
vm_manager
.munmap(addr, size)
.expect("munmap should always succeed");
}
}

@ -1,5 +1,5 @@
use super::*;
use std::{slice};
use std::slice;
#[derive(Clone, Debug)]
pub enum VMInitializer {
@ -19,12 +19,12 @@ impl VMInitializer {
match self {
VMInitializer::DoNothing() => {
// Do nothing
},
}
VMInitializer::FillZeros() => {
for b in buf {
*b = 0;
}
},
}
VMInitializer::LoadFromFile { file, offset } => {
// TODO: make sure that read_at does not move file cursor
let len = file.read_at(*offset, buf)?;
@ -37,12 +37,11 @@ impl VMInitializer {
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum VMMapAddr {
Any, // Free to choose any address
Hint(usize), // Prefer the given address
Fixed(usize), // Must be the given address
Any, // Free to choose any address
Hint(usize), // Prefer the given address
Fixed(usize), // Must be the given address
}
impl Default for VMMapAddr {
@ -51,21 +50,22 @@ impl Default for VMMapAddr {
}
}
#[derive(Builder, Debug, Default)]
#[builder(build_fn(skip), no_std)]
pub struct VMMapOptions {
size: usize,
align: usize,
addr: VMMapAddr,
initializer: VMInitializer
initializer: VMInitializer,
}
// VMMapOptionsBuilder is generated automatically, except the build function
impl VMMapOptionsBuilder {
pub fn build(&self) -> Result<VMMapOptions, Error> {
let size = {
let size = self.size.ok_or_else(|| (Errno::EINVAL, "Invalid size for mmap"))?;
let size = self
.size
.ok_or_else(|| (Errno::EINVAL, "Invalid size for mmap"))?;
if size == 0 {
return errno!(EINVAL, "Invalid size for mmap");
}
@ -82,9 +82,7 @@ impl VMMapOptionsBuilder {
let addr = self.addr.unwrap_or_default();
match addr {
// TODO: check addr + size overflow
VMMapAddr::Any => {
VMMapAddr::Any
}
VMMapAddr::Any => VMMapAddr::Any,
VMMapAddr::Hint(addr) => {
let addr = align_down(addr, PAGE_SIZE);
VMMapAddr::Hint(addr)
@ -98,8 +96,8 @@ impl VMMapOptionsBuilder {
}
};
let initializer = match self.initializer.as_ref() {
Some(initializer) => { initializer.clone() }
None => { VMInitializer::default() }
Some(initializer) => initializer.clone(),
None => VMInitializer::default(),
};
Ok(VMMapOptions {
size,
@ -124,7 +122,6 @@ impl VMMapOptions {
}
}
#[derive(Debug, Default)]
pub struct VMManager {
range: VMRange,
@ -141,20 +138,14 @@ impl VMManager {
let end_sentry = VMRange::from(end, end)?;
vec![start_sentry, end_sentry]
};
Ok(VMManager {
range,
sub_ranges,
})
Ok(VMManager { range, sub_ranges })
}
pub fn range(&self) -> &VMRange {
&self.range
}
pub fn mmap(
&mut self,
options: &VMMapOptions,
) -> Result<usize, Error> {
pub fn mmap(&mut self, options: &VMMapOptions) -> Result<usize, Error> {
// TODO: respect options.align when mmap
let addr = *options.addr();
let size = *options.size();
@ -194,22 +185,24 @@ impl VMManager {
let effective_munmap_range_opt = munmap_range.intersect(&self.range);
if effective_munmap_range_opt.is_none() {
return Ok(())
return Ok(());
}
let effective_munmap_range = effective_munmap_range_opt.unwrap();
if effective_munmap_range.empty() {
return Ok(())
return Ok(());
}
effective_munmap_range
};
let new_sub_ranges = self.sub_ranges
let new_sub_ranges = self
.sub_ranges
.iter()
.flat_map(|subrange| {
if subrange.size() > 0 {
subrange.subtract(&munmap_range)
} else { // Keep the two sentry subranges intact
} else {
// Keep the two sentry subranges intact
vec![*subrange]
}
})
@ -219,17 +212,20 @@ impl VMManager {
}
pub fn find_mmap_region(&self, addr: usize) -> Result<&VMRange, Error> {
self.sub_ranges.iter()
self.sub_ranges
.iter()
.find(|subrange| subrange.contains(addr))
.ok_or(Error::new(Errno::ESRCH,
"no mmap regions that contains the address"))
.ok_or(Error::new(
Errno::ESRCH,
"no mmap regions that contains the address",
))
}
// Find the free subrange that satisfies the constraints of size and address
fn find_free_subrange(
&mut self,
size: usize,
addr: VMMapAddr
addr: VMMapAddr,
) -> Result<(usize, VMRange), Error> {
// TODO: reduce the complexity from O(N) to O(log(N)), where N is
// the number of existing subranges.
@ -253,9 +249,7 @@ impl VMManager {
continue;
}
unsafe {
VMRange::from_unchecked(free_range_start, free_range_end)
}
unsafe { VMRange::from_unchecked(free_range_start, free_range_end) }
};
match addr {
@ -289,7 +283,8 @@ impl VMManager {
}
if result_free_range == None
|| result_free_range.as_ref().unwrap().size() > free_range.size() {
|| result_free_range.as_ref().unwrap().size() > free_range.size()
{
result_free_range = Some(free_range);
result_idx = Some(idx);
}
@ -308,7 +303,7 @@ impl VMManager {
&self,
size: usize,
addr: VMMapAddr,
free_subrange: &VMRange
free_subrange: &VMRange,
) -> VMRange {
debug_assert!(free_subrange.size() >= size);
@ -384,19 +379,22 @@ impl VMRange {
let other_end = other.end();
match (self_start < other_start, other_end < self_end) {
(false, false) => {
Vec::new()
}
(false, false) => Vec::new(),
(false, true) => unsafe {
vec![VMRange::from_unchecked(self_start.max(other_end), self_end)]
}
},
(true, false) => unsafe {
vec![VMRange::from_unchecked(self_start, self_end.min(other_start))]
}
vec![VMRange::from_unchecked(
self_start,
self_end.min(other_start),
)]
},
(true, true) => unsafe {
vec![VMRange::from_unchecked(self_start, other_start),
VMRange::from_unchecked(other_end, self_end)]
}
vec![
VMRange::from_unchecked(self_start, other_start),
VMRange::from_unchecked(other_end, self_end),
]
},
}
}
@ -407,7 +405,10 @@ impl VMRange {
return None;
}
unsafe {
Some(VMRange::from_unchecked(intersection_start, intersection_end))
Some(VMRange::from_unchecked(
intersection_start,
intersection_end,
))
}
}
}