mirror of
https://github.com/denoland/deno.git
synced 2025-01-21 21:50:00 -05:00
fix(runtime): Allow opening /dev/fd/XXX for unix (#23743)
`deno run script.ts <(some command)` is a valid use case -- let's allow this to work without `--allow-all`. Fixes #23703
This commit is contained in:
parent
a9708037c9
commit
adc7b3de26
4 changed files with 63 additions and 0 deletions
|
@ -1680,7 +1680,46 @@ impl PermissionsContainer {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// We'll allow opening /proc/self/fd/{n} without additional permissions under the following conditions:
|
||||||
|
///
|
||||||
|
/// 1. n > 2. This allows for opening bash-style redirections, but not stdio
|
||||||
|
/// 2. the fd referred to by n is a pipe
|
||||||
|
#[cfg(unix)]
|
||||||
|
fn is_fd_file_is_pipe(path: &Path) -> bool {
|
||||||
|
if let Some(fd) = path.file_name() {
|
||||||
|
if let Ok(s) = std::str::from_utf8(fd.as_encoded_bytes()) {
|
||||||
|
if let Ok(n) = s.parse::<i32>() {
|
||||||
|
if n > 2 {
|
||||||
|
// SAFETY: This is proper use of the stat syscall
|
||||||
|
unsafe {
|
||||||
|
let mut stat = std::mem::zeroed::<libc::stat>();
|
||||||
|
if libc::fstat(n, &mut stat as _) == 0
|
||||||
|
&& ((stat.st_mode & libc::S_IFMT) & libc::S_IFIFO) != 0
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
// On unixy systems, we allow opening /dev/fd/XXX for valid FDs that
|
||||||
|
// are pipes.
|
||||||
|
#[cfg(unix)]
|
||||||
|
if path.starts_with("/dev/fd") && is_fd_file_is_pipe(path) {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
if cfg!(target_os = "linux") {
|
if cfg!(target_os = "linux") {
|
||||||
|
// On Linux, we also allow opening /proc/self/fd/XXX for valid FDs that
|
||||||
|
// are pipes.
|
||||||
|
#[cfg(unix)]
|
||||||
|
if path.starts_with("/proc/self/fd") && is_fd_file_is_pipe(path) {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
if path.starts_with("/dev")
|
if path.starts_with("/dev")
|
||||||
|| path.starts_with("/proc")
|
|| path.starts_with("/proc")
|
||||||
|| path.starts_with("/sys")
|
|| path.starts_with("/sys")
|
||||||
|
|
5
tests/specs/permission/proc_self_fd/__test__.jsonc
Normal file
5
tests/specs/permission/proc_self_fd/__test__.jsonc
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"args": "run -A main.js",
|
||||||
|
"output": "hi\n\n0\n",
|
||||||
|
"exitCode": 123
|
||||||
|
}
|
18
tests/specs/permission/proc_self_fd/main.js
Normal file
18
tests/specs/permission/proc_self_fd/main.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// This test is Linux/Darwin only
|
||||||
|
if (Deno.build.os !== "linux" && Deno.build.os !== "darwin") {
|
||||||
|
console.log("hi\n\n0");
|
||||||
|
Deno.exit(123);
|
||||||
|
}
|
||||||
|
|
||||||
|
const cmd = new Deno.Command("/usr/bin/env", {
|
||||||
|
args: [
|
||||||
|
"bash",
|
||||||
|
"-c",
|
||||||
|
[Deno.execPath(), "run", "--allow-read", "reader.ts", '<(echo "hi")'].join(
|
||||||
|
" ",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
}).spawn();
|
||||||
|
|
||||||
|
console.log((await cmd.status).code);
|
||||||
|
Deno.exit(123);
|
1
tests/specs/permission/proc_self_fd/reader.ts
Normal file
1
tests/specs/permission/proc_self_fd/reader.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
console.log(Deno.readTextFileSync(Deno.args[0]));
|
Loading…
Add table
Reference in a new issue