Check program paths against entry points in Occlum.json
This commit is contained in:
parent
4cb63a4d99
commit
1a56fc4b72
@ -10,6 +10,9 @@
|
|||||||
"env": [
|
"env": [
|
||||||
"OCCLUM=yes"
|
"OCCLUM=yes"
|
||||||
],
|
],
|
||||||
|
"entry_points": [
|
||||||
|
"/bin"
|
||||||
|
],
|
||||||
"mount": [
|
"mount": [
|
||||||
{
|
{
|
||||||
"target": "/",
|
"target": "/",
|
||||||
|
@ -80,6 +80,7 @@ pub struct Config {
|
|||||||
pub vm: ConfigVM,
|
pub vm: ConfigVM,
|
||||||
pub process: ConfigProcess,
|
pub process: ConfigProcess,
|
||||||
pub env: Vec<CString>,
|
pub env: Vec<CString>,
|
||||||
|
pub entry_points: Vec<PathBuf>,
|
||||||
pub mount: Vec<ConfigMount>,
|
pub mount: Vec<ConfigMount>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,6 +129,17 @@ impl Config {
|
|||||||
}
|
}
|
||||||
env
|
env
|
||||||
};
|
};
|
||||||
|
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 mount = {
|
||||||
let mut mount = Vec::new();
|
let mut mount = Vec::new();
|
||||||
for input_mount in &input.mount {
|
for input_mount in &input.mount {
|
||||||
@ -139,6 +151,7 @@ impl Config {
|
|||||||
vm,
|
vm,
|
||||||
process,
|
process,
|
||||||
env,
|
env,
|
||||||
|
entry_points,
|
||||||
mount,
|
mount,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -246,6 +259,8 @@ struct InputConfig {
|
|||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub env: Vec<String>,
|
pub env: Vec<String>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
pub entry_points: Vec<String>,
|
||||||
|
#[serde(default)]
|
||||||
pub mount: Vec<InputConfigMount>,
|
pub mount: Vec<InputConfigMount>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,7 +284,6 @@ impl Default for InputConfigVM {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct InputConfigProcess {
|
struct InputConfigProcess {
|
||||||
|
@ -2,7 +2,7 @@ use super::*;
|
|||||||
use exception::*;
|
use exception::*;
|
||||||
use process::pid_t;
|
use process::pid_t;
|
||||||
use std::ffi::{CStr, CString, OsString};
|
use std::ffi::{CStr, CString, OsString};
|
||||||
use std::path::Path;
|
use std::path::{Path, PathBuf};
|
||||||
use util::mem_util::from_untrusted::*;
|
use util::mem_util::from_untrusted::*;
|
||||||
|
|
||||||
const ENCLAVE_PATH: &'static str = ".occlum/build/lib/libocclum.signed.so";
|
const ENCLAVE_PATH: &'static str = ".occlum/build/lib/libocclum.signed.so";
|
||||||
@ -60,15 +60,18 @@ pub extern "C" fn dummy_ecall() -> i32 {
|
|||||||
const EXIT_STATUS_INTERNAL_ERROR: i32 = 127;
|
const EXIT_STATUS_INTERNAL_ERROR: i32 = 127;
|
||||||
|
|
||||||
fn parse_arguments(
|
fn parse_arguments(
|
||||||
path_buf: *const c_char,
|
path_ptr: *const c_char,
|
||||||
argv: *const *const c_char,
|
argv: *const *const c_char,
|
||||||
) -> Result<(String, Vec<CString>)> {
|
) -> Result<(PathBuf, Vec<CString>)> {
|
||||||
let path_string = {
|
let path_buf = {
|
||||||
let path_cstring = clone_cstring_safely(path_buf)?;
|
let path_cstring = clone_cstring_safely(path_ptr)?;
|
||||||
path_cstring.to_string_lossy().into_owned()
|
let path_string = path_cstring
|
||||||
|
.into_string()
|
||||||
|
.map_err(|e| errno!(EINVAL, "path contains valid utf-8 data"))?;
|
||||||
|
Path::new(&path_string).to_path_buf()
|
||||||
};
|
};
|
||||||
let program_cstring = {
|
let program_cstring = {
|
||||||
let program_osstr = Path::new(&path_string)
|
let program_osstr = path_buf
|
||||||
.file_name()
|
.file_name()
|
||||||
.ok_or_else(|| errno!(EINVAL, "invalid path"))?;
|
.ok_or_else(|| errno!(EINVAL, "invalid path"))?;
|
||||||
let program_str = program_osstr
|
let program_str = program_osstr
|
||||||
@ -79,18 +82,20 @@ fn parse_arguments(
|
|||||||
|
|
||||||
let mut args = clone_cstrings_safely(argv)?;
|
let mut args = clone_cstrings_safely(argv)?;
|
||||||
args.insert(0, program_cstring);
|
args.insert(0, program_cstring);
|
||||||
Ok((path_string, args))
|
Ok((path_buf, args))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: make sure do_boot can only be called once
|
// TODO: make sure do_boot can only be called once
|
||||||
fn do_boot(path_str: &str, argv: &Vec<CString>) -> Result<()> {
|
fn do_boot(program_path: &PathBuf, argv: &Vec<CString>) -> Result<()> {
|
||||||
// info!("boot: path: {:?}, argv: {:?}", path_str, argv);
|
// info!("boot: path: {:?}, argv: {:?}", path_str, argv);
|
||||||
util::mpx_util::mpx_enable()?;
|
util::mpx_util::mpx_enable()?;
|
||||||
|
|
||||||
|
validate_program_path(program_path)?;
|
||||||
|
|
||||||
let envp = &config::LIBOS_CONFIG.env;
|
let envp = &config::LIBOS_CONFIG.env;
|
||||||
let file_actions = Vec::new();
|
let file_actions = Vec::new();
|
||||||
let parent = &process::IDLE_PROCESS;
|
let parent = &process::IDLE_PROCESS;
|
||||||
process::do_spawn(&path_str, argv, envp, &file_actions, parent)?;
|
process::do_spawn(&program_path, argv, envp, &file_actions, parent)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -106,3 +111,32 @@ fn do_run(host_tid: pid_t) -> Result<i32> {
|
|||||||
|
|
||||||
Ok(exit_status)
|
Ok(exit_status)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn validate_program_path(target_path: &PathBuf) -> Result<()> {
|
||||||
|
if !target_path.is_absolute() {
|
||||||
|
return_errno!(EINVAL, "program path must be absolute");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forbid paths like /bin/../root, which may circument our prefix-based path matching
|
||||||
|
let has_parent_component = {
|
||||||
|
target_path
|
||||||
|
.components()
|
||||||
|
.any(|component| component == std::path::Component::ParentDir)
|
||||||
|
};
|
||||||
|
if has_parent_component {
|
||||||
|
return_errno!(
|
||||||
|
EINVAL,
|
||||||
|
"program path cannot contain any parent component (i.e., \"..\")"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check whether the prefix of the program path matches one of the entry points
|
||||||
|
let is_valid_entry_point = &config::LIBOS_CONFIG
|
||||||
|
.entry_points
|
||||||
|
.iter()
|
||||||
|
.any(|valid_path_prefix| target_path.starts_with(valid_path_prefix));
|
||||||
|
if !is_valid_entry_point {
|
||||||
|
return_errno!(EINVAL, "program path is a valid entry point");
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
@ -11,6 +11,9 @@
|
|||||||
"OCCLUM=yes",
|
"OCCLUM=yes",
|
||||||
"TEST=true"
|
"TEST=true"
|
||||||
],
|
],
|
||||||
|
"entry_points": [
|
||||||
|
"/bin"
|
||||||
|
],
|
||||||
"mount": [
|
"mount": [
|
||||||
{
|
{
|
||||||
"target": "/",
|
"target": "/",
|
||||||
|
@ -52,6 +52,11 @@ get_conf_env() {
|
|||||||
python -c "import sys, json; print json.dumps(json.load(sys.stdin)['env'])"
|
python -c "import sys, json; print json.dumps(json.load(sys.stdin)['env'])"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get_conf_entry_points() {
|
||||||
|
cat "$working_dir/Occlum.json" | \
|
||||||
|
python -c "import sys, json; print json.dumps(json.load(sys.stdin)['entry_points'])"
|
||||||
|
}
|
||||||
|
|
||||||
get_occlum_conf_file_mac() {
|
get_occlum_conf_file_mac() {
|
||||||
"$occlum_dir/build/bin/occlum-protect-integrity" show-mac "$context_dir/build/Occlum.json.protected"
|
"$occlum_dir/build/bin/occlum-protect-integrity" show-mac "$context_dir/build/Occlum.json.protected"
|
||||||
}
|
}
|
||||||
@ -78,7 +83,7 @@ cmd_init() {
|
|||||||
|
|
||||||
local occlum_gcc_lib=/usr/local/occlum/x86_64-linux-musl/lib
|
local occlum_gcc_lib=/usr/local/occlum/x86_64-linux-musl/lib
|
||||||
cp -t image/lib/ \
|
cp -t image/lib/ \
|
||||||
/lib/ld-musl-x86_64.so.1 \
|
/lib/ld-musl-x86_64.so.1 \
|
||||||
"$occlum_gcc_lib/libc.so" \
|
"$occlum_gcc_lib/libc.so" \
|
||||||
"$occlum_gcc_lib/libstdc++.so.6" \
|
"$occlum_gcc_lib/libstdc++.so.6" \
|
||||||
"$occlum_gcc_lib/libgcc_s.so.1" \
|
"$occlum_gcc_lib/libgcc_s.so.1" \
|
||||||
@ -121,6 +126,7 @@ cmd_build() {
|
|||||||
export OCCLUM_CONF_DEFAULT_HEAP_SIZE=`get_conf_default_heap_size`
|
export OCCLUM_CONF_DEFAULT_HEAP_SIZE=`get_conf_default_heap_size`
|
||||||
export OCCLUM_CONF_DEFAULT_MMAP_SIZE=`get_conf_default_mmap_size`
|
export OCCLUM_CONF_DEFAULT_MMAP_SIZE=`get_conf_default_mmap_size`
|
||||||
export OCCLUM_CONF_ENV=`get_conf_env`
|
export OCCLUM_CONF_ENV=`get_conf_env`
|
||||||
|
export OCCLUM_CONF_ENTRY_POINTS=`get_conf_entry_points`
|
||||||
cd "$context_dir/build"
|
cd "$context_dir/build"
|
||||||
"$occlum_dir/build/bin/occlum-gen-default-occlum-json"\
|
"$occlum_dir/build/bin/occlum-gen-default-occlum-json"\
|
||||||
> "Occlum.json"
|
> "Occlum.json"
|
||||||
|
@ -34,6 +34,7 @@ cat <<EOF
|
|||||||
"type": "ramfs"
|
"type": "ramfs"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"env": $OCCLUM_CONF_ENV
|
"env": $OCCLUM_CONF_ENV,
|
||||||
|
"entry_points": $OCCLUM_CONF_ENTRY_POINTS
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
Loading…
Reference in New Issue
Block a user