Skip to content

Commit 32bd148

Browse files
committed
Check the execution permission in the execution engine before running.
1 parent b683b8b commit 32bd148

File tree

8 files changed

+38
-66
lines changed

8 files changed

+38
-66
lines changed

Diff for: crates/execution-engine/src/engines/common.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
//! information on licensing and copyright.
1818
1919
use anyhow::Result;
20-
use std::vec::Vec;
20+
use std::path::Path;
2121

2222
////////////////////////////////////////////////////////////////////////////////
2323
// The strategy trait.

Diff for: crates/execution-engine/src/engines/wasmtime.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::{
1818
use anyhow::Result;
1919
use log::info;
2020
use std::{
21-
vec::Vec,
21+
path::Path,
2222
fs::{create_dir_all, File},
2323
};
2424
use wasmtime::{Config, Engine, Linker, Module, Store};
@@ -70,7 +70,7 @@ impl ExecutionEngine for WasmtimeRuntimeState {
7070
/// program, along with a host state capturing the result of the program's
7171
/// execution.
7272
#[inline]
73-
fn invoke_entry_point(&mut self, program: Vec<u8>) -> Result<u32> {
73+
fn serve(&mut self, input: &Path) -> Result<()> {
7474
info!("Initialize a wasmtime engine.");
7575

7676
let mut config = Config::default();
@@ -98,7 +98,7 @@ impl ExecutionEngine for WasmtimeRuntimeState {
9898

9999
let wasi = wasm_build.build();
100100
let mut store = Store::new(&engine, wasi);
101-
let module = Module::new(&engine, program)?;
101+
let module = Module::from_file(&engine, input)?;
102102
linker.module(&mut store, "", &module)?;
103103

104104
info!("Engine readies.");
@@ -114,6 +114,6 @@ impl ExecutionEngine for WasmtimeRuntimeState {
114114

115115
info!("Execution returns.");
116116

117-
Ok(0)
117+
Ok(())
118118
}
119119
}

Diff for: crates/execution-engine/src/lib.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,10 @@ pub struct Environment {
4949
/// such as `freestanding-execution-engine` and `runtime-manager` can rely on.
5050
pub fn execute(
5151
strategy: &ExecutionStrategy,
52-
permissions: &PrincipalPermission,
52+
caller_permissions: &PrincipalPermission,
53+
execution_permissions: &PrincipalPermission,
5354
pipeline: Box<Expr>,
5455
env: &Environment,
55-
) -> anyhow::Result<u32> {
56-
Ok(pipeline::execute_pipeline(strategy, permissions, pipeline, env)?)
56+
) -> anyhow::Result<()> {
57+
pipeline::execute_pipeline(strategy, caller_permissions, execution_permissions, pipeline, env)
5758
}

Diff for: crates/execution-engine/src/native_modules/common.rs

-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
use anyhow::Result;
1313
use crate::{
1414
native_modules::{echo::EchoService, postcard::PostcardService, aes::AesCounterModeService}
15-
1615
};
1716
use std::{fs::{create_dir_all, remove_file}, sync::Once, path::{Path, PathBuf}, thread::{spawn, JoinHandle}};
1817
use log::info;

Diff for: crates/execution-engine/src/pipeline.rs

+21-24
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ use anyhow::{anyhow, Result};
2727
use log::info;
2828
use policy_utils::{
2929
pipeline::Expr,
30-
principal::{PrincipalPermission, ExecutionStrategy, NativeModule, NativeModuleType},
30+
principal::{PrincipalPermission, FilePermissions, ExecutionStrategy, NativeModule, NativeModuleType, check_permission},
3131
};
32-
use std::{boxed::Box, path::{Path, PathBuf}, fs};
32+
use std::{boxed::Box, path::{Path, PathBuf}};
3333

3434
/// Returns whether the given path corresponds to a WASM binary.
3535
fn is_wasm_binary(path_string: &String) -> bool {
@@ -41,21 +41,23 @@ fn is_wasm_binary(path_string: &String) -> bool {
4141
/// The function will return the error code.
4242
pub fn execute_pipeline(
4343
strategy: &ExecutionStrategy,
44+
caller_permissions: &PrincipalPermission,
4445
execution_permissions: &PrincipalPermission,
4546
pipeline: Box<Expr>,
4647
env: &Environment,
47-
) -> Result<u32> {
48+
) -> Result<()> {
4849
use policy_utils::pipeline::Expr::*;
4950
match *pipeline {
5051
Literal(path) => {
5152
info!("Literal {:?}", path);
53+
// checker permission
54+
if !check_permission(&caller_permissions, path.clone(), &FilePermissions{read: false, write: false, execute: true}) {
55+
return Err(anyhow!("Permission denies"));
56+
}
5257
if is_wasm_binary(&path) {
5358
info!("Read wasm binary: {}", path);
5459
// Read and call execute_WASM program
55-
let binary = fs::read(path)?;
56-
let return_code =
57-
execute_program(strategy, execution_permissions, binary, env)?;
58-
Ok(return_code)
60+
execute_program(strategy, execution_permissions, &Path::new(&path), env)
5961
} else {
6062
info!("Invoke native binary: {}", path);
6163
// Treat program as a provisioned native module
@@ -73,32 +75,27 @@ pub fn execute_pipeline(
7375
NativeModuleManager::new(native_module);
7476
native_module_manager
7577
.execute(vec![])
76-
.map(|_| 0)
78+
.map(|_| ())
7779
.map_err(|err| anyhow!(err))
7880
}
7981
}
8082
Seq(vec) => {
8183
info!("Seq {:?}", vec);
8284
for expr in vec {
83-
let return_code = execute_pipeline(strategy, execution_permissions, expr, env)?;
84-
85-
// An error occurs
86-
if return_code != 0 {
87-
return Ok(return_code);
88-
}
85+
execute_pipeline(strategy, caller_permissions, execution_permissions, expr, env)?;
8986
}
9087

9188
// default return_code is zero.
92-
Ok(0)
89+
Ok(())
9390
}
9491
IfElse(cond, true_branch, false_branch) => {
9592
info!("IfElse {:?} true -> {:?} false -> {:?}", cond, true_branch, false_branch);
9693
let return_code = if Path::new(&cond).exists() {
97-
execute_pipeline(strategy, execution_permissions, true_branch, env)?
94+
execute_pipeline(strategy, caller_permissions, execution_permissions, true_branch, env)?
9895
} else {
9996
match false_branch {
100-
Some(f) => execute_pipeline(strategy, execution_permissions, f, env)?,
101-
None => 0,
97+
Some(f) => execute_pipeline(strategy, caller_permissions, execution_permissions, f, env)?,
98+
None => (),
10299
}
103100
};
104101
Ok(return_code)
@@ -109,11 +106,11 @@ pub fn execute_pipeline(
109106
/// Execute the `program`. All I/O operations in the program are through at `filesystem`.
110107
fn execute_program(
111108
strategy: &ExecutionStrategy,
112-
permissions: &PrincipalPermission,
113-
program: Vec<u8>,
109+
execution_permissions: &PrincipalPermission,
110+
program_path: &Path,
114111
env: &Environment,
115-
) -> Result<u32> {
116-
info!("Execute program with permissions {:?}", permissions);
112+
) -> Result<()> {
113+
info!("Execute program with permissions {:?}", execution_permissions);
117114
initial_service();
118115
let mut engine: Box<dyn ExecutionEngine> = match strategy {
119116
ExecutionStrategy::Interpretation => {
@@ -123,7 +120,7 @@ fn execute_program(
123120
cfg_if::cfg_if! {
124121
if #[cfg(any(feature = "std", feature = "nitro"))] {
125122
info!("JIT engine initialising");
126-
Box::new(WasmtimeRuntimeState::new(permissions.clone(), env.clone())?)
123+
Box::new(WasmtimeRuntimeState::new(execution_permissions.clone(), env.clone())?)
127124

128125
} else {
129126
return Err(anyhow!("No JIT enine."));
@@ -132,5 +129,5 @@ fn execute_program(
132129
}
133130
};
134131
info!("engine call");
135-
engine.invoke_entry_point(program)
132+
engine.serve(program_path)
136133
}

Diff for: crates/freestanding-execution-engine/src/main.rs

+1
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@ fn main() -> Result<(), Box<dyn Error>> {
303303
let return_code = execute(
304304
&cmdline.execution_strategy,
305305
&permission,
306+
&permission,
306307
cmdline.pipeline.clone(),
307308
&env,
308309
)?;

Diff for: crates/policy-utils/src/policy.rs

+1-29
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
use super::{
3838
error::PolicyError,
3939
expiry::Timepoint,
40-
principal::{PrincipalPermission, FilePermissions, ExecutionStrategy, FileHash, Identity, NativeModule, Pipeline, Principal, Program},
40+
principal::{PrincipalPermission, ExecutionStrategy, FileHash, Identity, NativeModule, Pipeline, Principal, Program},
4141
Platform,
4242
};
4343
use anyhow::{anyhow, Result};
@@ -367,38 +367,10 @@ impl Policy {
367367
Ok(table)
368368
}
369369

370-
/// Return the program input table, mapping program filenames to their expected input filenames.
371-
pub fn get_input_table(&self) -> Result<HashMap<String, Vec<PathBuf>>> {
372-
let mut table = HashMap::new();
373-
for program in &self.programs {
374-
let program_file_name = program.program_file_name();
375-
let file_rights_map = program.file_rights_map();
376-
table.insert(
377-
program_file_name.to_string(),
378-
Self::get_required_inputs(&file_rights_map),
379-
);
380-
}
381-
Ok(table)
382-
}
383-
384370
/// Return the pipeline of `pipeline_id`
385371
pub fn get_pipeline(&self, pipeline_id: usize) -> Result<&Pipeline> {
386372
self.pipelines
387373
.get(pipeline_id)
388374
.ok_or(anyhow!("Failed to find pipeline {}", pipeline_id))
389375
}
390-
391-
/// Extract the input filenames from a right_map. If a program has rights call
392-
/// fd_read and path_open, it is considered as an input file.
393-
fn get_required_inputs(right_map: &HashMap<PathBuf, FilePermissions>) -> Vec<PathBuf> {
394-
right_map
395-
.iter()
396-
.filter_map(|(k,v)| {
397-
if v.read {
398-
Some(k.clone())
399-
} else {
400-
None
401-
}
402-
}).collect()
403-
}
404376
}

Diff for: crates/runtime-manager/src/managers/mod.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -233,16 +233,18 @@ impl ProtocolState {
233233
..Default::default()
234234
};
235235

236-
let permission = self.global_policy.get_permission(execution_principal)?;
236+
let caller_permission = self.global_policy.get_permission(caller_principal)?;
237+
let execution_permission = self.global_policy.get_permission(execution_principal)?;
237238

238-
let return_code = execute(
239+
execute(
239240
&execution_strategy,
240-
&permission,
241+
&caller_permission,
242+
&execution_permission,
241243
pipeline,
242244
&env,
243245
)?;
244246

245-
let response = Self::response_error_code_returned(return_code);
247+
let response = Self::response_error_code_returned(0);
246248
Ok(Some(response))
247249
}
248250

0 commit comments

Comments
 (0)