From 9851e06199ee6d2b5b030b4063c176f9bc3e1665 Mon Sep 17 00:00:00 2001 From: Joinhack Date: Thu, 9 Jan 2025 19:21:57 +0800 Subject: [PATCH] path open for permission --- crates/wasi-common/src/blockless/prompter.rs | 12 +++++++----- crates/wasi-common/src/ctx.rs | 4 ++-- crates/wasi-common/src/snapshots/preview_1.rs | 10 +++++++--- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/crates/wasi-common/src/blockless/prompter.rs b/crates/wasi-common/src/blockless/prompter.rs index 5838487..0f3380c 100644 --- a/crates/wasi-common/src/blockless/prompter.rs +++ b/crates/wasi-common/src/blockless/prompter.rs @@ -227,10 +227,11 @@ impl PermissionPrompter for TtyPrompter { api_name: Option<&str>, is_unary: bool, ) -> PromptResponse { + if !std::io::stdin().is_terminal() || !std::io::stderr().is_terminal() { return PromptResponse::Deny; }; - + #[allow(clippy::print_stderr)] if message.len() > MAX_PERMISSION_PROMPT_LENGTH { eprintln!("❌ Permission prompt length ({} bytes) was larger than the configured maximum length ({} bytes): denying request.", message.len(), MAX_PERMISSION_PROMPT_LENGTH); @@ -241,13 +242,13 @@ impl PermissionPrompter for TtyPrompter { #[cfg(unix)] let metadata_before = get_stdin_metadata().unwrap(); - + // Lock stdio streams, so no other output is written while the prompt is // displayed. let stdout_lock = std::io::stdout().lock(); let mut stderr_lock = std::io::stderr().lock(); let mut stdin_lock = std::io::stdin().lock(); - + // For security reasons we must consume everything in stdin so that previously // buffered data cannot affect the prompt. #[allow(clippy::print_stderr)] @@ -266,7 +267,7 @@ impl PermissionPrompter for TtyPrompter { } else { "[y/n] (y = yes, allow; n = no, deny)".to_string() }; - + // output everything in one shot to make the tests more reliable { let mut output = String::new(); @@ -295,8 +296,9 @@ impl PermissionPrompter for TtyPrompter { writeln!(&mut output, "┠─ {}", colors::italic(&msg)).unwrap(); write!(&mut output, "┗ {}", colors::bold("Allow?")).unwrap(); write!(&mut output, " {opts} > ").unwrap(); - + stderr_lock.write_all(output.as_bytes()).unwrap(); + stderr_lock.flush().unwrap(); } let value = loop { diff --git a/crates/wasi-common/src/ctx.rs b/crates/wasi-common/src/ctx.rs index 151f312..2ca5a9c 100644 --- a/crates/wasi-common/src/ctx.rs +++ b/crates/wasi-common/src/ctx.rs @@ -29,7 +29,7 @@ pub struct WasiCtxInner { pub clocks: WasiClocks, pub sched: Box, pub table: Table, - pub permissions_container: BlsRuntimePermissionsContainer, + pub perms_container: BlsRuntimePermissionsContainer, pub blockless_config: Mutex>, } @@ -46,7 +46,7 @@ impl WasiCtx { env: StringArray::new(), random: Mutex::new(random), blockless_config: Mutex::new(None), - permissions_container: BlsRuntimePermissionsContainer::new_with_env_cwd(cwd), + perms_container: BlsRuntimePermissionsContainer::new_with_env_cwd(cwd), clocks, sched, table, diff --git a/crates/wasi-common/src/snapshots/preview_1.rs b/crates/wasi-common/src/snapshots/preview_1.rs index 74295b8..8ceae4e 100644 --- a/crates/wasi-common/src/snapshots/preview_1.rs +++ b/crates/wasi-common/src/snapshots/preview_1.rs @@ -11,7 +11,7 @@ use crate::{ I32Exit, SystemTimeSpec, WasiCtx, }; use cap_std::time::{Duration, SystemClock}; -use std::borrow::Cow; +use std::{borrow::Cow, path::PathBuf}; use std::io::{IoSlice, IoSliceMut}; use std::ops::Deref; use std::sync::Arc; @@ -684,6 +684,7 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx { dirfd: types::Fd, path: GuestPtr, ) -> Result<(), Error> { + println!("{dirfd}"); self.table() .get_dir(u32::from(dirfd))? .dir @@ -778,6 +779,7 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx { _fs_rights_inheriting: types::Rights, fdflags: types::Fdflags, ) -> Result { + let table = self.table(); let dirfd = u32::from(dirfd); if table.is::(dirfd) { @@ -790,7 +792,10 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx { let oflags = OFlags::from(&oflags); let fdflags = FdFlags::from(fdflags); let path = memory.as_cow_str(path)?; - + let path_buf: PathBuf = PathBuf::from(path.as_ref()); + self.perms_container + .check_read_path(&path_buf, Some("path open")) + .map_err(|_| Error::perm())?; let read = fs_rights_base.contains(types::Rights::FD_READ); let write = fs_rights_base.contains(types::Rights::FD_WRITE); let access_mode = if read { @@ -802,7 +807,6 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx { } else { FileAccessMode::empty() }; - let file = dir_entry .dir .open_file(symlink_follow, path.deref(), oflags, read, write, fdflags)