Combine two config json files as one
This commit is contained in:
parent
0fef286df2
commit
2347951743
@ -39,14 +39,6 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
const IMAGE_CONFIG_FILE: &str = "/etc/image_config.json";
|
const IMAGE_CONFIG_FILE: &str = "/etc/image_config.json";
|
||||||
let image_config = load_config(IMAGE_CONFIG_FILE)?;
|
let image_config = load_config(IMAGE_CONFIG_FILE)?;
|
||||||
|
|
||||||
// Get the MAC of Occlum.json.protected file
|
|
||||||
let occlum_json_mac = {
|
|
||||||
let mut mac: sgx_aes_gcm_128bit_tag_t = Default::default();
|
|
||||||
parse_str_to_bytes(&image_config.occlum_json_mac, &mut mac)?;
|
|
||||||
mac
|
|
||||||
};
|
|
||||||
let occlum_json_mac_ptr = &occlum_json_mac as *const sgx_aes_gcm_128bit_tag_t;
|
|
||||||
|
|
||||||
// Get client secrets through grpc-ratls
|
// Get client secrets through grpc-ratls
|
||||||
let server_addr = CString::new("localhost:50051").unwrap();
|
let server_addr = CString::new("localhost:50051").unwrap();
|
||||||
let config_json = CString::new("dynamic_config.json").unwrap();
|
let config_json = CString::new("dynamic_config.json").unwrap();
|
||||||
@ -136,7 +128,10 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
|
|
||||||
// Mount the image
|
// Mount the image
|
||||||
const SYS_MOUNT_FS: i64 = 363;
|
const SYS_MOUNT_FS: i64 = 363;
|
||||||
let ret = unsafe { syscall(SYS_MOUNT_FS, key_ptr, occlum_json_mac_ptr) };
|
// User can provide valid path for runtime mount and boot
|
||||||
|
// Otherwise, just pass null pointer to do general mount and boot
|
||||||
|
let root_config_path: *const i8 = std::ptr::null();
|
||||||
|
let ret = unsafe { syscall(SYS_MOUNT_FS, key_ptr, root_config_path) };
|
||||||
if ret < 0 {
|
if ret < 0 {
|
||||||
return Err(Box::new(std::io::Error::last_os_error()));
|
return Err(Box::new(std::io::Error::last_os_error()));
|
||||||
}
|
}
|
||||||
@ -150,13 +145,10 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
type sgx_key_128bit_t = [u8; 16];
|
type sgx_key_128bit_t = [u8; 16];
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
type sgx_aes_gcm_128bit_tag_t = [u8; 16];
|
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct ImageConfig {
|
struct ImageConfig {
|
||||||
occlum_json_mac: String,
|
|
||||||
image_type: String,
|
image_type: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,14 +62,6 @@
|
|||||||
"target": "/host",
|
"target": "/host",
|
||||||
"type": "hostfs",
|
"type": "hostfs",
|
||||||
"source": "."
|
"source": "."
|
||||||
},
|
|
||||||
{
|
|
||||||
"target": "/proc",
|
|
||||||
"type": "procfs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"target": "/dev",
|
|
||||||
"type": "devfs"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -29,14 +29,6 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
const IMAGE_CONFIG_FILE: &str = "/etc/image_config.json";
|
const IMAGE_CONFIG_FILE: &str = "/etc/image_config.json";
|
||||||
let image_config = load_config(IMAGE_CONFIG_FILE)?;
|
let image_config = load_config(IMAGE_CONFIG_FILE)?;
|
||||||
|
|
||||||
// Get the MAC of Occlum.json.protected file
|
|
||||||
let occlum_json_mac = {
|
|
||||||
let mut mac: sgx_aes_gcm_128bit_tag_t = Default::default();
|
|
||||||
parse_str_to_bytes(&image_config.occlum_json_mac, &mut mac)?;
|
|
||||||
mac
|
|
||||||
};
|
|
||||||
let occlum_json_mac_ptr = &occlum_json_mac as *const sgx_aes_gcm_128bit_tag_t;
|
|
||||||
|
|
||||||
// Get grpc server address from environment GRPC_SERVER
|
// Get grpc server address from environment GRPC_SERVER
|
||||||
let server_addr = CString::new(
|
let server_addr = CString::new(
|
||||||
env::var("GRPC_SERVER").unwrap_or("localhost:50051".to_string()))
|
env::var("GRPC_SERVER").unwrap_or("localhost:50051".to_string()))
|
||||||
@ -99,7 +91,10 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
|
|
||||||
// Mount the image
|
// Mount the image
|
||||||
const SYS_MOUNT_FS: i64 = 363;
|
const SYS_MOUNT_FS: i64 = 363;
|
||||||
let ret = unsafe { syscall(SYS_MOUNT_FS, key_ptr, occlum_json_mac_ptr) };
|
// User can provide valid path for runtime mount and boot
|
||||||
|
// Otherwise, just pass null pointer to do general mount and boot
|
||||||
|
let root_config_path: *const i8 = std::ptr::null();
|
||||||
|
let ret = unsafe { syscall(SYS_MOUNT_FS, key_ptr, root_config_path) };
|
||||||
if ret < 0 {
|
if ret < 0 {
|
||||||
return Err(Box::new(std::io::Error::last_os_error()));
|
return Err(Box::new(std::io::Error::last_os_error()));
|
||||||
}
|
}
|
||||||
@ -112,13 +107,10 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
type sgx_key_128bit_t = [u8; 16];
|
type sgx_key_128bit_t = [u8; 16];
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
type sgx_aes_gcm_128bit_tag_t = [u8; 16];
|
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct ImageConfig {
|
struct ImageConfig {
|
||||||
occlum_json_mac: String,
|
|
||||||
image_type: String,
|
image_type: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,8 +94,7 @@ pub struct Config {
|
|||||||
pub resource_limits: ConfigResourceLimits,
|
pub resource_limits: ConfigResourceLimits,
|
||||||
pub process: ConfigProcess,
|
pub process: ConfigProcess,
|
||||||
pub env: ConfigEnv,
|
pub env: ConfigEnv,
|
||||||
pub entry_points: Vec<PathBuf>,
|
pub app: Vec<ConfigApp>,
|
||||||
pub mount: Vec<ConfigMount>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -116,7 +115,7 @@ pub struct ConfigEnv {
|
|||||||
pub untrusted: HashSet<String>,
|
pub untrusted: HashSet<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct ConfigMount {
|
pub struct ConfigMount {
|
||||||
pub type_: ConfigMountFsType,
|
pub type_: ConfigMountFsType,
|
||||||
pub target: PathBuf,
|
pub target: PathBuf,
|
||||||
@ -124,7 +123,14 @@ pub struct ConfigMount {
|
|||||||
pub options: ConfigMountOptions,
|
pub options: ConfigMountOptions,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct ConfigApp {
|
||||||
|
pub entry_points: Vec<PathBuf>,
|
||||||
|
pub stage: String,
|
||||||
|
pub mount: Vec<ConfigMount>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub enum ConfigMountFsType {
|
pub enum ConfigMountFsType {
|
||||||
TYPE_SEFS,
|
TYPE_SEFS,
|
||||||
@ -154,12 +160,13 @@ impl ConfigMountFsType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Clone, Default, Debug)]
|
||||||
pub struct ConfigMountOptions {
|
pub struct ConfigMountOptions {
|
||||||
pub mac: Option<sgx_aes_gcm_128bit_tag_t>,
|
pub mac: Option<sgx_aes_gcm_128bit_tag_t>,
|
||||||
pub layers: Option<Vec<ConfigMount>>,
|
pub layers: Option<Vec<ConfigMount>>,
|
||||||
pub temporary: bool,
|
pub temporary: bool,
|
||||||
pub cache_size: Option<u64>,
|
pub cache_size: Option<u64>,
|
||||||
|
pub index: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
@ -167,32 +174,32 @@ impl Config {
|
|||||||
let resource_limits = ConfigResourceLimits::from_input(&input.resource_limits)?;
|
let resource_limits = ConfigResourceLimits::from_input(&input.resource_limits)?;
|
||||||
let process = ConfigProcess::from_input(&input.process)?;
|
let process = ConfigProcess::from_input(&input.process)?;
|
||||||
let env = ConfigEnv::from_input(&input.env)?;
|
let env = ConfigEnv::from_input(&input.env)?;
|
||||||
let entry_points = {
|
|
||||||
let mut entry_points = Vec::new();
|
let app = {
|
||||||
for ep in &input.entry_points {
|
let mut app = Vec::new();
|
||||||
let ep_path = Path::new(ep).to_path_buf();
|
for input_app in &input.app {
|
||||||
if !ep_path.is_absolute() {
|
app.push(ConfigApp::from_input(&input_app)?);
|
||||||
return_errno!(EINVAL, "entry point must be an absolute path")
|
|
||||||
}
|
}
|
||||||
entry_points.push(ep_path);
|
app
|
||||||
}
|
|
||||||
entry_points
|
|
||||||
};
|
|
||||||
let mount = {
|
|
||||||
let mut mount = Vec::new();
|
|
||||||
for input_mount in &input.mount {
|
|
||||||
mount.push(ConfigMount::from_input(&input_mount)?);
|
|
||||||
}
|
|
||||||
mount
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Config {
|
Ok(Config {
|
||||||
resource_limits,
|
resource_limits,
|
||||||
process,
|
process,
|
||||||
env,
|
env,
|
||||||
entry_points,
|
app,
|
||||||
mount,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_app_config(&self, stage: &str) -> Result<&ConfigApp> {
|
||||||
|
let config_app = self
|
||||||
|
.app
|
||||||
|
.iter()
|
||||||
|
.find(|m| m.stage.eq(stage))
|
||||||
|
.ok_or_else(|| errno!(Errno::ENOENT, "No expected config app"))?;
|
||||||
|
|
||||||
|
Ok(config_app)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConfigResourceLimits {
|
impl ConfigResourceLimits {
|
||||||
@ -224,6 +231,36 @@ impl ConfigEnv {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ConfigApp {
|
||||||
|
fn from_input(input: &InputConfigApp) -> Result<ConfigApp> {
|
||||||
|
let stage = input.stage.clone();
|
||||||
|
let entry_points = {
|
||||||
|
let mut entry_points = Vec::new();
|
||||||
|
for ep in &input.entry_points {
|
||||||
|
let ep_path = Path::new(ep).to_path_buf();
|
||||||
|
if !ep_path.is_absolute() {
|
||||||
|
return_errno!(EINVAL, "entry point must be an absolute path")
|
||||||
|
}
|
||||||
|
entry_points.push(ep_path);
|
||||||
|
}
|
||||||
|
entry_points
|
||||||
|
};
|
||||||
|
let mount = {
|
||||||
|
let mut mount = Vec::new();
|
||||||
|
for input_mount in &input.mount {
|
||||||
|
mount.push(ConfigMount::from_input(&input_mount)?);
|
||||||
|
}
|
||||||
|
mount
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(ConfigApp {
|
||||||
|
stage,
|
||||||
|
entry_points,
|
||||||
|
mount,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ConfigMount {
|
impl ConfigMount {
|
||||||
fn from_input(input: &InputConfigMount) -> Result<ConfigMount> {
|
fn from_input(input: &InputConfigMount) -> Result<ConfigMount> {
|
||||||
let type_ = ConfigMountFsType::from_input(input.type_.as_str())?;
|
let type_ = ConfigMountFsType::from_input(input.type_.as_str())?;
|
||||||
@ -277,6 +314,7 @@ impl ConfigMountOptions {
|
|||||||
layers,
|
layers,
|
||||||
temporary: input.temporary,
|
temporary: input.temporary,
|
||||||
cache_size,
|
cache_size,
|
||||||
|
index: input.index,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -316,9 +354,7 @@ struct InputConfig {
|
|||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub env: InputConfigEnv,
|
pub env: InputConfigEnv,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub entry_points: Vec<String>,
|
pub app: Vec<InputConfigApp>,
|
||||||
#[serde(default)]
|
|
||||||
pub mount: Vec<InputConfigMount>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
@ -415,4 +451,17 @@ struct InputConfigMountOptions {
|
|||||||
pub temporary: bool,
|
pub temporary: bool,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub cache_size: Option<String>,
|
pub cache_size: Option<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub index: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
struct InputConfigApp {
|
||||||
|
#[serde(default)]
|
||||||
|
pub stage: String,
|
||||||
|
#[serde(default)]
|
||||||
|
pub entry_points: Vec<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub mount: Vec<InputConfigMount>,
|
||||||
}
|
}
|
||||||
|
@ -24,8 +24,13 @@ static mut ENCLAVE_PATH: String = String::new();
|
|||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref INIT_ONCE: Once = Once::new();
|
static ref INIT_ONCE: Once = Once::new();
|
||||||
static ref HAS_INIT: AtomicBool = AtomicBool::new(false);
|
static ref HAS_INIT: AtomicBool = AtomicBool::new(false);
|
||||||
pub static ref ENTRY_POINTS: RwLock<Vec<PathBuf>> =
|
pub static ref ENTRY_POINTS: RwLock<Vec<PathBuf>> = RwLock::new(
|
||||||
RwLock::new(config::LIBOS_CONFIG.entry_points.clone());
|
config::LIBOS_CONFIG
|
||||||
|
.get_app_config("init")
|
||||||
|
.unwrap()
|
||||||
|
.entry_points
|
||||||
|
.clone()
|
||||||
|
);
|
||||||
pub static ref RESOLV_CONF_STR: RwLock<Option<String>> = RwLock::new(None);
|
pub static ref RESOLV_CONF_STR: RwLock<Option<String>> = RwLock::new(None);
|
||||||
pub static ref HOSTNAME_STR: RwLock<Option<String>> = RwLock::new(None);
|
pub static ref HOSTNAME_STR: RwLock<Option<String>> = RwLock::new(None);
|
||||||
pub static ref HOSTS_STR: RwLock<Option<String>> = RwLock::new(None);
|
pub static ref HOSTS_STR: RwLock<Option<String>> = RwLock::new(None);
|
||||||
|
@ -13,7 +13,7 @@ lazy_static! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn do_mount_rootfs(
|
pub fn do_mount_rootfs(
|
||||||
user_config: &config::Config,
|
user_app_config: &config::ConfigApp,
|
||||||
user_key: &Option<sgx_key_128bit_t>,
|
user_key: &Option<sgx_key_128bit_t>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
debug!("mount rootfs");
|
debug!("mount rootfs");
|
||||||
@ -21,13 +21,15 @@ pub fn do_mount_rootfs(
|
|||||||
if MOUNT_ONCE.is_completed() {
|
if MOUNT_ONCE.is_completed() {
|
||||||
return_errno!(EPERM, "rootfs cannot be mounted more than once");
|
return_errno!(EPERM, "rootfs cannot be mounted more than once");
|
||||||
}
|
}
|
||||||
let new_rootfs = open_root_fs_according_to(&user_config.mount, user_key)?;
|
|
||||||
mount_nonroot_fs_according_to(&new_rootfs.root_inode(), &user_config.mount, user_key, true)?;
|
let mount_config = &user_app_config.mount;
|
||||||
|
let new_rootfs = open_root_fs_according_to(mount_config, user_key)?;
|
||||||
|
mount_nonroot_fs_according_to(&new_rootfs.root_inode(), mount_config, user_key, true)?;
|
||||||
MOUNT_ONCE.call_once(|| {
|
MOUNT_ONCE.call_once(|| {
|
||||||
let mut rootfs = ROOT_FS.write().unwrap();
|
let mut rootfs = ROOT_FS.write().unwrap();
|
||||||
rootfs.sync().expect("failed to sync old rootfs");
|
rootfs.sync().expect("failed to sync old rootfs");
|
||||||
*rootfs = new_rootfs;
|
*rootfs = new_rootfs;
|
||||||
*ENTRY_POINTS.write().unwrap() = user_config.entry_points.to_owned();
|
*ENTRY_POINTS.write().unwrap() = user_app_config.entry_points.to_owned();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Write resolv.conf file into mounted file system
|
// Write resolv.conf file into mounted file system
|
||||||
|
@ -33,7 +33,7 @@ pub use self::locks::range_lock::{
|
|||||||
FileRange, RangeLock, RangeLockBuilder, RangeLockList, RangeLockType, OFFSET_MAX,
|
FileRange, RangeLock, RangeLockBuilder, RangeLockList, RangeLockType, OFFSET_MAX,
|
||||||
};
|
};
|
||||||
pub use self::pipe::PipeType;
|
pub use self::pipe::PipeType;
|
||||||
pub use self::rootfs::ROOT_FS;
|
pub use self::rootfs::{gen_config_app, user_rootfs_config, ROOT_FS};
|
||||||
pub use self::stdio::{HostStdioFds, StdinFile, StdoutFile};
|
pub use self::stdio::{HostStdioFds, StdinFile, StdoutFile};
|
||||||
pub use self::syscalls::*;
|
pub use self::syscalls::*;
|
||||||
pub use self::timer_file::{AsTimer, TimerCreationFlags, TimerFile};
|
pub use self::timer_file::{AsTimer, TimerCreationFlags, TimerFile};
|
||||||
|
@ -3,7 +3,7 @@ use super::hostfs::HostFS;
|
|||||||
use super::procfs::ProcFS;
|
use super::procfs::ProcFS;
|
||||||
use super::sefs::{SgxStorage, SgxUuidProvider};
|
use super::sefs::{SgxStorage, SgxUuidProvider};
|
||||||
use super::*;
|
use super::*;
|
||||||
use config::ConfigMountFsType;
|
use config::{ConfigApp, ConfigMountFsType};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::untrusted::path::PathEx;
|
use std::untrusted::path::PathEx;
|
||||||
|
|
||||||
@ -13,11 +13,13 @@ use rcore_fs_sefs::dev::*;
|
|||||||
use rcore_fs_sefs::SEFS;
|
use rcore_fs_sefs::SEFS;
|
||||||
use rcore_fs_unionfs::UnionFS;
|
use rcore_fs_unionfs::UnionFS;
|
||||||
|
|
||||||
|
use util::mem_util::from_user;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
/// The root of file system
|
/// The root of file system
|
||||||
pub static ref ROOT_FS: RwLock<Arc<dyn FileSystem>> = {
|
pub static ref ROOT_FS: RwLock<Arc<dyn FileSystem>> = {
|
||||||
fn init_root_fs() -> Result<Arc<dyn FileSystem>> {
|
fn init_root_fs() -> Result<Arc<dyn FileSystem>> {
|
||||||
let mount_config = &config::LIBOS_CONFIG.mount;
|
let mount_config = &config::LIBOS_CONFIG.get_app_config("init").unwrap().mount;
|
||||||
let rootfs = open_root_fs_according_to(mount_config, &None)?;
|
let rootfs = open_root_fs_according_to(mount_config, &None)?;
|
||||||
mount_nonroot_fs_according_to(&rootfs.root_inode(), mount_config, &None, true)?;
|
mount_nonroot_fs_according_to(&rootfs.root_inode(), mount_config, &None, true)?;
|
||||||
Ok(rootfs)
|
Ok(rootfs)
|
||||||
@ -49,7 +51,7 @@ pub fn open_root_fs_according_to(
|
|||||||
.find(|m| {
|
.find(|m| {
|
||||||
m.target == Path::new("/")
|
m.target == Path::new("/")
|
||||||
&& m.type_ == ConfigMountFsType::TYPE_SEFS
|
&& m.type_ == ConfigMountFsType::TYPE_SEFS
|
||||||
&& m.options.mac.is_some()
|
&& (m.options.mac.is_some() || m.options.index == 1)
|
||||||
})
|
})
|
||||||
.ok_or_else(|| errno!(Errno::ENOENT, "the image SEFS in layers is not valid"))?;
|
.ok_or_else(|| errno!(Errno::ENOENT, "the image SEFS in layers is not valid"))?;
|
||||||
let root_image_sefs =
|
let root_image_sefs =
|
||||||
@ -61,6 +63,7 @@ pub fn open_root_fs_according_to(
|
|||||||
m.target == Path::new("/")
|
m.target == Path::new("/")
|
||||||
&& m.type_ == ConfigMountFsType::TYPE_SEFS
|
&& m.type_ == ConfigMountFsType::TYPE_SEFS
|
||||||
&& m.options.mac.is_none()
|
&& m.options.mac.is_none()
|
||||||
|
&& m.options.index == 0
|
||||||
})
|
})
|
||||||
.ok_or_else(|| errno!(Errno::ENOENT, "the container SEFS in layers is not valid"))?;
|
.ok_or_else(|| errno!(Errno::ENOENT, "the container SEFS in layers is not valid"))?;
|
||||||
let root_container_sefs =
|
let root_container_sefs =
|
||||||
@ -262,3 +265,109 @@ fn open_or_create_sefs_according_to(
|
|||||||
};
|
};
|
||||||
Ok(sefs)
|
Ok(sefs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
pub struct user_rootfs_config {
|
||||||
|
upper_layer_path: *const i8,
|
||||||
|
lower_layer_path: *const i8,
|
||||||
|
entry_point: *const i8,
|
||||||
|
hostfs_source: *const i8,
|
||||||
|
hostfs_target: *const i8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl user_rootfs_config {
|
||||||
|
pub fn from_raw_ptr(ptr: *const user_rootfs_config) -> Result<user_rootfs_config> {
|
||||||
|
let config = unsafe { *ptr };
|
||||||
|
Ok(config)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_option_pathbuf(path: *const i8) -> Result<Option<PathBuf>> {
|
||||||
|
let path = if path.is_null() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(PathBuf::from(
|
||||||
|
from_user::clone_cstring_safely(path)?
|
||||||
|
.to_string_lossy()
|
||||||
|
.into_owned(),
|
||||||
|
))
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn gen_config_app(config: &user_rootfs_config) -> Result<ConfigApp> {
|
||||||
|
let upper_layer = to_option_pathbuf(config.upper_layer_path)?;
|
||||||
|
let lower_layer = to_option_pathbuf(config.lower_layer_path)?;
|
||||||
|
let entry_point = to_option_pathbuf(config.entry_point)?;
|
||||||
|
let hostfs_source = to_option_pathbuf(config.hostfs_source)?;
|
||||||
|
|
||||||
|
let hostfs_target = if config.hostfs_target.is_null() {
|
||||||
|
PathBuf::from("/host")
|
||||||
|
} else {
|
||||||
|
PathBuf::from(
|
||||||
|
from_user::clone_cstring_safely(config.hostfs_target)?
|
||||||
|
.to_string_lossy()
|
||||||
|
.into_owned(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut config_app = config::LIBOS_CONFIG.get_app_config("app").unwrap().clone();
|
||||||
|
let root_mount_config = config_app
|
||||||
|
.mount
|
||||||
|
.iter_mut()
|
||||||
|
.find(|m| m.target == Path::new("/") && m.type_ == ConfigMountFsType::TYPE_UNIONFS)
|
||||||
|
.ok_or_else(|| errno!(Errno::ENOENT, "the root UnionFS is not valid"))?;
|
||||||
|
|
||||||
|
if upper_layer.is_some() {
|
||||||
|
let layer_mount_configs = root_mount_config.options.layers.as_mut().unwrap();
|
||||||
|
// image SEFS in layers
|
||||||
|
let root_image_sefs_mount_config = layer_mount_configs
|
||||||
|
.iter_mut()
|
||||||
|
.find(|m| {
|
||||||
|
m.target == Path::new("/")
|
||||||
|
&& m.type_ == ConfigMountFsType::TYPE_SEFS
|
||||||
|
&& (m.options.mac.is_some() || m.options.index == 1)
|
||||||
|
})
|
||||||
|
.ok_or_else(|| errno!(Errno::ENOENT, "the image SEFS in layers is not valid"))?;
|
||||||
|
|
||||||
|
root_image_sefs_mount_config.source = upper_layer;
|
||||||
|
root_image_sefs_mount_config.options.mac = None;
|
||||||
|
root_image_sefs_mount_config.options.index = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if lower_layer.is_some() {
|
||||||
|
let layer_mount_configs = root_mount_config.options.layers.as_mut().unwrap();
|
||||||
|
// container SEFS in layers
|
||||||
|
let root_container_sefs_mount_config = layer_mount_configs
|
||||||
|
.iter_mut()
|
||||||
|
.find(|m| {
|
||||||
|
m.target == Path::new("/")
|
||||||
|
&& m.type_ == ConfigMountFsType::TYPE_SEFS
|
||||||
|
&& m.options.mac.is_none()
|
||||||
|
&& m.options.index == 0
|
||||||
|
})
|
||||||
|
.ok_or_else(|| errno!(Errno::ENOENT, "the container SEFS in layers is not valid"))?;
|
||||||
|
|
||||||
|
root_container_sefs_mount_config.source = lower_layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
if entry_point.is_some() {
|
||||||
|
config_app.entry_points.clear();
|
||||||
|
config_app.entry_points.push(entry_point.unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
if hostfs_source.is_some() {
|
||||||
|
let hostfs_mount_config = config_app
|
||||||
|
.mount
|
||||||
|
.iter_mut()
|
||||||
|
.find(|m| m.type_ == ConfigMountFsType::TYPE_HOSTFS)
|
||||||
|
.ok_or_else(|| errno!(Errno::ENOENT, "the HostFS is not valid"))?;
|
||||||
|
hostfs_mount_config.source = hostfs_source;
|
||||||
|
hostfs_mount_config.target = hostfs_target;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(config_app)
|
||||||
|
}
|
||||||
|
@ -660,20 +660,26 @@ pub fn do_ioctl(fd: FileDesc, cmd: u32, argp: *mut u8) -> Result<isize> {
|
|||||||
|
|
||||||
pub fn do_mount_rootfs(
|
pub fn do_mount_rootfs(
|
||||||
key_ptr: *const sgx_key_128bit_t,
|
key_ptr: *const sgx_key_128bit_t,
|
||||||
occlum_json_mac_ptr: *const sgx_aes_gcm_128bit_tag_t,
|
rootfs_config: *const user_rootfs_config,
|
||||||
) -> Result<isize> {
|
) -> Result<isize> {
|
||||||
let key = if key_ptr.is_null() {
|
let key = if key_ptr.is_null() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(unsafe { key_ptr.read() })
|
Some(unsafe { key_ptr.read() })
|
||||||
};
|
};
|
||||||
if occlum_json_mac_ptr.is_null() {
|
|
||||||
return_errno!(EINVAL, "occlum_json_mac_ptr cannot be null");
|
// If user provided valid parameters, do runtime mount and boot
|
||||||
|
// Otherwise, do general mount and boot
|
||||||
|
if !rootfs_config.is_null() {
|
||||||
|
from_user::check_ptr(rootfs_config)?;
|
||||||
|
let rootfs_config = user_rootfs_config::from_raw_ptr(rootfs_config)?;
|
||||||
|
let app_config = gen_config_app(&rootfs_config)?;
|
||||||
|
debug!("user provided app config: {:?}", app_config);
|
||||||
|
fs_ops::do_mount_rootfs(&app_config, &key)?;
|
||||||
|
} else {
|
||||||
|
fs_ops::do_mount_rootfs(&config::LIBOS_CONFIG.get_app_config("app").unwrap(), &key)?;
|
||||||
}
|
}
|
||||||
let expected_occlum_json_mac = unsafe { occlum_json_mac_ptr.read() };
|
|
||||||
let user_config_path = unsafe { format!("{}{}", INSTANCE_DIR, "/build/Occlum.json.protected") };
|
|
||||||
let user_config = config::load_config(&user_config_path, &expected_occlum_json_mac)?;
|
|
||||||
fs_ops::do_mount_rootfs(&user_config, &key)?;
|
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,8 +31,8 @@ use crate::fs::{
|
|||||||
do_pwritev, do_read, do_readlink, do_readlinkat, do_readv, do_rename, do_renameat, do_rmdir,
|
do_pwritev, do_read, do_readlink, do_readlinkat, do_readv, do_rename, do_renameat, do_rmdir,
|
||||||
do_sendfile, do_stat, do_statfs, do_symlink, do_symlinkat, do_sync, do_timerfd_create,
|
do_sendfile, do_stat, do_statfs, do_symlink, do_symlinkat, do_sync, do_timerfd_create,
|
||||||
do_timerfd_gettime, do_timerfd_settime, do_truncate, do_umask, do_umount, do_unlink,
|
do_timerfd_gettime, do_timerfd_settime, do_truncate, do_umask, do_umount, do_unlink,
|
||||||
do_unlinkat, do_utime, do_utimensat, do_utimes, do_write, do_writev, iovec_t, utimbuf_t,
|
do_unlinkat, do_utime, do_utimensat, do_utimes, do_write, do_writev, iovec_t,
|
||||||
AsTimer, File, FileDesc, FileRef, HostStdioFds, Stat, Statfs,
|
user_rootfs_config, utimbuf_t, AsTimer, File, FileDesc, FileRef, HostStdioFds, Stat, Statfs,
|
||||||
};
|
};
|
||||||
use crate::interrupt::{do_handle_interrupt, sgx_interrupt_info_t};
|
use crate::interrupt::{do_handle_interrupt, sgx_interrupt_info_t};
|
||||||
use crate::ipc::{do_shmat, do_shmctl, do_shmdt, do_shmget, key_t, shmids_t};
|
use crate::ipc::{do_shmat, do_shmctl, do_shmdt, do_shmget, key_t, shmids_t};
|
||||||
@ -425,7 +425,7 @@ macro_rules! process_syscall_table_with_callback {
|
|||||||
(SpawnMusl = 360) => do_spawn_for_musl(child_pid_ptr: *mut u32, path: *const i8, argv: *const *const i8, envp: *const *const i8, fdop_list: *const FdOp, attribute_list: *const posix_spawnattr_t),
|
(SpawnMusl = 360) => do_spawn_for_musl(child_pid_ptr: *mut u32, path: *const i8, argv: *const *const i8, envp: *const *const i8, fdop_list: *const FdOp, attribute_list: *const posix_spawnattr_t),
|
||||||
(HandleException = 361) => do_handle_exception(info: *mut sgx_exception_info_t, fpregs: *mut FpRegs, context: *mut CpuContext),
|
(HandleException = 361) => do_handle_exception(info: *mut sgx_exception_info_t, fpregs: *mut FpRegs, context: *mut CpuContext),
|
||||||
(HandleInterrupt = 362) => do_handle_interrupt(info: *mut sgx_interrupt_info_t, fpregs: *mut FpRegs, context: *mut CpuContext),
|
(HandleInterrupt = 362) => do_handle_interrupt(info: *mut sgx_interrupt_info_t, fpregs: *mut FpRegs, context: *mut CpuContext),
|
||||||
(MountRootFS = 363) => do_mount_rootfs(key_ptr: *const sgx_key_128bit_t, occlum_json_mac_ptr: *const sgx_aes_gcm_128bit_tag_t),
|
(MountRootFS = 363) => do_mount_rootfs(key_ptr: *const sgx_key_128bit_t, rootfs_config: *const user_rootfs_config),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -67,8 +67,8 @@ fn main() {
|
|||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
SubCommand::with_name("gen_user_conf")
|
SubCommand::with_name("gen_conf")
|
||||||
.about("Generate user image config")
|
.about("Generate image config")
|
||||||
// Input: User's Secure Occlum FS image MAC
|
// Input: User's Secure Occlum FS image MAC
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("user_fs_mac")
|
Arg::with_name("user_fs_mac")
|
||||||
@ -77,11 +77,19 @@ fn main() {
|
|||||||
.required(true)
|
.required(true)
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
|
// Input: InitFS image MAC
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("init_fs_mac")
|
||||||
|
.long("init_fs_mac")
|
||||||
|
.value_name("input MAC of init image fs")
|
||||||
|
.required(true)
|
||||||
|
.takes_value(true),
|
||||||
|
)
|
||||||
// Output: JSON file used by libOS and users shouldn't touch
|
// Output: JSON file used by libOS and users shouldn't touch
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("output_user_json")
|
Arg::with_name("output_json")
|
||||||
.long("output_user_json")
|
.long("output_json")
|
||||||
.value_name("output user json")
|
.value_name("output json")
|
||||||
.required(true)
|
.required(true)
|
||||||
.validator(|f| match File::create(f) {
|
.validator(|f| match File::create(f) {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
@ -102,30 +110,6 @@ fn main() {
|
|||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.subcommand(
|
|
||||||
SubCommand::with_name("gen_sys_conf")
|
|
||||||
.about("Generate initfs image config")
|
|
||||||
// Input: InitFS image MAC
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("init_fs_mac")
|
|
||||||
.long("init_fs_mac")
|
|
||||||
.value_name("input MAC of init image fs")
|
|
||||||
.required(true)
|
|
||||||
.takes_value(true),
|
|
||||||
)
|
|
||||||
// Output: JSON file for initfs and users shouldn't touch
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("sys_json")
|
|
||||||
.long("sys_json")
|
|
||||||
.value_name("output sys json")
|
|
||||||
.required(true)
|
|
||||||
.validator(|f| match File::create(f) {
|
|
||||||
Ok(_) => Ok(()),
|
|
||||||
Err(e) => Err(e.to_string()),
|
|
||||||
})
|
|
||||||
.takes_value(true),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
let occlum_config_file_path = matches.value_of("user_json").unwrap();
|
let occlum_config_file_path = matches.value_of("user_json").unwrap();
|
||||||
@ -141,14 +125,17 @@ fn main() {
|
|||||||
debug!("The occlum config is:{:?}", occlum_config);
|
debug!("The occlum config is:{:?}", occlum_config);
|
||||||
|
|
||||||
// Match subcommand
|
// Match subcommand
|
||||||
if let Some(sub_matches) = matches.subcommand_matches("gen_user_conf") {
|
if let Some(sub_matches) = matches.subcommand_matches("gen_conf") {
|
||||||
let occlum_conf_user_fs_mac = sub_matches.value_of("user_fs_mac").unwrap();
|
let occlum_conf_user_fs_mac = sub_matches.value_of("user_fs_mac").unwrap();
|
||||||
debug!("Occlum config user FS MAC {:?}", occlum_conf_user_fs_mac);
|
debug!("Occlum config user FS MAC {:?}", occlum_conf_user_fs_mac);
|
||||||
|
|
||||||
let occlum_user_json_file_path = sub_matches.value_of("output_user_json").unwrap();
|
let occlum_conf_init_fs_mac = sub_matches.value_of("init_fs_mac").unwrap();
|
||||||
|
debug!("Occlum config init FS MAC {:?}", occlum_conf_init_fs_mac);
|
||||||
|
|
||||||
|
let occlum_json_file_path = sub_matches.value_of("output_json").unwrap();
|
||||||
debug!(
|
debug!(
|
||||||
"Generated Occlum user config (json) file name {:?}",
|
"Genereated Occlum user config (json) file name {:?}",
|
||||||
occlum_user_json_file_path
|
occlum_json_file_path
|
||||||
);
|
);
|
||||||
|
|
||||||
let enclave_config_file_path = sub_matches.value_of("sdk_xml").unwrap();
|
let enclave_config_file_path = sub_matches.value_of("sdk_xml").unwrap();
|
||||||
@ -273,17 +260,23 @@ fn main() {
|
|||||||
let enclave_config = serde_xml_rs::to_string(&sgx_enclave_configuration).unwrap();
|
let enclave_config = serde_xml_rs::to_string(&sgx_enclave_configuration).unwrap();
|
||||||
debug!("The enclave config:{:?}", enclave_config);
|
debug!("The enclave config:{:?}", enclave_config);
|
||||||
|
|
||||||
// Generate user Occlum.json - "output_user_json"
|
// Generate app config, including "init" and user app
|
||||||
let user_mount_config = {
|
let app_config = {
|
||||||
let user_mount_config =
|
let app_config =
|
||||||
gen_user_mount_config(occlum_config.mount, occlum_conf_user_fs_mac.to_string());
|
gen_app_config(
|
||||||
if user_mount_config.is_err() {
|
occlum_config.entry_points,
|
||||||
println!("Mount configuration invalid: {:?}", user_mount_config);
|
occlum_config.mount,
|
||||||
|
occlum_conf_user_fs_mac.to_string(),
|
||||||
|
occlum_conf_init_fs_mac.to_string(),
|
||||||
|
);
|
||||||
|
if app_config.is_err() {
|
||||||
|
println!("Mount configuration invalid: {:?}", app_config);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
user_mount_config.unwrap()
|
app_config.unwrap()
|
||||||
};
|
};
|
||||||
let user_occlum_json_config = InternalOcclumJson {
|
|
||||||
|
let occlum_json_config = InternalOcclumJson {
|
||||||
resource_limits: InternalResourceLimits {
|
resource_limits: InternalResourceLimits {
|
||||||
user_space_size: occlum_config.resource_limits.user_space_size.to_string(),
|
user_space_size: occlum_config.resource_limits.user_space_size.to_string(),
|
||||||
},
|
},
|
||||||
@ -292,12 +285,12 @@ fn main() {
|
|||||||
default_heap_size: occlum_config.process.default_heap_size,
|
default_heap_size: occlum_config.process.default_heap_size,
|
||||||
default_mmap_size: occlum_config.process.default_mmap_size,
|
default_mmap_size: occlum_config.process.default_mmap_size,
|
||||||
},
|
},
|
||||||
entry_points: occlum_config.entry_points,
|
|
||||||
env: occlum_config.env,
|
env: occlum_config.env,
|
||||||
mount: serde_json::to_value(user_mount_config).unwrap(),
|
app: app_config,
|
||||||
};
|
};
|
||||||
let user_occlum_json_str = serde_json::to_string_pretty(&user_occlum_json_config).unwrap();
|
|
||||||
debug!("The user Occlum.json config:\n{:?}", user_occlum_json_str);
|
let occlum_json_str = serde_json::to_string_pretty(&occlum_json_config).unwrap();
|
||||||
|
debug!("The Occlum.json config:\n{:?}", occlum_json_str);
|
||||||
|
|
||||||
// Update the output file
|
// Update the output file
|
||||||
let mut enclave_config_file = File::create(enclave_config_file_path)
|
let mut enclave_config_file = File::create(enclave_config_file_path)
|
||||||
@ -306,44 +299,11 @@ fn main() {
|
|||||||
.write_all(enclave_config.as_bytes())
|
.write_all(enclave_config.as_bytes())
|
||||||
.expect("Failed to update the Enclave configuration file.");
|
.expect("Failed to update the Enclave configuration file.");
|
||||||
|
|
||||||
let mut user_occlum_json = File::create(occlum_user_json_file_path)
|
let mut occlum_json = File::create(occlum_json_file_path)
|
||||||
.expect("Could not open the output user Occlum.json file.");
|
.expect("Could not open the output Occlum.json file.");
|
||||||
user_occlum_json
|
occlum_json
|
||||||
.write_all(user_occlum_json_str.as_bytes())
|
.write_all(occlum_json_str.as_bytes())
|
||||||
.expect("Failed to update the output user Occlum.json file.");
|
.expect("Failed to update the output Occlum.json file.");
|
||||||
} else if let Some(sub_matches) = matches.subcommand_matches("gen_sys_conf") {
|
|
||||||
let occlum_conf_init_fs_mac = sub_matches.value_of("init_fs_mac").unwrap();
|
|
||||||
debug!("Occlum config init FS MAC {:?}", occlum_conf_init_fs_mac);
|
|
||||||
|
|
||||||
let occlum_sys_json_file_path = sub_matches.value_of("sys_json").unwrap();
|
|
||||||
debug!(
|
|
||||||
"Generated Occlum sys config (json) file name {:?}",
|
|
||||||
occlum_sys_json_file_path
|
|
||||||
);
|
|
||||||
|
|
||||||
// Generate sys Occlum.json - "sys_json"
|
|
||||||
let sys_occlum_json_config = InternalOcclumJson {
|
|
||||||
resource_limits: InternalResourceLimits {
|
|
||||||
user_space_size: occlum_config.resource_limits.user_space_size.to_string(),
|
|
||||||
},
|
|
||||||
process: OcclumProcess {
|
|
||||||
default_stack_size: occlum_config.process.default_stack_size,
|
|
||||||
default_heap_size: occlum_config.process.default_heap_size,
|
|
||||||
default_mmap_size: occlum_config.process.default_mmap_size,
|
|
||||||
},
|
|
||||||
entry_points: json!(["/bin"]),
|
|
||||||
env: occlum_config.env,
|
|
||||||
mount: gen_sys_mount_config(occlum_conf_init_fs_mac.to_string()),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Update the output file
|
|
||||||
let sys_occlum_json_str = serde_json::to_string_pretty(&sys_occlum_json_config).unwrap();
|
|
||||||
debug!("The sys Occlum.json config:\n{:?}", sys_occlum_json_str);
|
|
||||||
let mut sys_occlum_json = File::create(occlum_sys_json_file_path)
|
|
||||||
.expect("Could not open the output sys Occlum.json file.");
|
|
||||||
sys_occlum_json
|
|
||||||
.write_all(sys_occlum_json_str.as_bytes())
|
|
||||||
.expect("Failed to update the output sys Occlum.json file.");
|
|
||||||
} else {
|
} else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
@ -402,38 +362,19 @@ fn parse_kss_conf(occlum_config: &OcclumConfiguration) -> (u32, u64, u64, u64, u
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gen_user_mount_config(
|
fn gen_app_config(
|
||||||
|
entry_points: serde_json::Value,
|
||||||
mount_conf: Vec<OcclumMount>,
|
mount_conf: Vec<OcclumMount>,
|
||||||
occlum_conf_user_fs_mac: String,
|
occlum_conf_user_fs_mac: String,
|
||||||
) -> Result<Vec<OcclumMount>, &'static str> {
|
occlum_conf_init_fs_mac: String,
|
||||||
let mut user_mount_config = mount_conf;
|
) -> Result<serde_json::Value, &'static str> {
|
||||||
let root_mc = user_mount_config
|
let mut app_config: serde_json::Value = json!({
|
||||||
.iter_mut()
|
"app": [
|
||||||
.find(|m| m.target == String::from("/") && m.type_ == String::from("unionfs"))
|
{
|
||||||
.ok_or("the root UnionFS is not valid")?;
|
"stage": "init",
|
||||||
if root_mc.options.layers.is_none() {
|
"entry_points": [
|
||||||
return Err("the root UnionFS must be given layers");
|
"/bin"
|
||||||
}
|
],
|
||||||
let mut root_image_sefs_mc = root_mc
|
|
||||||
.options
|
|
||||||
.layers
|
|
||||||
.as_mut()
|
|
||||||
.unwrap()
|
|
||||||
.iter_mut()
|
|
||||||
.find(|m| {
|
|
||||||
m.target == String::from("/")
|
|
||||||
&& m.type_ == String::from("sefs")
|
|
||||||
&& m.options.mac.is_some()
|
|
||||||
})
|
|
||||||
.ok_or("the image SEFS in layers is not valid")?;
|
|
||||||
root_image_sefs_mc.options.mac = Some(occlum_conf_user_fs_mac);
|
|
||||||
|
|
||||||
debug!("user Occlum.json mount config:\n{:?}", user_mount_config);
|
|
||||||
Ok(user_mount_config)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn gen_sys_mount_config(occlum_conf_init_fs_mac: String) -> serde_json::Value {
|
|
||||||
let mut init_fs_mount_config: serde_json::Value = json!({
|
|
||||||
"mount": [
|
"mount": [
|
||||||
{
|
{
|
||||||
"target": "/",
|
"target": "/",
|
||||||
@ -465,15 +406,107 @@ fn gen_sys_mount_config(occlum_conf_init_fs_mac: String) -> serde_json::Value {
|
|||||||
"type": "devfs"
|
"type": "devfs"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"stage": "app",
|
||||||
|
"entry_points": [],
|
||||||
|
"mount": [
|
||||||
|
{
|
||||||
|
"target": "/",
|
||||||
|
"type": "unionfs",
|
||||||
|
"options": {
|
||||||
|
"layers": [
|
||||||
|
{
|
||||||
|
"target": "/",
|
||||||
|
"type": "sefs",
|
||||||
|
"source": "./build/mount/__ROOT",
|
||||||
|
"options": {
|
||||||
|
"MAC": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"target": "/",
|
||||||
|
"type": "sefs",
|
||||||
|
"source": "./run/mount/__ROOT"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"target": "/host",
|
||||||
|
"type": "hostfs",
|
||||||
|
"source": "."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"target": "/proc",
|
||||||
|
"type": "procfs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"target": "/dev",
|
||||||
|
"type": "devfs"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}]
|
||||||
});
|
});
|
||||||
|
|
||||||
*init_fs_mount_config
|
// Update init root mount fs MAC
|
||||||
.pointer_mut("/mount/0/options/layers/0/options/MAC")
|
*app_config
|
||||||
|
.pointer_mut("/app/0/mount/0/options/layers/0/options/MAC")
|
||||||
.unwrap() = serde_json::Value::String(occlum_conf_init_fs_mac);
|
.unwrap() = serde_json::Value::String(occlum_conf_init_fs_mac);
|
||||||
|
|
||||||
debug!("initfs mount config:\n{:?}", init_fs_mount_config);
|
// Update app entry points
|
||||||
|
*app_config
|
||||||
|
.pointer_mut("/app/1/entry_points")
|
||||||
|
.unwrap() = entry_points;
|
||||||
|
|
||||||
init_fs_mount_config["mount"].to_owned()
|
let mut mount_config = mount_conf;
|
||||||
|
if let Some(root_mc) = mount_config
|
||||||
|
.iter_mut()
|
||||||
|
.find(|m| {
|
||||||
|
m.target == String::from("/")
|
||||||
|
&& m.type_ == String::from("unionfs")
|
||||||
|
}) {
|
||||||
|
debug!("User provides Root mount config:\n{:?}", root_mc);
|
||||||
|
root_mc
|
||||||
|
.options
|
||||||
|
.layers
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.iter_mut()
|
||||||
|
.find(|m| {
|
||||||
|
m.target == String::from("/")
|
||||||
|
&& m.type_ == String::from("sefs")
|
||||||
|
&& m.options.mac.is_some()
|
||||||
|
})
|
||||||
|
.ok_or("the image SEFS in layers is not valid")?;
|
||||||
|
|
||||||
|
// Update app root mount
|
||||||
|
*app_config
|
||||||
|
.pointer_mut("/app/1/mount/0")
|
||||||
|
.unwrap() = serde_json::to_value(root_mc).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update app root mount fs MAC
|
||||||
|
*app_config
|
||||||
|
.pointer_mut("/app/1/mount/0/options/layers/0/options/MAC")
|
||||||
|
.unwrap() = serde_json::Value::String(occlum_conf_user_fs_mac);
|
||||||
|
|
||||||
|
// Update host mount
|
||||||
|
if let Some(host_mc) = mount_config
|
||||||
|
.iter_mut()
|
||||||
|
.find(|m| {
|
||||||
|
m.type_ == String::from("hostfs")
|
||||||
|
}) {
|
||||||
|
debug!("User provides host mount config:\n{:?}", host_mc);
|
||||||
|
// Update app root mount
|
||||||
|
*app_config
|
||||||
|
.pointer_mut("/app/1/mount/1")
|
||||||
|
.unwrap() = serde_json::to_value(host_mc).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
debug!("Occlum.json mount config:\n{:?}", app_config);
|
||||||
|
|
||||||
|
Ok(app_config["app"].to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Deserialize)]
|
#[derive(Debug, PartialEq, Deserialize)]
|
||||||
@ -598,7 +631,6 @@ struct InternalResourceLimits {
|
|||||||
struct InternalOcclumJson {
|
struct InternalOcclumJson {
|
||||||
resource_limits: InternalResourceLimits,
|
resource_limits: InternalResourceLimits,
|
||||||
process: OcclumProcess,
|
process: OcclumProcess,
|
||||||
entry_points: serde_json::Value,
|
|
||||||
env: serde_json::Value,
|
env: serde_json::Value,
|
||||||
mount: serde_json::Value,
|
app: serde_json::Value,
|
||||||
}
|
}
|
||||||
|
@ -14,14 +14,6 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
const IMAGE_CONFIG_FILE: &str = "/etc/image_config.json";
|
const IMAGE_CONFIG_FILE: &str = "/etc/image_config.json";
|
||||||
let image_config = load_config(IMAGE_CONFIG_FILE)?;
|
let image_config = load_config(IMAGE_CONFIG_FILE)?;
|
||||||
|
|
||||||
// Get the MAC of Occlum.json.protected file
|
|
||||||
let occlum_json_mac = {
|
|
||||||
let mut mac: sgx_aes_gcm_128bit_tag_t = Default::default();
|
|
||||||
parse_str_to_bytes(&image_config.occlum_json_mac, &mut mac)?;
|
|
||||||
mac
|
|
||||||
};
|
|
||||||
let occlum_json_mac_ptr = &occlum_json_mac as *const sgx_aes_gcm_128bit_tag_t;
|
|
||||||
|
|
||||||
// Get the key of FS image if needed
|
// Get the key of FS image if needed
|
||||||
let key = match &image_config.image_type[..] {
|
let key = match &image_config.image_type[..] {
|
||||||
"encrypted" => {
|
"encrypted" => {
|
||||||
@ -42,7 +34,11 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
|
|
||||||
// Mount the image
|
// Mount the image
|
||||||
const SYS_MOUNT_FS: i64 = 363;
|
const SYS_MOUNT_FS: i64 = 363;
|
||||||
let ret = unsafe { syscall(SYS_MOUNT_FS, key_ptr, occlum_json_mac_ptr) };
|
// User can provide valid path for runtime mount and boot
|
||||||
|
// Otherwise, just pass null pointer to do general mount and boot
|
||||||
|
let root_config_path: *const i8 = std::ptr::null();
|
||||||
|
let ret = unsafe { syscall(
|
||||||
|
SYS_MOUNT_FS, key_ptr, root_config_path) };
|
||||||
if ret < 0 {
|
if ret < 0 {
|
||||||
return Err(Box::new(std::io::Error::last_os_error()));
|
return Err(Box::new(std::io::Error::last_os_error()));
|
||||||
}
|
}
|
||||||
@ -52,13 +48,10 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
type sgx_key_128bit_t = [u8; 16];
|
type sgx_key_128bit_t = [u8; 16];
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
type sgx_aes_gcm_128bit_tag_t = [u8; 16];
|
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct ImageConfig {
|
struct ImageConfig {
|
||||||
occlum_json_mac: String,
|
|
||||||
image_type: String,
|
image_type: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -510,8 +510,8 @@ cmd_package() {
|
|||||||
$instance_base_name/build/bin \
|
$instance_base_name/build/bin \
|
||||||
$instance_base_name/build/lib/libocclum-libos.signed.so \
|
$instance_base_name/build/lib/libocclum-libos.signed.so \
|
||||||
$instance_base_name/build/lib/libocclum-pal.so* \
|
$instance_base_name/build/lib/libocclum-pal.so* \
|
||||||
$instance_base_name/build/mount $instance_base_name/build/Occlum.json.protected \
|
$instance_base_name/build/initfs $instance_base_name/build/mount \
|
||||||
$instance_base_name/build/initfs $instance_base_name/build/.Occlum_sys.json.protected \
|
$instance_base_name/build/.Occlum_sys.json.protected \
|
||||||
$instance_base_name/initfs $instance_base_name/run \
|
$instance_base_name/initfs $instance_base_name/run \
|
||||||
$instance_base_name/.__occlum_status $instance_base_name/.sgx_mode \
|
$instance_base_name/.__occlum_status $instance_base_name/.sgx_mode \
|
||||||
"
|
"
|
||||||
|
@ -68,9 +68,11 @@ $(instance_dir)/build/.Occlum_sys.json.protected: $(instance_dir)/build/.Occlum_
|
|||||||
@cd "$(instance_dir)/build" ; \
|
@cd "$(instance_dir)/build" ; \
|
||||||
LD_LIBRARY_PATH="$(SGX_SDK)/sdk_libs" "$(occlum_dir)/build/bin/occlum-protect-integrity" protect .Occlum_sys.json ;
|
LD_LIBRARY_PATH="$(SGX_SDK)/sdk_libs" "$(occlum_dir)/build/bin/occlum-protect-integrity" protect .Occlum_sys.json ;
|
||||||
|
|
||||||
$(instance_dir)/build/.Occlum_sys.json: $(INITFS_IMAGE) $(INITFS_IMAGE_MAC) $(JSON_CONF)
|
$(instance_dir)/build/Enclave.xml:
|
||||||
@$(occlum_dir)/build/bin/gen_internal_conf --user_json "$(JSON_CONF)" gen_sys_conf \
|
$(instance_dir)/build/.Occlum_sys.json: $(INITFS_IMAGE) $(INITFS_IMAGE_MAC) $(JSON_CONF) $(SECURE_IMAGE) $(SECURE_IMAGE_MAC)
|
||||||
--init_fs_mac "`cat $(INITFS_IMAGE_MAC)`" --sys_json $(instance_dir)/build/.Occlum_sys.json
|
@$(occlum_dir)/build/bin/gen_internal_conf --user_json "$(JSON_CONF)" gen_conf \
|
||||||
|
--user_fs_mac "`cat $(SECURE_IMAGE_MAC)`" --sdk_xml "$(instance_dir)/build/Enclave.xml" \
|
||||||
|
--init_fs_mac "`cat $(INITFS_IMAGE_MAC)`" --output_json $(instance_dir)/build/.Occlum_sys.json
|
||||||
|
|
||||||
$(BIN_LINKS): $(instance_dir)/build/bin/%: $(occlum_dir)/build/bin/% | $(instance_dir)/build/bin
|
$(BIN_LINKS): $(instance_dir)/build/bin/%: $(occlum_dir)/build/bin/% | $(instance_dir)/build/bin
|
||||||
@ln -sf $< $@
|
@ln -sf $< $@
|
||||||
@ -103,24 +105,11 @@ $(INITFS_IMAGE): $(INITFS) $(INITFS_DIRS) $(INITFS_FILES) $(IMAGE_CONFIG_JSON) $
|
|||||||
"$(instance_dir)/build/initfs/__ROOT" \
|
"$(instance_dir)/build/initfs/__ROOT" \
|
||||||
"$(INITFS_IMAGE_MAC)"
|
"$(INITFS_IMAGE_MAC)"
|
||||||
|
|
||||||
$(IMAGE_CONFIG_JSON): $(instance_dir)/build/Occlum.json.protected
|
$(IMAGE_CONFIG_JSON):
|
||||||
@$(call get_occlum_file_mac, "$(instance_dir)/build/Occlum.json.protected", "$(CONF_TMP_MAC)") && \
|
@mkdir -p "$(instance_dir)/build/lib"
|
||||||
[ -n "$(SECURE_IMAGE_KEY)" ] && \
|
@[ -n "$(SECURE_IMAGE_KEY)" ] && \
|
||||||
jq -n --arg mac_val "`cat $(CONF_TMP_MAC)`" \
|
jq -n '{image_type: "encrypted"}' > $(IMAGE_CONFIG_JSON) || \
|
||||||
'{image_type: "encrypted", occlum_json_mac: $$mac_val}' > $(IMAGE_CONFIG_JSON) || \
|
jq -n '{image_type: "integrity-only"}' > $(IMAGE_CONFIG_JSON)
|
||||||
jq -n --arg mac_val "`cat $(CONF_TMP_MAC)`" \
|
|
||||||
'{image_type: "integrity-only", occlum_json_mac: $$mac_val}' > $(IMAGE_CONFIG_JSON)
|
|
||||||
@rm -f "$(CONF_TMP_MAC)"
|
|
||||||
|
|
||||||
$(instance_dir)/build/Occlum.json.protected: $(instance_dir)/build/Occlum.json
|
|
||||||
@cd "$(instance_dir)/build" ; \
|
|
||||||
LD_LIBRARY_PATH="$(SGX_SDK)/sdk_libs" "$(occlum_dir)/build/bin/occlum-protect-integrity" protect Occlum.json ;
|
|
||||||
|
|
||||||
$(instance_dir)/build/Enclave.xml:
|
|
||||||
$(instance_dir)/build/Occlum.json: $(SECURE_IMAGE) $(SECURE_IMAGE_MAC) $(JSON_CONF) | $(instance_dir)/build/lib
|
|
||||||
@$(occlum_dir)/build/bin/gen_internal_conf --user_json "$(JSON_CONF)" gen_user_conf \
|
|
||||||
--user_fs_mac "`cat $(SECURE_IMAGE_MAC)`" --sdk_xml "$(instance_dir)/build/Enclave.xml" \
|
|
||||||
--output_user_json $(instance_dir)/build/Occlum.json
|
|
||||||
|
|
||||||
# If image dir not exist, just use the secure Occlum FS image
|
# If image dir not exist, just use the secure Occlum FS image
|
||||||
ifneq ($(wildcard $(IMAGE)/. ),)
|
ifneq ($(wildcard $(IMAGE)/. ),)
|
||||||
|
Loading…
Reference in New Issue
Block a user