Add the integrity-only mode SEFS
* Add patch to Rust SGX SDK to enable integrity-only SgxFile * Upgrade to the new SEFS extended with the integrity-only mode * Use integrity-only SEFS for /bin and /lib in test * Add the MAC of integrity-only SEFS to Occlum.json in test * Mount multiple FS according to Occlum.json * Check the MACs of integrity-only SEFS images
This commit is contained in:
parent
76f91a1aa3
commit
dff0dbf77d
2
deps/sefs
vendored
2
deps/sefs
vendored
@ -1 +1 @@
|
|||||||
Subproject commit a843c6783ae14842225bb6777616dc707a657583
|
Subproject commit 2a7101f074439c5c70a1ad5d4d171227817eaf19
|
@ -1,6 +1,7 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::sgxfs::{SgxFile};
|
use std::sgxfs::{SgxFile};
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
const LIBOS_CONFIG_PATH : &str = "Occlum.json.protected";
|
const LIBOS_CONFIG_PATH : &str = "Occlum.json.protected";
|
||||||
|
|
||||||
@ -103,16 +104,24 @@ pub struct ConfigProcess {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ConfigMount {
|
pub struct ConfigMount {
|
||||||
pub type_: String,
|
pub type_: ConfigMountFsType,
|
||||||
pub target: String,
|
pub target: PathBuf,
|
||||||
pub source: Option<String>,
|
pub source: Option<PathBuf>,
|
||||||
pub options: ConfigMountOptions,
|
pub options: ConfigMountOptions,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
pub enum ConfigMountFsType {
|
||||||
|
TYPE_SEFS,
|
||||||
|
TYPE_HOSTFS,
|
||||||
|
TYPE_RAMFS,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ConfigMountOptions {
|
pub struct ConfigMountOptions {
|
||||||
pub integrity_only: bool,
|
pub integrity_only: bool,
|
||||||
pub mac: Option<String>,
|
pub mac: Option<sgx_aes_gcm_128bit_tag_t>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -155,21 +164,22 @@ impl ConfigMount {
|
|||||||
fn from_input(input: &InputConfigMount) -> Result<ConfigMount, Error> {
|
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_ = {
|
let type_ = match input.type_.as_str() {
|
||||||
let type_ = input.type_.to_string();
|
"sefs" => ConfigMountFsType::TYPE_SEFS,
|
||||||
if !ALL_FS_TYPES.contains(&type_.as_str()) {
|
"hostfs" => ConfigMountFsType::TYPE_HOSTFS,
|
||||||
|
"ramfs" => ConfigMountFsType::TYPE_RAMFS,
|
||||||
|
_ => {
|
||||||
return errno!(EINVAL, "Unsupported file system type");
|
return errno!(EINVAL, "Unsupported file system type");
|
||||||
}
|
}
|
||||||
type_
|
|
||||||
};
|
};
|
||||||
let target = {
|
let target = {
|
||||||
let target = input.target.clone();
|
let target = PathBuf::from(&input.target);
|
||||||
if !target.starts_with("/") {
|
if !target.starts_with("/") {
|
||||||
return errno!(EINVAL, "Target must be an absolute path");
|
return errno!(EINVAL, "Target must be an absolute path");
|
||||||
}
|
}
|
||||||
target
|
target
|
||||||
};
|
};
|
||||||
let source = input.source.clone();
|
let source = input.source.as_ref().map(|s| PathBuf::from(s));
|
||||||
let options = ConfigMountOptions::from_input(&input.options)?;
|
let options = ConfigMountOptions::from_input(&input.options)?;
|
||||||
Ok(ConfigMount { type_, target, source, options, })
|
Ok(ConfigMount { type_, target, source, options, })
|
||||||
}
|
}
|
||||||
@ -184,7 +194,7 @@ impl ConfigMountOptions {
|
|||||||
if input.mac.is_none() {
|
if input.mac.is_none() {
|
||||||
return errno!(EINVAL, "MAC is expected");
|
return errno!(EINVAL, "MAC is expected");
|
||||||
}
|
}
|
||||||
(true, input.mac.clone())
|
(true, Some(parse_mac(&input.mac.as_ref().unwrap())?))
|
||||||
};
|
};
|
||||||
Ok(ConfigMountOptions { integrity_only, mac })
|
Ok(ConfigMountOptions { integrity_only, mac })
|
||||||
}
|
}
|
||||||
|
@ -1,50 +1,5 @@
|
|||||||
use rcore_fs::vfs::{FileSystem, FileType, FsError, INode};
|
|
||||||
use rcore_fs_mountfs::{MountFS, MNode};
|
|
||||||
use rcore_fs_ramfs::RamFS;
|
|
||||||
use rcore_fs_sefs::SEFS;
|
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
use super::hostfs::HostFS;
|
|
||||||
use super::sgx_impl::SgxStorage;
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use std::fmt;
|
||||||
lazy_static! {
|
|
||||||
/// The root of file system
|
|
||||||
pub static ref ROOT_INODE: Arc<INode> = {
|
|
||||||
// Mount SEFS at /
|
|
||||||
let device = Box::new(SgxStorage::new("sefs"));
|
|
||||||
let sefs = SEFS::open(device, &time::OcclumTimeProvider)
|
|
||||||
.expect("failed to open SEFS");
|
|
||||||
let rootfs = MountFS::new(sefs);
|
|
||||||
let root = rootfs.root_inode();
|
|
||||||
|
|
||||||
fn mount_default_fs(fs: Arc<dyn FileSystem>, root: &MNode, mount_at: &str) -> Result<(), Error> {
|
|
||||||
let mount_dir = match root.find(false, mount_at) {
|
|
||||||
Ok(existing_dir) => {
|
|
||||||
if existing_dir.metadata()?.type_ != FileType::Dir {
|
|
||||||
return errno!(EIO, "not a directory");
|
|
||||||
}
|
|
||||||
existing_dir
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
root.create(mount_at, FileType::Dir, 0o777)?
|
|
||||||
}
|
|
||||||
};
|
|
||||||
mount_dir.mount(fs);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
let hostfs = HostFS::new(".");
|
|
||||||
mount_default_fs(hostfs, &root, "host")
|
|
||||||
.expect("failed to mount HostFS at /host");
|
|
||||||
|
|
||||||
let ramfs = RamFS::new();
|
|
||||||
mount_default_fs(ramfs, &root, "tmp")
|
|
||||||
.expect("failed to mount RamFS at /tmp");
|
|
||||||
|
|
||||||
root
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct INodeFile {
|
pub struct INodeFile {
|
||||||
inode: Arc<INode>,
|
inode: Arc<INode>,
|
||||||
|
@ -10,7 +10,8 @@ pub use self::access::{do_access, do_faccessat, AccessFlags, AccessModes, AT_FDC
|
|||||||
pub use self::file::{File, FileRef, SgxFile, StdinFile, StdoutFile};
|
pub use self::file::{File, FileRef, SgxFile, StdinFile, StdoutFile};
|
||||||
pub use self::file_table::{FileDesc, FileTable};
|
pub use self::file_table::{FileDesc, FileTable};
|
||||||
use self::inode_file::OpenOptions;
|
use self::inode_file::OpenOptions;
|
||||||
pub use self::inode_file::{INodeExt, INodeFile, ROOT_INODE};
|
pub use self::inode_file::{INodeExt, INodeFile};
|
||||||
|
pub use self::root_inode::{ROOT_INODE};
|
||||||
pub use self::io_multiplexing::*;
|
pub use self::io_multiplexing::*;
|
||||||
use self::dev_null::DevNull;
|
use self::dev_null::DevNull;
|
||||||
use self::dev_zero::DevZero;
|
use self::dev_zero::DevZero;
|
||||||
@ -26,6 +27,7 @@ mod file;
|
|||||||
mod file_table;
|
mod file_table;
|
||||||
mod hostfs;
|
mod hostfs;
|
||||||
mod inode_file;
|
mod inode_file;
|
||||||
|
mod root_inode;
|
||||||
mod io_multiplexing;
|
mod io_multiplexing;
|
||||||
mod dev_null;
|
mod dev_null;
|
||||||
mod dev_zero;
|
mod dev_zero;
|
||||||
|
131
src/libos/src/fs/root_inode.rs
Normal file
131
src/libos/src/fs/root_inode.rs
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
use super::*;
|
||||||
|
use super::hostfs::HostFS;
|
||||||
|
use super::sgx_impl::SgxStorage;
|
||||||
|
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_ramfs::RamFS;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
/// The root of file system
|
||||||
|
pub static ref ROOT_INODE: Arc<INode> = {
|
||||||
|
let mount_config = &config::LIBOS_CONFIG.mount;
|
||||||
|
|
||||||
|
let rootfs = open_or_create_root_fs_according_to(mount_config)
|
||||||
|
.expect("failed to create or open SEFS for /");
|
||||||
|
let root = rootfs.root_inode();
|
||||||
|
|
||||||
|
mount_nonroot_fs_according_to(mount_config, &root)
|
||||||
|
.expect("failed to create or open other FS");
|
||||||
|
|
||||||
|
root
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
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)");
|
||||||
|
}
|
||||||
|
if root_mount_config.source.is_none() {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
.or_else(|_| {
|
||||||
|
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>
|
||||||
|
{
|
||||||
|
for mc in mount_config {
|
||||||
|
if mc.target == Path::new("/") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if !mc.target.is_absolute() {
|
||||||
|
return errno!(EINVAL, "The target path must be absolute");
|
||||||
|
}
|
||||||
|
if mc.target.parent().unwrap() != Path::new("/") {
|
||||||
|
return errno!(EINVAL, "The target mount point must be under /");
|
||||||
|
}
|
||||||
|
let target_dirname = mc.target.file_name().unwrap().to_str().unwrap();
|
||||||
|
|
||||||
|
use self::ConfigMountFsType::*;
|
||||||
|
match mc.type_ {
|
||||||
|
TYPE_SEFS => {
|
||||||
|
if !mc.options.integrity_only {
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
let source_path = mc.source.as_ref().unwrap();
|
||||||
|
|
||||||
|
let device = {
|
||||||
|
let mut device = Box::new(SgxStorage::new(source_path, true));
|
||||||
|
device.set_root_mac(mc.options.mac.unwrap());
|
||||||
|
device
|
||||||
|
};
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
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>
|
||||||
|
{
|
||||||
|
let mount_dir = match parent_inode.find(false, dirname) {
|
||||||
|
Ok(existing_dir) => {
|
||||||
|
if existing_dir.metadata()?.type_ != FileType::Dir {
|
||||||
|
return errno!(EIO, "not a directory");
|
||||||
|
}
|
||||||
|
existing_dir
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
parent_inode.create(dirname, FileType::Dir, 0o777)?
|
||||||
|
}
|
||||||
|
};
|
||||||
|
mount_dir.mount(fs);
|
||||||
|
Ok(())
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
|
use super::{sgx_aes_gcm_128bit_tag_t};
|
||||||
use rcore_fs::dev::TimeProvider;
|
use rcore_fs::dev::TimeProvider;
|
||||||
use rcore_fs::vfs::Timespec;
|
use rcore_fs::vfs::Timespec;
|
||||||
use rcore_fs_sefs::dev::*;
|
use rcore_fs_sefs::dev::*;
|
||||||
@ -11,39 +12,52 @@ use std::time::{SystemTime, UNIX_EPOCH};
|
|||||||
|
|
||||||
pub struct SgxStorage {
|
pub struct SgxStorage {
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
|
integrity_only: bool,
|
||||||
file_cache: Mutex<BTreeMap<usize, LockedFile>>,
|
file_cache: Mutex<BTreeMap<usize, LockedFile>>,
|
||||||
|
root_mac: Option<sgx_aes_gcm_128bit_tag_t>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SgxStorage {
|
impl SgxStorage {
|
||||||
pub fn new(path: impl AsRef<Path>) -> Self {
|
pub fn new(path: impl AsRef<Path>, integrity_only: bool) -> Self {
|
||||||
// assert!(path.as_ref().is_dir());
|
// assert!(path.as_ref().is_dir());
|
||||||
SgxStorage {
|
SgxStorage {
|
||||||
path: path.as_ref().to_path_buf(),
|
path: path.as_ref().to_path_buf(),
|
||||||
|
integrity_only: integrity_only,
|
||||||
file_cache: Mutex::new(BTreeMap::new()),
|
file_cache: Mutex::new(BTreeMap::new()),
|
||||||
|
root_mac: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Get file by `file_id`.
|
/// Get file by `file_id`.
|
||||||
/// It lookups cache first, if miss, then call `open_fn` to open one,
|
/// It lookups cache first, if miss, then call `open_fn` to open one,
|
||||||
/// and add it to cache before return.
|
/// and add it to cache before return.
|
||||||
#[cfg(feature = "sgx_file_cache")]
|
#[cfg(feature = "sgx_file_cache")]
|
||||||
fn get(&self, file_id: usize, open_fn: impl FnOnce(&Self) -> LockedFile) -> LockedFile {
|
fn get(&self, file_id: usize, open_fn: impl FnOnce(&Self) -> DevResult<LockedFile>) -> DevResult<LockedFile> {
|
||||||
// query cache
|
// query cache
|
||||||
let mut caches = self.file_cache.lock().unwrap();
|
let mut caches = self.file_cache.lock().unwrap();
|
||||||
if let Some(locked_file) = caches.get(&file_id) {
|
if let Some(locked_file) = caches.get(&file_id) {
|
||||||
// hit, return
|
// hit, return
|
||||||
return locked_file.clone();
|
return Ok(locked_file.clone());
|
||||||
}
|
}
|
||||||
// miss, open one
|
// miss, open one
|
||||||
let locked_file = open_fn(self);
|
let locked_file = open_fn(self)?;
|
||||||
// add to cache
|
// add to cache
|
||||||
caches.insert(file_id, locked_file.clone());
|
caches.insert(file_id, locked_file.clone());
|
||||||
locked_file
|
Ok(locked_file)
|
||||||
}
|
}
|
||||||
/// Get file by `file_id` without cache.
|
/// Get file by `file_id` without cache.
|
||||||
#[cfg(not(feature = "sgx_file_cache"))]
|
#[cfg(not(feature = "sgx_file_cache"))]
|
||||||
fn get(&self, file_id: usize, open_fn: impl FnOnce(&Self) -> LockedFile) -> LockedFile {
|
fn get(&self, file_id: usize, open_fn: impl FnOnce(&Self) -> DevResult<LockedFile>) -> LockedFile {
|
||||||
open_fn(self)
|
open_fn(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the expected root MAC of the SGX storage.
|
||||||
|
///
|
||||||
|
/// By giving this root MAC, we can be sure that the root file (file_id = 0) opened
|
||||||
|
/// by the storage has a MAC that is equal to the given root MAC.
|
||||||
|
pub fn set_root_mac(&mut self, mac: sgx_aes_gcm_128bit_tag_t) -> DevResult<()> {
|
||||||
|
self.root_mac = Some(mac);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Storage for SgxStorage {
|
impl Storage for SgxStorage {
|
||||||
@ -51,15 +65,36 @@ impl Storage for SgxStorage {
|
|||||||
let locked_file = self.get(file_id, |this| {
|
let locked_file = self.get(file_id, |this| {
|
||||||
let mut path = this.path.to_path_buf();
|
let mut path = this.path.to_path_buf();
|
||||||
path.push(format!("{}", file_id));
|
path.push(format!("{}", file_id));
|
||||||
// TODO: key
|
let options = {
|
||||||
let key = [0u8; 16];
|
let mut options = OpenOptions::new();
|
||||||
let file = OpenOptions::new()
|
options.read(true).update(true);
|
||||||
.read(true)
|
options
|
||||||
.update(true)
|
};
|
||||||
.open_ex(path, &key)
|
let file = {
|
||||||
.expect("failed to open SgxFile");
|
let open_res = if !self.integrity_only {
|
||||||
LockedFile(Arc::new(Mutex::new(file)))
|
options.open(path)
|
||||||
});
|
} else {
|
||||||
|
options.open_integrity_only(path)
|
||||||
|
};
|
||||||
|
if open_res.is_err() {
|
||||||
|
return Err(DeviceError);
|
||||||
|
}
|
||||||
|
open_res.unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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");
|
||||||
|
if root_file_mac != self.root_mac.unwrap() {
|
||||||
|
println!("Expected MAC = {:#?}, actual MAC = {:?}",
|
||||||
|
self.root_mac.unwrap(), root_file_mac);
|
||||||
|
return Err(DeviceError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(LockedFile(Arc::new(Mutex::new(file))))
|
||||||
|
})?;
|
||||||
Ok(Box::new(locked_file))
|
Ok(Box::new(locked_file))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,15 +102,24 @@ impl Storage for SgxStorage {
|
|||||||
let locked_file = self.get(file_id, |this| {
|
let locked_file = self.get(file_id, |this| {
|
||||||
let mut path = this.path.to_path_buf();
|
let mut path = this.path.to_path_buf();
|
||||||
path.push(format!("{}", file_id));
|
path.push(format!("{}", file_id));
|
||||||
// TODO: key
|
let options = {
|
||||||
let key = [0u8; 16];
|
let mut options = OpenOptions::new();
|
||||||
let file = OpenOptions::new()
|
options.write(true).update(true);
|
||||||
.write(true)
|
options
|
||||||
.update(true)
|
};
|
||||||
.open_ex(path, &key)
|
let file = {
|
||||||
.expect("failed to create SgxFile");
|
let open_res = if !self.integrity_only {
|
||||||
LockedFile(Arc::new(Mutex::new(file)))
|
options.open(path)
|
||||||
});
|
} else {
|
||||||
|
options.open_integrity_only(path)
|
||||||
|
};
|
||||||
|
if open_res.is_err() {
|
||||||
|
return Err(DeviceError);
|
||||||
|
}
|
||||||
|
open_res.unwrap()
|
||||||
|
};
|
||||||
|
Ok(LockedFile(Arc::new(Mutex::new(file))))
|
||||||
|
})?;
|
||||||
Ok(Box::new(locked_file))
|
Ok(Box::new(locked_file))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ BUILD_TARGETS := $(TEST_DEPS) $(TESTS) $(BENCHES)
|
|||||||
TEST_TARGETS := $(TESTS:%=test-%)
|
TEST_TARGETS := $(TESTS:%=test-%)
|
||||||
BENCH_TARGETS := $(BENCHES:%=bench-%)
|
BENCH_TARGETS := $(BENCHES:%=bench-%)
|
||||||
CLEAN_TARGETS := $(BUILD_TARGETS:%=clean-%)
|
CLEAN_TARGETS := $(BUILD_TARGETS:%=clean-%)
|
||||||
.PHONY: all build test clean sefs $(BUILD_TARGETS) $(TEST_TARGETS) $(BENCH_TARGETS) $(CLEAN_TARGETS)
|
.PHONY: all build test clean sefs root-sefs bin-sefs lib-sefs $(BUILD_TARGETS) $(TEST_TARGETS) $(BENCH_TARGETS) $(CLEAN_TARGETS)
|
||||||
|
|
||||||
# Use echo program instead of built-in echo command in shell. This ensures
|
# Use echo program instead of built-in echo command in shell. This ensures
|
||||||
# that echo can recognize escaped sequences (with -e argument) regardless of
|
# that echo can recognize escaped sequences (with -e argument) regardless of
|
||||||
@ -29,6 +29,8 @@ NO_COLOR := \033[0m
|
|||||||
|
|
||||||
FS_PATH := fs
|
FS_PATH := fs
|
||||||
SEFS_PATH := sefs
|
SEFS_PATH := sefs
|
||||||
|
BIN_SEFS_ROOT_FILE := $(SEFS_PATH)/bin/0
|
||||||
|
LIB_SEFS_ROOT_FILE := $(SEFS_PATH)/lib/0
|
||||||
|
|
||||||
#############################################################################
|
#############################################################################
|
||||||
# Build targets
|
# Build targets
|
||||||
@ -43,33 +45,60 @@ $(BUILD_TARGETS): %:
|
|||||||
@$(MAKE) --no-print-directory -C $@
|
@$(MAKE) --no-print-directory -C $@
|
||||||
@$(ECHO) "$(GREEN)DONE$(NO_COLOR)"
|
@$(ECHO) "$(GREEN)DONE$(NO_COLOR)"
|
||||||
|
|
||||||
sefs:
|
sefs: root-sefs bin-sefs lib-sefs
|
||||||
@$(RM) -rf $(SEFS_PATH)
|
|
||||||
|
root-sefs:
|
||||||
|
@mkdir -p $(SEFS_PATH)/root/
|
||||||
|
@echo "SEFS => $@"
|
||||||
|
|
||||||
|
bin-sefs:
|
||||||
|
@mkdir -p $(FS_PATH)/bin/
|
||||||
|
@for test in $(TESTS) ; do \
|
||||||
|
cp "$$test/$$test" $(FS_PATH)/bin/ ; \
|
||||||
|
done
|
||||||
|
@rm -rf $(SEFS_PATH)/bin
|
||||||
|
@mkdir -p $(SEFS_PATH)
|
||||||
|
@cd $(PROJECT_DIR)/deps/sefs/sefs-fuse/bin/ && \
|
||||||
|
./app \
|
||||||
|
--integrity-only \
|
||||||
|
$(CUR_DIR)/$(SEFS_PATH)/bin \
|
||||||
|
$(CUR_DIR)/$(FS_PATH)/bin \
|
||||||
|
zip
|
||||||
|
@echo "SEFS => $@"
|
||||||
|
|
||||||
|
lib-sefs:
|
||||||
@mkdir -p $(FS_PATH)/lib/
|
@mkdir -p $(FS_PATH)/lib/
|
||||||
@cp /lib/ld-musl-x86_64.so.1 $(FS_PATH)/lib/
|
@cp /lib/ld-musl-x86_64.so.1 $(FS_PATH)/lib/
|
||||||
@cp /usr/local/occlum/lib/libc++.so.1 $(FS_PATH)/lib/
|
@cp /usr/local/occlum/lib/libc++.so.1 $(FS_PATH)/lib/
|
||||||
@cp /usr/local/occlum/lib/libc++abi.so.1 $(FS_PATH)/lib/
|
@cp /usr/local/occlum/lib/libc++abi.so.1 $(FS_PATH)/lib/
|
||||||
@cp /usr/local/occlum/lib/libunwind.so.1 $(FS_PATH)/lib/
|
@cp /usr/local/occlum/lib/libunwind.so.1 $(FS_PATH)/lib/
|
||||||
|
@rm -rf $(SEFS_PATH)/lib
|
||||||
|
@mkdir -p $(SEFS_PATH)
|
||||||
@cd $(PROJECT_DIR)/deps/sefs/sefs-fuse/bin/ && \
|
@cd $(PROJECT_DIR)/deps/sefs/sefs-fuse/bin/ && \
|
||||||
./app \
|
./app \
|
||||||
$(CUR_DIR)/$(SEFS_PATH) \
|
--integrity-only \
|
||||||
$(CUR_DIR)/$(FS_PATH) \
|
$(CUR_DIR)/$(SEFS_PATH)/lib \
|
||||||
|
$(CUR_DIR)/$(FS_PATH)/lib \
|
||||||
zip
|
zip
|
||||||
@echo "SEFS => $@"
|
@echo "SEFS => $@"
|
||||||
|
|
||||||
libocclum.signed.so: Occlum.json Enclave_config.xml Enclave_private.pem
|
libocclum.signed.so: Occlum.json Enclave_config.xml Enclave_private.pem
|
||||||
@$(PROJECT_DIR)/tools/bin/build-enclave Occlum.json Enclave_config.xml Enclave_private.pem
|
@$(PROJECT_DIR)/tools/bin/build-enclave Occlum.json Enclave_config.xml Enclave_private.pem
|
||||||
|
|
||||||
|
Occlum.json: Occlum.json.sh $(BIN_SEFS_ROOT_FILE) $(LIB_SEFS_ROOT_FILE)
|
||||||
|
@./Occlum.json.sh \
|
||||||
|
`$(PROJECT_DIR)/tools/bin/protect-integrity show-mac $(BIN_SEFS_ROOT_FILE)` \
|
||||||
|
`$(PROJECT_DIR)/tools/bin/protect-integrity show-mac $(LIB_SEFS_ROOT_FILE)` \
|
||||||
|
> $@
|
||||||
|
@echo "GEN => $@"
|
||||||
|
|
||||||
#############################################################################
|
#############################################################################
|
||||||
# Test targets
|
# Test targets
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
||||||
test: build $(TEST_TARGETS)
|
test: build $(TEST_TARGETS)
|
||||||
|
|
||||||
pal: $(PROJECT_DIR)/src/pal/pal
|
$(TEST_TARGETS): test-%: % pal
|
||||||
@cp $< pal
|
|
||||||
|
|
||||||
$(TEST_TARGETS): test-%: % pal libocclum.signed.so
|
|
||||||
@$(ECHO) "$(CYAN)RUN TEST => $<$(NO_COLOR)"
|
@$(ECHO) "$(CYAN)RUN TEST => $<$(NO_COLOR)"
|
||||||
@$(MAKE) --no-print-directory -C $< test ; \
|
@$(MAKE) --no-print-directory -C $< test ; \
|
||||||
if [ $$? -eq 0 ] ; then \
|
if [ $$? -eq 0 ] ; then \
|
||||||
@ -78,6 +107,13 @@ $(TEST_TARGETS): test-%: % pal libocclum.signed.so
|
|||||||
$(ECHO) "$(RED)FAILED$(NO_COLOR)" ; \
|
$(ECHO) "$(RED)FAILED$(NO_COLOR)" ; \
|
||||||
fi ;
|
fi ;
|
||||||
|
|
||||||
|
pal: $(PROJECT_DIR)/src/pal/pal
|
||||||
|
@cp $< pal
|
||||||
|
|
||||||
|
$(PROJECT_DIR)/src/pal/pal:
|
||||||
|
@cd $(PROJECT_DIR)/src/pal && make
|
||||||
|
|
||||||
|
|
||||||
#############################################################################
|
#############################################################################
|
||||||
# Benchmark targets
|
# Benchmark targets
|
||||||
#############################################################################
|
#############################################################################
|
||||||
@ -98,7 +134,7 @@ $(BENCH_TARGETS): bench-%: % pal libocclum.signed.so
|
|||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
||||||
clean: $(CLEAN_TARGETS)
|
clean: $(CLEAN_TARGETS)
|
||||||
@$(RM) -f pal libocclum.signed.so Occlum.json.protected
|
@$(RM) -f pal libocclum.signed.so Occlum.json.protected Occlum.json
|
||||||
@$(RM) -rf $(FS_PATH) $(SEFS_PATH)
|
@$(RM) -rf $(FS_PATH) $(SEFS_PATH)
|
||||||
|
|
||||||
$(CLEAN_TARGETS): clean-%:
|
$(CLEAN_TARGETS): clean-%:
|
||||||
|
21
test/Occlum.json → test/Occlum.json.sh
Normal file → Executable file
21
test/Occlum.json → test/Occlum.json.sh
Normal file → Executable file
@ -1,3 +1,8 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
bin_sefs_mac=$1
|
||||||
|
lib_sefs_mac=$2
|
||||||
|
|
||||||
|
cat <<EOF
|
||||||
{
|
{
|
||||||
"vm": {
|
"vm": {
|
||||||
"user_space_size": "128MB"
|
"user_space_size": "128MB"
|
||||||
@ -11,15 +16,24 @@
|
|||||||
{
|
{
|
||||||
"target": "/",
|
"target": "/",
|
||||||
"type": "sefs",
|
"type": "sefs",
|
||||||
"source": "./root_sefs"
|
"source": "./sefs/root"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"target": "/bin",
|
"target": "/bin",
|
||||||
"type": "sefs",
|
"type": "sefs",
|
||||||
"source": "./bin_sefs",
|
"source": "./sefs/bin",
|
||||||
"options": {
|
"options": {
|
||||||
"integrity_only": true,
|
"integrity_only": true,
|
||||||
"MAC": "00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-"
|
"MAC": "$bin_sefs_mac"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"target": "/lib",
|
||||||
|
"type": "sefs",
|
||||||
|
"source": "./sefs/lib",
|
||||||
|
"options": {
|
||||||
|
"integrity_only": true,
|
||||||
|
"MAC": "$lib_sefs_mac"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -33,3 +47,4 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
EOF
|
@ -25,7 +25,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
posix_spawn_file_actions_addclose(&file_actions, pipe_rd_fd);
|
posix_spawn_file_actions_addclose(&file_actions, pipe_rd_fd);
|
||||||
|
|
||||||
const char* msg = "Echo!\n";
|
const char* msg = "Echo!\n";
|
||||||
const char* child_prog = "hello_world";
|
const char* child_prog = "/bin/hello_world";
|
||||||
const char* child_argv[3] = { child_prog, msg, NULL };
|
const char* child_argv[3] = { child_prog, msg, NULL };
|
||||||
int child_pid;
|
int child_pid;
|
||||||
if (posix_spawn(&child_pid, child_prog, &file_actions,
|
if (posix_spawn(&child_pid, child_prog, &file_actions,
|
||||||
|
@ -63,7 +63,7 @@ static int test_sched_xetaffinity_with_child_pid() {
|
|||||||
cpu_set_t mask;
|
cpu_set_t mask;
|
||||||
CPU_ZERO(&mask);
|
CPU_ZERO(&mask);
|
||||||
CPU_SET(num - 1 , &mask);
|
CPU_SET(num - 1 , &mask);
|
||||||
int ret = posix_spawn(&child_pid, "getpid", NULL, NULL, NULL, NULL);
|
int ret = posix_spawn(&child_pid, "/bin/getpid", NULL, NULL, NULL, NULL);
|
||||||
if (ret < 0 ) {
|
if (ret < 0 ) {
|
||||||
throw_error("spawn process error");
|
throw_error("spawn process error");
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ int main(int argc, const char *argv[]) {
|
|||||||
|
|
||||||
int client_pid;
|
int client_pid;
|
||||||
char* client_argv[] = {"client", "127.0.0.1"};
|
char* client_argv[] = {"client", "127.0.0.1"};
|
||||||
ret = posix_spawn(&client_pid, "client", NULL, NULL, client_argv, NULL);
|
ret = posix_spawn(&client_pid, "/bin/client", NULL, NULL, client_argv, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printf("spawn client process error: %s(errno: %d)\n", strerror(errno), errno);
|
printf("spawn client process error: %s(errno: %d)\n", strerror(errno), errno);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -67,7 +67,7 @@ main(int argc, char *argv[]) {
|
|||||||
int client_pid;
|
int client_pid;
|
||||||
char* client_argv[] = {"client", "127.0.0.1"};
|
char* client_argv[] = {"client", "127.0.0.1"};
|
||||||
for(int i=0; i<3; ++i) {
|
for(int i=0; i<3; ++i) {
|
||||||
int ret = posix_spawn(&client_pid, "client", NULL, NULL, client_argv, NULL);
|
int ret = posix_spawn(&client_pid, "/bin/client", NULL, NULL, client_argv, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printf("spawn client process error: %s(errno: %d)\n", strerror(errno), errno);
|
printf("spawn client process error: %s(errno: %d)\n", strerror(errno), errno);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -8,7 +8,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
int ret, child_pid, status;
|
int ret, child_pid, status;
|
||||||
printf("Run a parent process has pid = %d and ppid = %d\n", getpid(), getppid());
|
printf("Run a parent process has pid = %d and ppid = %d\n", getpid(), getppid());
|
||||||
|
|
||||||
ret = posix_spawn(&child_pid, "getpid", NULL, NULL, NULL, NULL);
|
ret = posix_spawn(&child_pid, "/bin/getpid", NULL, NULL, NULL, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printf("ERROR: failed to spawn a child process\n");
|
printf("ERROR: failed to spawn a child process\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -11,8 +11,6 @@ C_OBJS := $(C_SRCS:%.c=%.o)
|
|||||||
CXX_OBJS := $(CXX_SRCS:%.cc=%.o)
|
CXX_OBJS := $(CXX_SRCS:%.cc=%.o)
|
||||||
FS_PATH := ../fs
|
FS_PATH := ../fs
|
||||||
BIN_NAME := $(shell basename $(CUR_DIR))
|
BIN_NAME := $(shell basename $(CUR_DIR))
|
||||||
BIN_FS_PATH := $(BIN_NAME)
|
|
||||||
BIN_PATH := $(FS_PATH)/$(BIN_FS_PATH)
|
|
||||||
OBJDUMP_FILE := bin.objdump
|
OBJDUMP_FILE := bin.objdump
|
||||||
READELF_FILE := bin.readelf
|
READELF_FILE := bin.readelf
|
||||||
|
|
||||||
@ -28,12 +26,7 @@ LINK_FLAGS = $(C_FLAGS) -pie $(EXTRA_LINK_FLAGS)
|
|||||||
# Build
|
# Build
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
||||||
all: $(BIN_PATH)
|
all: $(BIN_NAME)
|
||||||
|
|
||||||
$(BIN_PATH): $(BIN_NAME)
|
|
||||||
@mkdir -p $(shell dirname $@)
|
|
||||||
@cp $^ $@
|
|
||||||
@echo "COPY => $@"
|
|
||||||
|
|
||||||
# Compile C/C++ test program
|
# Compile C/C++ test program
|
||||||
#
|
#
|
||||||
@ -61,7 +54,7 @@ $(CXX_OBJS): %.o: %.cc
|
|||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
||||||
test: $(BIN_ENC_NAME)
|
test: $(BIN_ENC_NAME)
|
||||||
@cd $(CUR_DIR)/.. && RUST_BACKTRACE=1 ./pal $(BIN_FS_PATH) $(BIN_ARGS)
|
@cd $(CUR_DIR)/.. && RUST_BACKTRACE=1 ./pal /bin/$(BIN_NAME) $(BIN_ARGS)
|
||||||
|
|
||||||
#############################################################################
|
#############################################################################
|
||||||
# Misc
|
# Misc
|
||||||
|
@ -83,7 +83,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
posix_spawn_file_actions_addclose(&file_actions, socket_rd_fd);
|
posix_spawn_file_actions_addclose(&file_actions, socket_rd_fd);
|
||||||
|
|
||||||
const char* msg = "Echo!\n";
|
const char* msg = "Echo!\n";
|
||||||
const char* child_prog = "hello_world";
|
const char* child_prog = "/bin/hello_world";
|
||||||
const char* child_argv[3] = { child_prog, msg, NULL };
|
const char* child_argv[3] = { child_prog, msg, NULL };
|
||||||
int child_pid;
|
int child_pid;
|
||||||
if (posix_spawn(&child_pid, child_prog, &file_actions,
|
if (posix_spawn(&child_pid, child_prog, &file_actions,
|
||||||
|
Loading…
Reference in New Issue
Block a user