From f512387c371648d0aa8d6a9140e0c7f58e24df43 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 16 Dec 2019 06:52:01 -0800 Subject: [PATCH] Port the changes to the snapshot_0 directory. --- .../wasi-common/src/old/snapshot_0/fdentry.rs | 8 +++++ .../src/old/snapshot_0/hostcalls_impl/fs.rs | 32 ++++++++++++++----- crates/wasi-common/src/old/snapshot_0/mod.rs | 1 + 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/crates/wasi-common/src/old/snapshot_0/fdentry.rs b/crates/wasi-common/src/old/snapshot_0/fdentry.rs index d6b69eed47f..44cc4ce4032 100644 --- a/crates/wasi-common/src/old/snapshot_0/fdentry.rs +++ b/crates/wasi-common/src/old/snapshot_0/fdentry.rs @@ -162,6 +162,14 @@ impl FdEntry { Ok(()) } } + + /// Test whether this descriptor is considered a tty within WASI. + /// Note that since WASI itself lacks an `isatty` syscall and relies + /// on a conservative approximation, we use the same approximation here. + pub(crate) fn isatty(&self) -> bool { + self.file_type == wasi::__WASI_FILETYPE_CHARACTER_DEVICE + && (self.rights_base & (wasi::__WASI_RIGHTS_FD_SEEK | wasi::__WASI_RIGHTS_FD_TELL)) == 0 + } } /// This allows an `OsHandle` to be temporarily borrowed from a diff --git a/crates/wasi-common/src/old/snapshot_0/hostcalls_impl/fs.rs b/crates/wasi-common/src/old/snapshot_0/hostcalls_impl/fs.rs index da51e01f2eb..1d373c6a96d 100644 --- a/crates/wasi-common/src/old/snapshot_0/hostcalls_impl/fs.rs +++ b/crates/wasi-common/src/old/snapshot_0/hostcalls_impl/fs.rs @@ -4,6 +4,7 @@ use crate::old::snapshot_0::ctx::WasiCtx; use crate::old::snapshot_0::fdentry::{Descriptor, FdEntry}; use crate::old::snapshot_0::helpers::*; use crate::old::snapshot_0::memory::*; +use crate::old::snapshot_0::sandboxed_tty_writer::SandboxedTTYWriter; use crate::old::snapshot_0::sys::fdentry_impl::determine_type_rights; use crate::old::snapshot_0::sys::hostcalls_impl::fs_helpers::path_open_rights; use crate::old::snapshot_0::sys::{host_impl, hostcalls_impl}; @@ -12,6 +13,7 @@ use filetime::{set_file_handle_times, FileTime}; use log::trace; use std::fs::File; use std::io::{self, Read, Seek, SeekFrom, Write}; +use std::ops::DerefMut; use std::time::{Duration, SystemTime, UNIX_EPOCH}; pub(crate) unsafe fn fd_close(wasi_ctx: &mut WasiCtx, fd: wasi::__wasi_fd_t) -> Result<()> { @@ -160,7 +162,7 @@ pub(crate) unsafe fn fd_read( .as_descriptor_mut(wasi::__WASI_RIGHTS_FD_READ, 0)? { Descriptor::OsHandle(file) => file.read_vectored(&mut iovs), - Descriptor::Stdin => io::stdin().lock().read_vectored(&mut iovs), + Descriptor::Stdin => io::stdin().read_vectored(&mut iovs), _ => return Err(Error::EBADF), }; @@ -357,21 +359,35 @@ pub(crate) unsafe fn fd_write( let iovs: Vec = iovs.iter().map(|vec| host::ciovec_to_host(vec)).collect(); // perform unbuffered writes - let host_nwritten = match wasi_ctx - .get_fd_entry_mut(fd)? - .as_descriptor_mut(wasi::__WASI_RIGHTS_FD_WRITE, 0)? - { - Descriptor::OsHandle(file) => file.write_vectored(&iovs)?, + let entry = wasi_ctx.get_fd_entry_mut(fd)?; + let isatty = entry.isatty(); + let desc = entry.as_descriptor_mut(wasi::__WASI_RIGHTS_FD_WRITE, 0)?; + let host_nwritten = match desc { + Descriptor::OsHandle(file) => { + if isatty { + SandboxedTTYWriter::new(file.deref_mut()).write_vectored(&iovs)? + } else { + file.write_vectored(&iovs)? + } + } Descriptor::Stdin => return Err(Error::EBADF), Descriptor::Stdout => { // lock for the duration of the scope let stdout = io::stdout(); let mut stdout = stdout.lock(); - let nwritten = stdout.write_vectored(&iovs)?; + let nwritten = if isatty { + SandboxedTTYWriter::new(&mut stdout).write_vectored(&iovs)? + } else { + stdout.write_vectored(&iovs)? + }; stdout.flush()?; nwritten } - Descriptor::Stderr => io::stderr().lock().write_vectored(&iovs)?, + // Always sanitize stderr, even if it's not directly connected to a tty, + // because stderr is meant for diagnostics rather than binary output, + // and may be redirected to a file which could end up being displayed + // on a tty later. + Descriptor::Stderr => SandboxedTTYWriter::new(&mut io::stderr()).write_vectored(&iovs)?, }; trace!(" | *nwritten={:?}", host_nwritten); diff --git a/crates/wasi-common/src/old/snapshot_0/mod.rs b/crates/wasi-common/src/old/snapshot_0/mod.rs index 5d4e7f01b0f..3644ca05d50 100644 --- a/crates/wasi-common/src/old/snapshot_0/mod.rs +++ b/crates/wasi-common/src/old/snapshot_0/mod.rs @@ -5,6 +5,7 @@ mod helpers; mod host; pub mod hostcalls; mod hostcalls_impl; +mod sandboxed_tty_writer; mod memory; mod sys; pub mod wasi;