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:
Tate, Hongliang Tian 2019-08-17 04:20:11 +00:00
parent 76f91a1aa3
commit dff0dbf77d
15 changed files with 297 additions and 111 deletions

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;

@ -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

@ -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,