From 9b3477f602835f6060dd50d7d0589280db0bdbe6 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 26 Aug 2022 11:39:51 -0700 Subject: [PATCH] Implement the remaining socket-related WASI functions. (#4776) * Implement the remaining socket-related WASI functions. The original WASI specification included `sock_read`, `sock_write`, and `shutdown`. Now that we have some sockets support, implement these additional functions, to make it easier for people porting existing code to WASI. It's expected that this will all be subsumed by the wasi-sockets proposal, but for now, this is a relatively small change which should hopefully unblock people trying to use the current `accept` support. * Update to system-interface 0.22, which has fixes for Windows. --- Cargo.lock | 4 +- crates/wasi-common/README.md | 9 +--- crates/wasi-common/cap-std-sync/Cargo.toml | 2 +- crates/wasi-common/cap-std-sync/src/file.rs | 2 +- crates/wasi-common/cap-std-sync/src/net.rs | 60 +++++++++++++++++++-- supply-chain/audits.toml | 5 ++ supply-chain/config.toml | 4 -- 7 files changed, 67 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index adbbd6547e..bf4830f6eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2782,9 +2782,9 @@ dependencies = [ [[package]] name = "system-interface" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e3e98c4cf2f43a7e3b3a943b63fd192559b8a98ddcbef260580f29f0f4b9d1b" +checksum = "fa85f9e64bd72b222ced152d2694fd306c0ebe43670cb9d187701874b7b89008" dependencies = [ "atty", "bitflags", diff --git a/crates/wasi-common/README.md b/crates/wasi-common/README.md index 7282e54f9b..c406f38132 100644 --- a/crates/wasi-common/README.md +++ b/crates/wasi-common/README.md @@ -32,14 +32,7 @@ Please note that the library requires Rust compiler version at least 1.37.0. ### *nix In our *nix implementation, we currently support the entire [WASI API] -with the exception of socket hostcalls: -- `sock_recv` -- `sock_send` -- `sock_shutdown` - -We expect these to be implemented when network access is standardised. - -We also currently do not support the `proc_raise` hostcall, as it is expected to +with the exception of the `proc_raise` hostcall, as it is expected to be dropped entirely from WASI. [WASI API]: https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/docs.md diff --git a/crates/wasi-common/cap-std-sync/Cargo.toml b/crates/wasi-common/cap-std-sync/Cargo.toml index 261f3be448..57a625b95d 100644 --- a/crates/wasi-common/cap-std-sync/Cargo.toml +++ b/crates/wasi-common/cap-std-sync/Cargo.toml @@ -20,7 +20,7 @@ cap-fs-ext = "0.25.0" cap-time-ext = "0.25.0" cap-rand = "0.25.0" fs-set-times = "0.17.0" -system-interface = { version = "0.21.0", features = ["cap_std_impls"] } +system-interface = { version = "0.22.0", features = ["cap_std_impls"] } tracing = "0.1.19" io-lifetimes = { version = "0.7.0", default-features = false } is-terminal = "0.3.0" diff --git a/crates/wasi-common/cap-std-sync/src/file.rs b/crates/wasi-common/cap-std-sync/src/file.rs index af710cd7ae..8fe395fdaf 100644 --- a/crates/wasi-common/cap-std-sync/src/file.rs +++ b/crates/wasi-common/cap-std-sync/src/file.rs @@ -7,7 +7,7 @@ use std::convert::TryInto; use std::io; use system_interface::{ fs::{FileIoExt, GetSetFdFlags}, - io::ReadReady, + io::{IoExt, ReadReady}, }; use wasi_common::{ file::{Advice, FdFlags, FileType, Filestat, WasiFile}, diff --git a/crates/wasi-common/cap-std-sync/src/net.rs b/crates/wasi-common/cap-std-sync/src/net.rs index 223cb894fe..bdbf507fe4 100644 --- a/crates/wasi-common/cap-std-sync/src/net.rs +++ b/crates/wasi-common/cap-std-sync/src/net.rs @@ -9,13 +9,12 @@ use std::any::Any; use std::convert::TryInto; use std::io; #[cfg(unix)] -use system_interface::fs::FileIoExt; -#[cfg(unix)] use system_interface::fs::GetSetFdFlags; +use system_interface::io::IoExt; use system_interface::io::IsReadWrite; use system_interface::io::ReadReady; use wasi_common::{ - file::{FdFlags, FileType, WasiFile}, + file::{FdFlags, FileType, RiFlags, RoFlags, SdFlags, SiFlags, WasiFile}, Error, ErrorExt, }; @@ -243,6 +242,61 @@ macro_rules! wasi_stream_write_impl { Err(Error::io()) } } + + async fn sock_recv<'a>( + &mut self, + ri_data: &mut [std::io::IoSliceMut<'a>], + ri_flags: RiFlags, + ) -> Result<(u64, RoFlags), Error> { + if (ri_flags & !(RiFlags::RECV_PEEK | RiFlags::RECV_WAITALL)) != RiFlags::empty() { + return Err(Error::not_supported()); + } + + if ri_flags.contains(RiFlags::RECV_PEEK) { + if let Some(first) = ri_data.iter_mut().next() { + let n = self.0.peek(first)?; + return Ok((n as u64, RoFlags::empty())); + } else { + return Ok((0, RoFlags::empty())); + } + } + + if ri_flags.contains(RiFlags::RECV_WAITALL) { + let n: usize = ri_data.iter().map(|buf| buf.len()).sum(); + self.0.read_exact_vectored(ri_data)?; + return Ok((n as u64, RoFlags::empty())); + } + + let n = self.0.read_vectored(ri_data)?; + Ok((n as u64, RoFlags::empty())) + } + + async fn sock_send<'a>( + &mut self, + si_data: &[std::io::IoSlice<'a>], + si_flags: SiFlags, + ) -> Result { + if si_flags != SiFlags::empty() { + return Err(Error::not_supported()); + } + + let n = self.0.write_vectored(si_data)?; + Ok(n as u64) + } + + async fn sock_shutdown(&mut self, how: SdFlags) -> Result<(), Error> { + let how = if how == SdFlags::RD | SdFlags::WR { + cap_std::net::Shutdown::Both + } else if how == SdFlags::RD { + cap_std::net::Shutdown::Read + } else if how == SdFlags::WR { + cap_std::net::Shutdown::Write + } else { + return Err(Error::invalid_argument()); + }; + self.0.shutdown(how)?; + Ok(()) + } } #[cfg(unix)] impl AsFd for $ty { diff --git a/supply-chain/audits.toml b/supply-chain/audits.toml index 29fc774cad..7612204fcf 100644 --- a/supply-chain/audits.toml +++ b/supply-chain/audits.toml @@ -194,3 +194,8 @@ criteria = "safe-to-deploy" version = "1.0.48" notes = "The Bytecode Alliance is the author of this crate." +[[audits.system-interface]] +who = "Dan Gohman " +criteria = "safe-to-deploy" +version = "0.22.0" +notes = "The Bytecode Alliance is the author of this crate." diff --git a/supply-chain/config.toml b/supply-chain/config.toml index e8e3985ae8..462ef24f2c 100644 --- a/supply-chain/config.toml +++ b/supply-chain/config.toml @@ -1011,10 +1011,6 @@ criteria = "safe-to-deploy" version = "0.12.6" criteria = "safe-to-deploy" -[[exemptions.system-interface]] -version = "0.21.0" -criteria = "safe-to-deploy" - [[exemptions.target-lexicon]] version = "0.12.3" criteria = "safe-to-deploy"