Check program paths against entry points in Occlum.json
This commit is contained in:
		
							parent
							
								
									4cb63a4d99
								
							
						
					
					
						commit
						1a56fc4b72
					
				| @ -10,6 +10,9 @@ | ||||
|     "env": [ | ||||
|         "OCCLUM=yes" | ||||
|     ], | ||||
|     "entry_points": [ | ||||
|         "/bin" | ||||
|     ], | ||||
|     "mount": [ | ||||
|         { | ||||
|             "target": "/", | ||||
|  | ||||
| @ -80,6 +80,7 @@ pub struct Config { | ||||
|     pub vm: ConfigVM, | ||||
|     pub process: ConfigProcess, | ||||
|     pub env: Vec<CString>, | ||||
|     pub entry_points: Vec<PathBuf>, | ||||
|     pub mount: Vec<ConfigMount>, | ||||
| } | ||||
| 
 | ||||
| @ -128,6 +129,17 @@ impl Config { | ||||
|             } | ||||
|             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 mut mount = Vec::new(); | ||||
|             for input_mount in &input.mount { | ||||
| @ -139,6 +151,7 @@ impl Config { | ||||
|             vm, | ||||
|             process, | ||||
|             env, | ||||
|             entry_points, | ||||
|             mount, | ||||
|         }) | ||||
|     } | ||||
| @ -246,6 +259,8 @@ struct InputConfig { | ||||
|     #[serde(default)] | ||||
|     pub env: Vec<String>, | ||||
|     #[serde(default)] | ||||
|     pub entry_points: Vec<String>, | ||||
|     #[serde(default)] | ||||
|     pub mount: Vec<InputConfigMount>, | ||||
| } | ||||
| 
 | ||||
| @ -269,7 +284,6 @@ impl Default for InputConfigVM { | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Deserialize, Debug)] | ||||
| #[serde(deny_unknown_fields)] | ||||
| struct InputConfigProcess { | ||||
|  | ||||
| @ -2,7 +2,7 @@ use super::*; | ||||
| use exception::*; | ||||
| use process::pid_t; | ||||
| use std::ffi::{CStr, CString, OsString}; | ||||
| use std::path::Path; | ||||
| use std::path::{Path, PathBuf}; | ||||
| use util::mem_util::from_untrusted::*; | ||||
| 
 | ||||
| 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; | ||||
| 
 | ||||
| fn parse_arguments( | ||||
|     path_buf: *const c_char, | ||||
|     path_ptr: *const c_char, | ||||
|     argv: *const *const c_char, | ||||
| ) -> Result<(String, Vec<CString>)> { | ||||
|     let path_string = { | ||||
|         let path_cstring = clone_cstring_safely(path_buf)?; | ||||
|         path_cstring.to_string_lossy().into_owned() | ||||
| ) -> Result<(PathBuf, Vec<CString>)> { | ||||
|     let path_buf = { | ||||
|         let path_cstring = clone_cstring_safely(path_ptr)?; | ||||
|         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_osstr = Path::new(&path_string) | ||||
|         let program_osstr = path_buf | ||||
|             .file_name() | ||||
|             .ok_or_else(|| errno!(EINVAL, "invalid path"))?; | ||||
|         let program_str = program_osstr | ||||
| @ -79,18 +82,20 @@ fn parse_arguments( | ||||
| 
 | ||||
|     let mut args = clone_cstrings_safely(argv)?; | ||||
|     args.insert(0, program_cstring); | ||||
|     Ok((path_string, args)) | ||||
|     Ok((path_buf, args)) | ||||
| } | ||||
| 
 | ||||
| // 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);
 | ||||
|     util::mpx_util::mpx_enable()?; | ||||
| 
 | ||||
|     validate_program_path(program_path)?; | ||||
| 
 | ||||
|     let envp = &config::LIBOS_CONFIG.env; | ||||
|     let file_actions = Vec::new(); | ||||
|     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(()) | ||||
| } | ||||
| @ -106,3 +111,32 @@ fn do_run(host_tid: pid_t) -> Result<i32> { | ||||
| 
 | ||||
|     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", | ||||
|         "TEST=true" | ||||
|     ], | ||||
|     "entry_points": [ | ||||
|         "/bin" | ||||
|     ], | ||||
|     "mount": [ | ||||
|         { | ||||
|             "target": "/", | ||||
|  | ||||
| @ -52,6 +52,11 @@ get_conf_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() { | ||||
|     "$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 | ||||
|     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/libstdc++.so.6" \ | ||||
|         "$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_MMAP_SIZE=`get_conf_default_mmap_size` | ||||
|     export OCCLUM_CONF_ENV=`get_conf_env` | ||||
|     export OCCLUM_CONF_ENTRY_POINTS=`get_conf_entry_points` | ||||
|     cd "$context_dir/build" | ||||
|     "$occlum_dir/build/bin/occlum-gen-default-occlum-json"\ | ||||
|         > "Occlum.json" | ||||
|  | ||||
| @ -34,6 +34,7 @@ cat <<EOF | ||||
|             "type": "ramfs" | ||||
|         } | ||||
|     ], | ||||
|     "env": $OCCLUM_CONF_ENV | ||||
|     "env": $OCCLUM_CONF_ENV, | ||||
|     "entry_points": $OCCLUM_CONF_ENTRY_POINTS | ||||
| } | ||||
| EOF | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user