summaryrefslogtreecommitdiff
path: root/runtime/permissions/lib.rs
diff options
context:
space:
mode:
authorMatt Mastracci <matthew@mastracci.com>2024-05-10 11:21:36 -0600
committerGitHub <noreply@github.com>2024-05-10 11:21:36 -0600
commitadc7b3de2695a1371a5179329b4a5aa90a3aef84 (patch)
treecce4a582c39d834f54b60c4d8dd7c09d24971ccc /runtime/permissions/lib.rs
parenta9708037c9e333104bfdfe0ccadbc40395809c39 (diff)
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
Diffstat (limited to 'runtime/permissions/lib.rs')
-rw-r--r--runtime/permissions/lib.rs39
1 files changed, 39 insertions, 0 deletions
diff --git a/runtime/permissions/lib.rs b/runtime/permissions/lib.rs
index 70d1abae7..06db9958c 100644
--- a/runtime/permissions/lib.rs
+++ b/runtime/permissions/lib.rs
@@ -1680,7 +1680,46 @@ impl PermissionsContainer {
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") {
+ // 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")
|| path.starts_with("/proc")
|| path.starts_with("/sys")