mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 15:04:11 -05:00
fix(regression): do not expose resolved path in Deno.Command permission denied error (#25434)
Regression from https://github.com/denoland/deno/pull/25370
This commit is contained in:
parent
195b17ae12
commit
dd208a6df0
7 changed files with 99 additions and 21 deletions
|
@ -17,6 +17,7 @@ use deno_io::ChildStderrResource;
|
||||||
use deno_io::ChildStdinResource;
|
use deno_io::ChildStdinResource;
|
||||||
use deno_io::ChildStdoutResource;
|
use deno_io::ChildStdoutResource;
|
||||||
use deno_permissions::PermissionsContainer;
|
use deno_permissions::PermissionsContainer;
|
||||||
|
use deno_permissions::RunPathQuery;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
@ -516,7 +517,15 @@ fn compute_run_cmd_and_check_permissions(
|
||||||
.with_context(|| format!("Failed to spawn '{}'", arg_cmd))?;
|
.with_context(|| format!("Failed to spawn '{}'", arg_cmd))?;
|
||||||
let cmd = resolve_cmd(arg_cmd, &run_env)
|
let cmd = resolve_cmd(arg_cmd, &run_env)
|
||||||
.with_context(|| format!("Failed to spawn '{}'", arg_cmd))?;
|
.with_context(|| format!("Failed to spawn '{}'", arg_cmd))?;
|
||||||
check_run_permission(state, &cmd, &run_env, api_name)?;
|
check_run_permission(
|
||||||
|
state,
|
||||||
|
RunPathQuery {
|
||||||
|
requested: arg_cmd,
|
||||||
|
resolved: &cmd,
|
||||||
|
},
|
||||||
|
&run_env,
|
||||||
|
api_name,
|
||||||
|
)?;
|
||||||
Ok((cmd, run_env))
|
Ok((cmd, run_env))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -588,7 +597,7 @@ fn resolve_path(path: &str, cwd: &Path) -> PathBuf {
|
||||||
|
|
||||||
fn check_run_permission(
|
fn check_run_permission(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
cmd: &Path,
|
cmd: RunPathQuery,
|
||||||
run_env: &RunEnv,
|
run_env: &RunEnv,
|
||||||
api_name: &str,
|
api_name: &str,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), AnyError> {
|
||||||
|
|
|
@ -862,6 +862,12 @@ impl AsRef<str> for EnvDescriptor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct RunPathQuery<'a> {
|
||||||
|
pub requested: &'a str,
|
||||||
|
pub resolved: &'a Path,
|
||||||
|
}
|
||||||
|
|
||||||
pub enum RunDescriptorArg {
|
pub enum RunDescriptorArg {
|
||||||
Name(String),
|
Name(String),
|
||||||
Path(PathBuf),
|
Path(PathBuf),
|
||||||
|
@ -1321,16 +1327,16 @@ impl UnaryPermission<RunDescriptor> {
|
||||||
|
|
||||||
pub fn check(
|
pub fn check(
|
||||||
&mut self,
|
&mut self,
|
||||||
cmd: &Path,
|
cmd: RunPathQuery,
|
||||||
api_name: Option<&str>,
|
api_name: Option<&str>,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), AnyError> {
|
||||||
debug_assert!(cmd.is_absolute());
|
debug_assert!(cmd.resolved.is_absolute());
|
||||||
skip_check_if_is_permission_fully_granted!(self);
|
skip_check_if_is_permission_fully_granted!(self);
|
||||||
self.check_desc(
|
self.check_desc(
|
||||||
Some(&RunDescriptor::Path(cmd.to_path_buf())),
|
Some(&RunDescriptor::Path(cmd.resolved.to_path_buf())),
|
||||||
false,
|
false,
|
||||||
api_name,
|
api_name,
|
||||||
|| Some(format!("\"{}\"", cmd.display())),
|
|| Some(format!("\"{}\"", cmd.requested)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1692,7 +1698,7 @@ impl PermissionsContainer {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn check_run(
|
pub fn check_run(
|
||||||
&mut self,
|
&mut self,
|
||||||
cmd: &Path,
|
cmd: RunPathQuery,
|
||||||
api_name: &str,
|
api_name: &str,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), AnyError> {
|
||||||
self.0.lock().run.check(cmd, Some(api_name))
|
self.0.lock().run.check(cmd, Some(api_name))
|
||||||
|
@ -3036,10 +3042,37 @@ mod tests {
|
||||||
#[allow(clippy::disallowed_methods)]
|
#[allow(clippy::disallowed_methods)]
|
||||||
let cwd = std::env::current_dir().unwrap();
|
let cwd = std::env::current_dir().unwrap();
|
||||||
prompt_value.set(true);
|
prompt_value.set(true);
|
||||||
assert!(perms.run.check(&cwd.join("cat"), None).is_ok());
|
assert!(perms
|
||||||
|
.run
|
||||||
|
.check(
|
||||||
|
RunPathQuery {
|
||||||
|
requested: "cat",
|
||||||
|
resolved: &cwd.join("cat")
|
||||||
|
},
|
||||||
|
None
|
||||||
|
)
|
||||||
|
.is_ok());
|
||||||
prompt_value.set(false);
|
prompt_value.set(false);
|
||||||
assert!(perms.run.check(&cwd.join("cat"), None).is_ok());
|
assert!(perms
|
||||||
assert!(perms.run.check(&cwd.join("ls"), None).is_err());
|
.run
|
||||||
|
.check(
|
||||||
|
RunPathQuery {
|
||||||
|
requested: "cat",
|
||||||
|
resolved: &cwd.join("cat")
|
||||||
|
},
|
||||||
|
None
|
||||||
|
)
|
||||||
|
.is_ok());
|
||||||
|
assert!(perms
|
||||||
|
.run
|
||||||
|
.check(
|
||||||
|
RunPathQuery {
|
||||||
|
requested: "ls",
|
||||||
|
resolved: &cwd.join("ls")
|
||||||
|
},
|
||||||
|
None
|
||||||
|
)
|
||||||
|
.is_err());
|
||||||
|
|
||||||
prompt_value.set(true);
|
prompt_value.set(true);
|
||||||
assert!(perms.env.check("HOME", None).is_ok());
|
assert!(perms.env.check("HOME", None).is_ok());
|
||||||
|
@ -3133,12 +3166,48 @@ mod tests {
|
||||||
prompt_value.set(false);
|
prompt_value.set(false);
|
||||||
#[allow(clippy::disallowed_methods)]
|
#[allow(clippy::disallowed_methods)]
|
||||||
let cwd = std::env::current_dir().unwrap();
|
let cwd = std::env::current_dir().unwrap();
|
||||||
assert!(perms.run.check(&cwd.join("cat"), None).is_err());
|
assert!(perms
|
||||||
|
.run
|
||||||
|
.check(
|
||||||
|
RunPathQuery {
|
||||||
|
requested: "cat",
|
||||||
|
resolved: &cwd.join("cat")
|
||||||
|
},
|
||||||
|
None
|
||||||
|
)
|
||||||
|
.is_err());
|
||||||
prompt_value.set(true);
|
prompt_value.set(true);
|
||||||
assert!(perms.run.check(&cwd.join("cat"), None).is_err());
|
assert!(perms
|
||||||
assert!(perms.run.check(&cwd.join("ls"), None).is_ok());
|
.run
|
||||||
|
.check(
|
||||||
|
RunPathQuery {
|
||||||
|
requested: "cat",
|
||||||
|
resolved: &cwd.join("cat")
|
||||||
|
},
|
||||||
|
None
|
||||||
|
)
|
||||||
|
.is_err());
|
||||||
|
assert!(perms
|
||||||
|
.run
|
||||||
|
.check(
|
||||||
|
RunPathQuery {
|
||||||
|
requested: "ls",
|
||||||
|
resolved: &cwd.join("ls")
|
||||||
|
},
|
||||||
|
None
|
||||||
|
)
|
||||||
|
.is_ok());
|
||||||
prompt_value.set(false);
|
prompt_value.set(false);
|
||||||
assert!(perms.run.check(&cwd.join("ls"), None).is_ok());
|
assert!(perms
|
||||||
|
.run
|
||||||
|
.check(
|
||||||
|
RunPathQuery {
|
||||||
|
requested: "ls",
|
||||||
|
resolved: &cwd.join("ls")
|
||||||
|
},
|
||||||
|
None
|
||||||
|
)
|
||||||
|
.is_ok());
|
||||||
|
|
||||||
prompt_value.set(false);
|
prompt_value.set(false);
|
||||||
assert!(perms.env.check("HOME", None).is_err());
|
assert!(perms.env.check("HOME", None).is_err());
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
error: Uncaught (in promise) PermissionDenied: Requires run access to "[WILDLINE]deno[WILDLINE]", specify the required permissions during compilation using `deno compile --allow-run`
|
error: Uncaught (in promise) PermissionDenied: Requires run access to "deno", specify the required permissions during compilation using `deno compile --allow-run`
|
||||||
[WILDCARD]
|
[WILDCARD]
|
|
@ -1,10 +1,10 @@
|
||||||
Running...
|
Running...
|
||||||
PermissionDenied: Requires run access to "[WILDLINE]deno[WILDLINE]", run again with the --allow-run flag
|
PermissionDenied: Requires run access to "deno", run again with the --allow-run flag
|
||||||
[WILDCARD]
|
[WILDCARD]
|
||||||
at file:///[WILDLINE]/sub.ts:15:5 {
|
at file:///[WILDLINE]/sub.ts:15:5 {
|
||||||
name: "PermissionDenied"
|
name: "PermissionDenied"
|
||||||
}
|
}
|
||||||
PermissionDenied: Requires run access to "[WILDLINE]deno[WILDLINE]", run again with the --allow-run flag
|
PermissionDenied: Requires run access to "deno", run again with the --allow-run flag
|
||||||
[WILDCARD]
|
[WILDCARD]
|
||||||
at file:///[WILDLINE]/sub.ts:23:22 {
|
at file:///[WILDLINE]/sub.ts:23:22 {
|
||||||
name: "PermissionDenied"
|
name: "PermissionDenied"
|
||||||
|
|
|
@ -9,7 +9,7 @@ new Deno.Command(
|
||||||
"run",
|
"run",
|
||||||
"--allow-write",
|
"--allow-write",
|
||||||
"--allow-read",
|
"--allow-read",
|
||||||
`--allow-run=${binaryName}`,
|
`--allow-run=deno`,
|
||||||
"sub.ts",
|
"sub.ts",
|
||||||
],
|
],
|
||||||
stderr: "inherit",
|
stderr: "inherit",
|
||||||
|
|
|
@ -6,7 +6,7 @@ Deno.copyFileSync(binaryName, "subdir/" + binaryName);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const commandResult = new Deno.Command(
|
const commandResult = new Deno.Command(
|
||||||
binaryName,
|
"deno",
|
||||||
{
|
{
|
||||||
env: { "PATH": Deno.cwd() + pathSep + "subdir" },
|
env: { "PATH": Deno.cwd() + pathSep + "subdir" },
|
||||||
stdout: "inherit",
|
stdout: "inherit",
|
||||||
|
@ -22,7 +22,7 @@ try {
|
||||||
try {
|
try {
|
||||||
const child = Deno.run(
|
const child = Deno.run(
|
||||||
{
|
{
|
||||||
cmd: [binaryName],
|
cmd: ["deno"],
|
||||||
env: { "PATH": Deno.cwd() + pathSep + "subdir" },
|
env: { "PATH": Deno.cwd() + pathSep + "subdir" },
|
||||||
stdout: "inherit",
|
stdout: "inherit",
|
||||||
stderr: "inherit",
|
stderr: "inherit",
|
||||||
|
|
2
tests/testdata/run/089_run_allow_list.ts.out
vendored
2
tests/testdata/run/089_run_allow_list.ts.out
vendored
|
@ -1,3 +1,3 @@
|
||||||
[WILDCARD]PermissionDenied: Requires run access to "[WILDLINE]ls[WILDLINE]", run again with the --allow-run flag
|
[WILDCARD]PermissionDenied: Requires run access to "ls", run again with the --allow-run flag
|
||||||
[WILDCARD]
|
[WILDCARD]
|
||||||
true
|
true
|
||||||
|
|
Loading…
Reference in a new issue