diff options
author | Matt Mastracci <matthew@mastracci.com> | 2024-05-10 11:21:36 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-10 11:21:36 -0600 |
commit | adc7b3de2695a1371a5179329b4a5aa90a3aef84 (patch) | |
tree | cce4a582c39d834f54b60c4d8dd7c09d24971ccc /runtime/permissions/lib.rs | |
parent | a9708037c9e333104bfdfe0ccadbc40395809c39 (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.rs | 39 |
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") |