diff options
author | crowlKats <13135287+crowlKats@users.noreply.github.com> | 2021-04-13 13:25:21 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-13 13:25:21 +0200 |
commit | 8b59d9f7bc2ce4aa33b6b8ac41495c62d3791f3c (patch) | |
tree | 2dbbd97062244f65145e917ee6025e5ac595675a /runtime/ops | |
parent | ec1fce58d93de61462ddf0c9e9c58e6e844d2230 (diff) |
feat(permissions): allow env permission to take values (#9825)
Diffstat (limited to 'runtime/ops')
-rw-r--r-- | runtime/ops/os.rs | 19 | ||||
-rw-r--r-- | runtime/ops/permissions.rs | 7 | ||||
-rw-r--r-- | runtime/ops/worker_host.rs | 48 |
3 files changed, 59 insertions, 15 deletions
diff --git a/runtime/ops/os.rs b/runtime/ops/os.rs index b9511fcdc..c2c9fb550 100644 --- a/runtime/ops/os.rs +++ b/runtime/ops/os.rs @@ -54,7 +54,7 @@ fn op_set_env( args: SetEnv, _zero_copy: Option<ZeroCopyBuf>, ) -> Result<(), AnyError> { - state.borrow_mut::<Permissions>().env.check()?; + state.borrow_mut::<Permissions>().env.check(&args.key)?; let invalid_key = args.key.is_empty() || args.key.contains(&['=', '\0'] as &[char]); let invalid_value = args.value.contains('\0'); @@ -70,7 +70,7 @@ fn op_env( _args: (), _zero_copy: Option<ZeroCopyBuf>, ) -> Result<HashMap<String, String>, AnyError> { - state.borrow_mut::<Permissions>().env.check()?; + state.borrow_mut::<Permissions>().env.check_all()?; Ok(env::vars().collect()) } @@ -79,7 +79,7 @@ fn op_get_env( key: String, _zero_copy: Option<ZeroCopyBuf>, ) -> Result<Option<String>, AnyError> { - state.borrow_mut::<Permissions>().env.check()?; + state.borrow_mut::<Permissions>().env.check(&key)?; if key.is_empty() || key.contains(&['=', '\0'] as &[char]) { return Err(type_error("Key contains invalid characters.")); } @@ -89,12 +89,13 @@ fn op_get_env( }; Ok(r) } + fn op_delete_env( state: &mut OpState, key: String, _zero_copy: Option<ZeroCopyBuf>, ) -> Result<(), AnyError> { - state.borrow_mut::<Permissions>().env.check()?; + state.borrow_mut::<Permissions>().env.check(&key)?; if key.is_empty() || key.contains(&['=', '\0'] as &[char]) { return Err(type_error("Key contains invalid characters.")); } @@ -116,7 +117,7 @@ fn op_loadavg( _zero_copy: Option<ZeroCopyBuf>, ) -> Result<(f64, f64, f64), AnyError> { super::check_unstable(state, "Deno.loadavg"); - state.borrow_mut::<Permissions>().env.check()?; + state.borrow_mut::<Permissions>().env.check_all()?; match sys_info::loadavg() { Ok(loadavg) => Ok((loadavg.one, loadavg.five, loadavg.fifteen)), Err(_) => Ok((0.0, 0.0, 0.0)), @@ -129,7 +130,7 @@ fn op_hostname( _zero_copy: Option<ZeroCopyBuf>, ) -> Result<String, AnyError> { super::check_unstable(state, "Deno.hostname"); - state.borrow_mut::<Permissions>().env.check()?; + state.borrow_mut::<Permissions>().env.check_all()?; let hostname = sys_info::hostname().unwrap_or_else(|_| "".to_string()); Ok(hostname) } @@ -140,7 +141,7 @@ fn op_os_release( _zero_copy: Option<ZeroCopyBuf>, ) -> Result<String, AnyError> { super::check_unstable(state, "Deno.osRelease"); - state.borrow_mut::<Permissions>().env.check()?; + state.borrow_mut::<Permissions>().env.check_all()?; let release = sys_info::os_release().unwrap_or_else(|_| "".to_string()); Ok(release) } @@ -164,7 +165,7 @@ fn op_system_memory_info( _zero_copy: Option<ZeroCopyBuf>, ) -> Result<Option<MemInfo>, AnyError> { super::check_unstable(state, "Deno.systemMemoryInfo"); - state.borrow_mut::<Permissions>().env.check()?; + state.borrow_mut::<Permissions>().env.check_all()?; match sys_info::mem_info() { Ok(info) => Ok(Some(MemInfo { total: info.total, @@ -191,7 +192,7 @@ fn op_system_cpu_info( _zero_copy: Option<ZeroCopyBuf>, ) -> Result<CpuInfo, AnyError> { super::check_unstable(state, "Deno.systemCpuInfo"); - state.borrow_mut::<Permissions>().env.check()?; + state.borrow_mut::<Permissions>().env.check_all()?; let cores = sys_info::cpu_num().ok(); let speed = sys_info::cpu_speed().ok(); diff --git a/runtime/ops/permissions.rs b/runtime/ops/permissions.rs index ce89def54..832af485b 100644 --- a/runtime/ops/permissions.rs +++ b/runtime/ops/permissions.rs @@ -21,6 +21,7 @@ pub struct PermissionArgs { name: String, path: Option<String>, host: Option<String>, + variable: Option<String>, command: Option<String>, } @@ -41,7 +42,7 @@ pub fn op_query_permission( } .as_ref(), ), - "env" => permissions.env.query(), + "env" => permissions.env.query(args.variable.as_deref()), "run" => permissions.run.query(args.command.as_deref()), "plugin" => permissions.plugin.query(), "hrtime" => permissions.hrtime.query(), @@ -72,7 +73,7 @@ pub fn op_revoke_permission( } .as_ref(), ), - "env" => permissions.env.revoke(), + "env" => permissions.env.revoke(args.variable.as_deref()), "run" => permissions.run.revoke(args.command.as_deref()), "plugin" => permissions.plugin.revoke(), "hrtime" => permissions.hrtime.revoke(), @@ -103,7 +104,7 @@ pub fn op_request_permission( } .as_ref(), ), - "env" => permissions.env.request(), + "env" => permissions.env.request(args.variable.as_deref()), "run" => permissions.run.request(args.command.as_deref()), "plugin" => permissions.plugin.request(), "hrtime" => permissions.hrtime.request(), diff --git a/runtime/ops/worker_host.rs b/runtime/ops/worker_host.rs index 92de420e3..905ae1334 100644 --- a/runtime/ops/worker_host.rs +++ b/runtime/ops/worker_host.rs @@ -1,6 +1,8 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. + use crate::permissions::resolve_read_allowlist; use crate::permissions::resolve_write_allowlist; +use crate::permissions::EnvDescriptor; use crate::permissions::NetDescriptor; use crate::permissions::PermissionState; use crate::permissions::Permissions; @@ -186,6 +188,26 @@ fn merge_write_permission( Ok(main) } +fn merge_env_permission( + mut main: UnaryPermission<EnvDescriptor>, + worker: Option<UnaryPermission<EnvDescriptor>>, +) -> Result<UnaryPermission<EnvDescriptor>, AnyError> { + if let Some(worker) = worker { + if (worker.global_state < main.global_state) + || !worker.granted_list.iter().all(|x| main.check(&x.0).is_ok()) + { + return Err(custom_error( + "PermissionDenied", + "Can't escalate parent thread permissions", + )); + } else { + main.global_state = worker.global_state; + main.granted_list = worker.granted_list; + } + } + Ok(main) +} + fn merge_run_permission( mut main: UnaryPermission<RunDescriptor>, worker: Option<UnaryPermission<RunDescriptor>>, @@ -211,7 +233,7 @@ fn create_worker_permissions( worker_perms: PermissionsArg, ) -> Result<Permissions, AnyError> { Ok(Permissions { - env: merge_boolean_permission(main_perms.env, worker_perms.env)?, + env: merge_env_permission(main_perms.env, worker_perms.env)?, hrtime: merge_boolean_permission(main_perms.hrtime, worker_perms.hrtime)?, net: merge_net_permission(main_perms.net, worker_perms.net)?, plugin: merge_boolean_permission(main_perms.plugin, worker_perms.plugin)?, @@ -223,8 +245,8 @@ fn create_worker_permissions( #[derive(Debug, Deserialize)] struct PermissionsArg { - #[serde(default, deserialize_with = "as_permission_state")] - env: Option<PermissionState>, + #[serde(default, deserialize_with = "as_unary_env_permission")] + env: Option<UnaryPermission<EnvDescriptor>>, #[serde(default, deserialize_with = "as_permission_state")] hrtime: Option<PermissionState>, #[serde(default, deserialize_with = "as_unary_net_permission")] @@ -366,6 +388,26 @@ where })) } +fn as_unary_env_permission<'de, D>( + deserializer: D, +) -> Result<Option<UnaryPermission<EnvDescriptor>>, D::Error> +where + D: Deserializer<'de>, +{ + let value: UnaryPermissionBase = + deserializer.deserialize_any(ParseBooleanOrStringVec)?; + + Ok(Some(UnaryPermission::<EnvDescriptor> { + global_state: value.global_state, + granted_list: value + .paths + .into_iter() + .map(|env| EnvDescriptor(env.to_uppercase())) + .collect(), + ..Default::default() + })) +} + fn as_unary_run_permission<'de, D>( deserializer: D, ) -> Result<Option<UnaryPermission<RunDescriptor>>, D::Error> |