From b578adced16fe8bfd8d6629748a34d4c52dc929b Mon Sep 17 00:00:00 2001 From: Raoul Strackx Date: Mon, 6 Nov 2023 12:43:56 +0100 Subject: [PATCH 1/2] Add support for the `x86_64-fortanix-unknown-sgx` target --- Cargo.toml | 8 ++ benches/Cargo.toml | 7 +- enclave-runner/Cargo.toml | 10 +++ enclave-runner/src/main.rs | 51 +++++++++++ examples/Cargo.toml | 6 ++ stress-test/Cargo.toml | 5 ++ stress-test/examples/simple_echo_tcp.rs | 6 +- tokio-macros/Cargo.toml | 5 ++ tokio-macros/src/lib.rs | 4 + tokio-stream/Cargo.toml | 10 ++- tokio-test/Cargo.toml | 7 +- tokio-util/Cargo.toml | 7 +- tokio-util/tests/compat.rs | 2 +- tokio-util/tests/time_delay_queue.rs | 2 +- tokio/Cargo.toml | 25 +++++- tokio/src/io/poll_evented.rs | 1 + tokio/src/lib.rs | 1 + tokio/src/net/addr.rs | 113 +++++++++++++++++++++++- tokio/src/net/mod.rs | 4 + tokio/src/net/tcp/listener.rs | 19 +++- tokio/src/net/tcp/mod.rs | 1 + tokio/src/net/tcp/stream.rs | 20 ++++- tokio/src/net/udp.rs | 4 + tokio/src/runtime/blocking/pool.rs | 1 + tokio/src/runtime/context.rs | 7 ++ tokio/src/runtime/io/registration.rs | 2 +- tokio/src/task/local.rs | 8 ++ tokio/tests/_require_full.rs | 2 +- tokio/tests/async_send_sync.rs | 8 +- tokio/tests/buffered.rs | 2 +- tokio/tests/io_async_read.rs | 2 +- tokio/tests/io_chain.rs | 2 +- tokio/tests/io_copy.rs | 2 +- tokio/tests/io_driver.rs | 2 +- tokio/tests/io_driver_drop.rs | 2 +- tokio/tests/io_lines.rs | 2 +- tokio/tests/io_read.rs | 2 +- tokio/tests/io_read_exact.rs | 2 +- tokio/tests/io_read_line.rs | 2 +- tokio/tests/io_read_to_end.rs | 2 +- tokio/tests/io_read_to_string.rs | 2 +- tokio/tests/io_read_until.rs | 2 +- tokio/tests/io_split.rs | 2 +- tokio/tests/io_take.rs | 2 +- tokio/tests/io_write.rs | 2 +- tokio/tests/io_write_all.rs | 2 +- tokio/tests/io_write_int.rs | 2 +- tokio/tests/net_bind_resource.rs | 2 +- tokio/tests/rt_basic.rs | 2 +- tokio/tests/rt_common.rs | 4 +- tokio/tests/rt_threaded.rs | 3 +- tokio/tests/sync_barrier.rs | 2 +- tokio/tests/sync_errors.rs | 2 +- tokio/tests/sync_mpsc.rs | 2 +- tokio/tests/sync_mutex.rs | 2 +- tokio/tests/sync_mutex_owned.rs | 2 +- tokio/tests/sync_notify.rs | 2 +- tokio/tests/sync_oneshot.rs | 2 +- tokio/tests/sync_semaphore.rs | 2 +- tokio/tests/sync_semaphore_owned.rs | 2 +- tokio/tests/sync_watch.rs | 2 +- tokio/tests/task_blocking.rs | 2 +- tokio/tests/task_local_set.rs | 2 +- tokio/tests/tcp_accept.rs | 2 +- tokio/tests/tcp_connect.rs | 2 +- tokio/tests/tcp_echo.rs | 2 +- tokio/tests/tcp_into_split.rs | 4 +- tokio/tests/tcp_split.rs | 3 +- tokio/tests/test_clock.rs | 2 +- tokio/tests/time_interval.rs | 2 +- tokio/tests/time_rt.rs | 2 +- tokio/tests/time_sleep.rs | 2 +- tokio/tests/time_timeout.rs | 2 +- 73 files changed, 373 insertions(+), 67 deletions(-) create mode 100644 enclave-runner/Cargo.toml create mode 100644 enclave-runner/src/main.rs diff --git a/Cargo.toml b/Cargo.toml index d8ac248189d..8c399ca898f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [workspace] resolver = "2" members = [ + "enclave-runner", "tokio", "tokio-macros", "tokio-test", @@ -18,3 +19,10 @@ members = [ [workspace.metadata.spellcheck] config = "spellcheck.toml" +[patch.crates-io] +async-usercalls = { git = "https://github.com/fortanix/rust-sgx.git", branch = "master" } +enclave-runner = { git = "https://github.com/fortanix/rust-sgx", branch = "master" } +mio = { git = "https://github.com/fortanix/mio", branch = "v0.8.10" } +sgx-isa = { git = "https://github.com/fortanix/rust-sgx", branch = "master" } +sgxs = { git = "https://github.com/fortanix/rust-sgx", branch = "master" } +tokio = { path = "./tokio" } diff --git a/benches/Cargo.toml b/benches/Cargo.toml index c581055cf65..f6416c1f3a9 100644 --- a/benches/Cargo.toml +++ b/benches/Cargo.toml @@ -8,12 +8,17 @@ edition = "2021" test-util = ["tokio/test-util"] [dependencies] -tokio = { version = "1.5.0", path = "../tokio", features = ["full"] } criterion = "0.5.1" rand = "0.8" rand_chacha = "0.3" num_cpus = "1.16.0" +[target.'cfg(target_env = "sgx")'.dependencies] +tokio = { version = "1.5.0", path = "../tokio", features = ["full-sgx"] } + +[target.'cfg(not(target_env = "sgx"))'.dependencies] +tokio = { version = "1.5.0", path = "../tokio", features = ["full"] } + [dev-dependencies] tokio-util = { version = "0.7.0", path = "../tokio-util", features = ["full"] } tokio-stream = { path = "../tokio-stream" } diff --git a/enclave-runner/Cargo.toml b/enclave-runner/Cargo.toml new file mode 100644 index 00000000000..03a8e415099 --- /dev/null +++ b/enclave-runner/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "enclave-runner" +version = "0.1.0" +edition = "2018" + +[dependencies] +aesm-client = { version = "0.5", features = ["sgxs"] } +clap = "4.4" +enclave-runner = "0.5" +sgxs-loaders = "0.3.0" diff --git a/enclave-runner/src/main.rs b/enclave-runner/src/main.rs new file mode 100644 index 00000000000..788c3347408 --- /dev/null +++ b/enclave-runner/src/main.rs @@ -0,0 +1,51 @@ +use aesm_client::AesmClient; +use clap::{Command, Arg, ArgAction}; +use enclave_runner::EnclaveBuilder; + +#[cfg(windows)] +use sgxs_loaders::enclaveapi::Sgx as IsgxDevice; +#[cfg(unix)] +use sgxs_loaders::isgx::Device as IsgxDevice; + +fn main() { + let args = Command::new("runner") + .arg(Arg::new("file").required(true)) + .arg( + Arg::new("enclave-args") + .help( + "Arguments passed to the enclave. \ + Note that this is not an appropriate channel for passing \ + secrets or security configurations to the enclave.", + ) + .action(ArgAction::Append) + ) + .get_matches(); + + let file = args.get_one::("file").unwrap(); + + let mut device = IsgxDevice::new() + .expect("failed to open SGX device") + .einittoken_provider(AesmClient::new()) + .build(); + + let mut enclave_builder = EnclaveBuilder::new(file.as_ref()); + if let Err(_) = enclave_builder.coresident_signature() { + enclave_builder.dummy_signature(); + } + + if let Some(enclave_args) = args.get_many::("enclave-args") { + enclave_builder.args(enclave_args); + } + + let enclave = enclave_builder + .build(&mut device) + .expect("failed to load SGX enclave"); + + match enclave.run() { + Err(e) => { + eprintln!("Error while executing SGX enclave.\n{}", e); + std::process::exit(-1) + } + Ok(()) => {} + } +} diff --git a/examples/Cargo.toml b/examples/Cargo.toml index a244fccaca1..2d5dd55b242 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -27,6 +27,12 @@ rand = "0.8.3" [target.'cfg(windows)'.dev-dependencies.windows-sys] version = "0.48" +[target.'cfg(not(target_env = "sgx"))'.dev-dependencies] +tokio = { version = "1.0.0", path = "../tokio",features = ["full", "tracing"] } + +[target.'cfg(target_env = "sgx")'.dev-dependencies] +tokio = { version = "1.0.0", path = "../tokio",features = ["full-sgx", "tracing"] } + [[example]] name = "chat" path = "chat.rs" diff --git a/stress-test/Cargo.toml b/stress-test/Cargo.toml index ee7431f096b..2c6529b74df 100644 --- a/stress-test/Cargo.toml +++ b/stress-test/Cargo.toml @@ -8,7 +8,12 @@ publish = false # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] + +[target.'cfg(not(target_env = "sgx"))'.dependencies] tokio = { path = "../tokio/", features = ["full"] } +[target.'cfg(target_env = "sgx")'.dependencies] +tokio = { path = "../tokio/", features = ["full-sgx"] } + [dev-dependencies] rand = "0.8" diff --git a/stress-test/examples/simple_echo_tcp.rs b/stress-test/examples/simple_echo_tcp.rs index 01e545026c5..11df2abbd1e 100644 --- a/stress-test/examples/simple_echo_tcp.rs +++ b/stress-test/examples/simple_echo_tcp.rs @@ -3,7 +3,7 @@ use std::{thread::sleep, time::Duration}; use tokio::{ io::{AsyncReadExt, AsyncWriteExt}, - net::{TcpListener, TcpSocket}, + net::{TcpListener, TcpStream}, runtime::Builder, sync::oneshot, }; @@ -30,9 +30,7 @@ fn main() { let (tx, mut rx) = oneshot::channel(); rt2.spawn(async { - let addr = TCP_ENDPOINT.parse().unwrap(); - let socket = TcpSocket::new_v4().unwrap(); - let mut stream = socket.connect(addr).await.unwrap(); + let mut stream = TcpStream::connect(TCP_ENDPOINT).await.unwrap(); let mut buff = [0; MSG_SIZE]; for _ in 0..NUM_MSGS { diff --git a/tokio-macros/Cargo.toml b/tokio-macros/Cargo.toml index ea9839c6d06..5522709aed3 100644 --- a/tokio-macros/Cargo.toml +++ b/tokio-macros/Cargo.toml @@ -27,7 +27,12 @@ quote = "1" syn = { version = "2.0", features = ["full"] } [dev-dependencies] + +[target.'cfg(not(target_env = "sgx"))'.dev-dependencies] tokio = { version = "1.0.0", path = "../tokio", features = ["full"] } +[target.'cfg(target_env = "sgx")'.dev-dependencies] +tokio = { version = "1.0.0", path = "../tokio", features = ["full-sgx"] } + [package.metadata.docs.rs] all-features = true diff --git a/tokio-macros/src/lib.rs b/tokio-macros/src/lib.rs index 919c4ac0ba9..47f9e7fc2f9 100644 --- a/tokio-macros/src/lib.rs +++ b/tokio-macros/src/lib.rs @@ -152,6 +152,9 @@ use proc_macro::TokenStream; /// ### Configure the runtime to start with time paused /// /// ```rust +/// # #[cfg(not(feature = "test-util"))] +/// # fn main(){} +/// # #[cfg(feature = "test-util")] /// #[tokio::main(flavor = "current_thread", start_paused = true)] /// async fn main() { /// println!("Hello world"); @@ -162,6 +165,7 @@ use proc_macro::TokenStream; /// /// ```rust /// fn main() { +/// # #[cfg(feature = "test-util")] /// tokio::runtime::Builder::new_current_thread() /// .enable_all() /// .start_paused(true) diff --git a/tokio-stream/Cargo.toml b/tokio-stream/Cargo.toml index b71119eda2e..d54df59a19b 100644 --- a/tokio-stream/Cargo.toml +++ b/tokio-stream/Cargo.toml @@ -42,12 +42,17 @@ tokio = { version = "1.15.0", path = "../tokio", features = ["sync"] } tokio-util = { version = "0.7.0", path = "../tokio-util", optional = true } [dev-dependencies] -tokio = { version = "1.2.0", path = "../tokio", features = ["full", "test-util"] } async-stream = "0.3" parking_lot = "0.12.0" tokio-test = { path = "../tokio-test" } futures = { version = "0.3", default-features = false } +[target.'cfg(not(target_env = "sgx"))'.dev-dependencies] +tokio = { version = "1.2.0", path = "../tokio", features = ["full", "test-util"] } + +[target.'cfg(target_env = "sgx")'.dev-dependencies] +tokio = { version = "1.2.0", path = "../tokio", features = ["full-sgx", "test-util"] } + [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] @@ -56,3 +61,6 @@ rustdoc-args = ["--cfg", "docsrs"] # This should allow `docsrs` to be read across projects, so that `tokio-stream` # can pick up stubbed types exported by `tokio`. rustc-args = ["--cfg", "docsrs"] + +[package.metadata.fortanix-sgx] +runner = "enclave-runner" diff --git a/tokio-test/Cargo.toml b/tokio-test/Cargo.toml index 29a35054679..163b5f93793 100644 --- a/tokio-test/Cargo.toml +++ b/tokio-test/Cargo.toml @@ -25,8 +25,13 @@ bytes = "1.0.0" futures-core = "0.3.0" [dev-dependencies] -tokio = { version = "1.2.0", path = "../tokio", features = ["full"] } futures-util = "0.3.0" +[target.'cfg(not(target_env = "sgx"))'.dev-dependencies] +tokio = { version = "1.2.0", path = "../tokio", features = ["full"] } + +[target.'cfg(target_env = "sgx")'.dev-dependencies] +tokio = { version = "1.2.0", path = "../tokio", features = ["full-sgx"] } + [package.metadata.docs.rs] all-features = true diff --git a/tokio-util/Cargo.toml b/tokio-util/Cargo.toml index 12c3c813656..96196c712ce 100644 --- a/tokio-util/Cargo.toml +++ b/tokio-util/Cargo.toml @@ -48,7 +48,6 @@ tracing = { version = "0.1.25", default-features = false, features = ["std"], op hashbrown = { version = "0.14.0", optional = true } [dev-dependencies] -tokio = { version = "1.0.0", path = "../tokio", features = ["full"] } tokio-test = { version = "0.4.0", path = "../tokio-test" } tokio-stream = { version = "0.1", path = "../tokio-stream" } @@ -58,6 +57,12 @@ futures-test = "0.3.5" parking_lot = "0.12.0" tempfile = "3.1.0" +[target.'cfg(not(target_env = "sgx"))'.dev-dependencies] +tokio = { version = "1.0.0", path = "../tokio", features = ["full"] } + +[target.'cfg(target_env = "sgx")'.dev-dependencies] +tokio = { version = "1.0.0", path = "../tokio", features = ["full-sgx"] } + [package.metadata.docs.rs] all-features = true # enable unstable features in the documentation diff --git a/tokio-util/tests/compat.rs b/tokio-util/tests/compat.rs index 8a0eab3407d..af90f2674c1 100644 --- a/tokio-util/tests/compat.rs +++ b/tokio-util/tests/compat.rs @@ -1,5 +1,5 @@ #![cfg(feature = "compat")] -#![cfg(not(target_os = "wasi"))] // WASI does not support all fs operations +#![cfg(not(any(target_os = "wasi", target_env = "sgx")))] // WASI and SGX do not support all fs operations #![warn(rust_2018_idioms)] use futures_io::SeekFrom; diff --git a/tokio-util/tests/time_delay_queue.rs b/tokio-util/tests/time_delay_queue.rs index 6616327d41c..f5df2ef1d04 100644 --- a/tokio-util/tests/time_delay_queue.rs +++ b/tokio-util/tests/time_delay_queue.rs @@ -1,6 +1,6 @@ #![allow(clippy::disallowed_names)] #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any(feature = "full", feature = "full-sgx"))] use futures::StreamExt; use tokio::time::{self, sleep, sleep_until, Duration, Instant}; diff --git a/tokio/Cargo.toml b/tokio/Cargo.toml index 194494dabf7..6f1e51f2e7c 100644 --- a/tokio/Cargo.toml +++ b/tokio/Cargo.toml @@ -41,6 +41,18 @@ full = [ "time", ] +# everything possible in SGX +full-sgx = [ + "io-util", + "io-std", + "macros", + "net", + "rt", + "rt-multi-thread", + "sync", + "time", +] + fs = [] io-util = ["bytes"] # stdin, stdout, stderr @@ -95,11 +107,11 @@ pin-project-lite = "0.2.11" # Everything else is optional... bytes = { version = "1.0.0", optional = true } -mio = { version = "0.8.9", optional = true, default-features = false } +mio = { version = "0.8.10", optional = true, default-features = false } num_cpus = { version = "1.8.0", optional = true } parking_lot = { version = "0.12.0", optional = true } -[target.'cfg(not(target_family = "wasm"))'.dependencies] +[target.'cfg(not(any(target_family = "wasm", target_env = "sgx")))'.dependencies] socket2 = { version = "0.5.5", optional = true, features = [ "all" ] } # Currently unstable. The API exposed by these features may be broken at any time. @@ -138,7 +150,7 @@ futures = { version = "0.3.0", features = ["async-await"] } mockall = "0.11.1" async-stream = "0.3" -[target.'cfg(not(target_family = "wasm"))'.dev-dependencies] +[target.'cfg(not(any(target_family = "wasm", target_env = "sgx")))'.dev-dependencies] socket2 = "0.5.5" tempfile = "3.1.0" @@ -174,3 +186,10 @@ allowed_external_types = [ "tokio_macros::*", ] + +# set number of threads so tests can run properly +[package.metadata.fortanix-sgx] +threads = 100 +heap-size = 0x4000000 +stack-size = 0x40000 +runner = "enclave-runner" diff --git a/tokio/src/io/poll_evented.rs b/tokio/src/io/poll_evented.rs index 3952a31e783..dd1628270c3 100644 --- a/tokio/src/io/poll_evented.rs +++ b/tokio/src/io/poll_evented.rs @@ -131,6 +131,7 @@ impl PollEvented { /// Deregisters the inner io from the registration and returns a Result containing the inner io. #[cfg(any(feature = "net", feature = "process"))] + #[cfg(not(target_env = "sgx"))] pub(crate) fn into_inner(mut self) -> io::Result { let mut inner = self.io.take().unwrap(); // As io shouldn't ever be None, just unwrap here. self.registration.deregister(&mut inner)?; diff --git a/tokio/src/lib.rs b/tokio/src/lib.rs index 3f035098832..a2bf46d19a5 100644 --- a/tokio/src/lib.rs +++ b/tokio/src/lib.rs @@ -15,6 +15,7 @@ no_crate_inject, attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables)) ))] +#![cfg_attr(target_env = "sgx", feature(sgx_platform))] #![cfg_attr(docsrs, feature(doc_cfg))] #![cfg_attr(docsrs, allow(unused_attributes))] #![cfg_attr(loom, allow(dead_code, unreachable_pub))] diff --git a/tokio/src/net/addr.rs b/tokio/src/net/addr.rs index fb8248fb3ba..d6fcf3a4b5d 100644 --- a/tokio/src/net/addr.rs +++ b/tokio/src/net/addr.rs @@ -1,6 +1,8 @@ use std::future; use std::io; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; +#[cfg(target_env = "sgx")] +use std::iter; /// Converts or resolves without blocking to one or more `SocketAddr` values. /// @@ -39,10 +41,18 @@ where { type Iter = T::Iter; type Future = T::Future; + #[cfg(target_env = "sgx")] + type StringIter = T::StringIter; + fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future { (**self).to_socket_addrs(sealed::Internal) } + + #[cfg(target_env = "sgx")] + fn to_string_addrs(&self) -> Self::StringIter { + (**self).to_string_addrs() + } } // ===== impl SocketAddr ===== @@ -52,11 +62,18 @@ impl ToSocketAddrs for SocketAddr {} impl sealed::ToSocketAddrsPriv for SocketAddr { type Iter = std::option::IntoIter; type Future = ReadyFuture; + #[cfg(target_env = "sgx")] + type StringIter = iter::Once; fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future { let iter = Some(*self).into_iter(); future::ready(Ok(iter)) } + + #[cfg(target_env = "sgx")] + fn to_string_addrs(&self) -> Self::StringIter { + iter::once(self.to_string()) + } } // ===== impl SocketAddrV4 ===== @@ -66,10 +83,17 @@ impl ToSocketAddrs for SocketAddrV4 {} impl sealed::ToSocketAddrsPriv for SocketAddrV4 { type Iter = std::option::IntoIter; type Future = ReadyFuture; + #[cfg(target_env = "sgx")] + type StringIter = iter::Once; fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future { SocketAddr::V4(*self).to_socket_addrs(sealed::Internal) } + + #[cfg(target_env = "sgx")] + fn to_string_addrs(&self) -> Self::StringIter { + iter::once(self.to_string()) + } } // ===== impl SocketAddrV6 ===== @@ -79,10 +103,17 @@ impl ToSocketAddrs for SocketAddrV6 {} impl sealed::ToSocketAddrsPriv for SocketAddrV6 { type Iter = std::option::IntoIter; type Future = ReadyFuture; + #[cfg(target_env = "sgx")] + type StringIter = iter::Once; fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future { SocketAddr::V6(*self).to_socket_addrs(sealed::Internal) } + + #[cfg(target_env = "sgx")] + fn to_string_addrs(&self) -> Self::StringIter { + iter::once(self.to_string()) + } } // ===== impl (IpAddr, u16) ===== @@ -92,11 +123,18 @@ impl ToSocketAddrs for (IpAddr, u16) {} impl sealed::ToSocketAddrsPriv for (IpAddr, u16) { type Iter = std::option::IntoIter; type Future = ReadyFuture; + #[cfg(target_env = "sgx")] + type StringIter = iter::Once; fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future { let iter = Some(SocketAddr::from(*self)).into_iter(); future::ready(Ok(iter)) } + + #[cfg(target_env = "sgx")] + fn to_string_addrs(&self) -> Self::StringIter { + iter::once(SocketAddr::from(*self).to_string()) + } } // ===== impl (Ipv4Addr, u16) ===== @@ -106,11 +144,18 @@ impl ToSocketAddrs for (Ipv4Addr, u16) {} impl sealed::ToSocketAddrsPriv for (Ipv4Addr, u16) { type Iter = std::option::IntoIter; type Future = ReadyFuture; + #[cfg(target_env = "sgx")] + type StringIter = iter::Once; fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future { let (ip, port) = *self; SocketAddrV4::new(ip, port).to_socket_addrs(sealed::Internal) } + + #[cfg(target_env = "sgx")] + fn to_string_addrs(&self) -> Self::StringIter { + iter::once(SocketAddr::from(*self).to_string()) + } } // ===== impl (Ipv6Addr, u16) ===== @@ -120,20 +165,46 @@ impl ToSocketAddrs for (Ipv6Addr, u16) {} impl sealed::ToSocketAddrsPriv for (Ipv6Addr, u16) { type Iter = std::option::IntoIter; type Future = ReadyFuture; + #[cfg(target_env = "sgx")] + type StringIter = iter::Once; fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future { let (ip, port) = *self; SocketAddrV6::new(ip, port, 0, 0).to_socket_addrs(sealed::Internal) } + + #[cfg(target_env = "sgx")] + fn to_string_addrs(&self) -> Self::StringIter { + iter::once(SocketAddr::from(*self).to_string()) + } } // ===== impl &[SocketAddr] ===== +#[cfg(target_env = "sgx")] +#[derive(Debug)] +pub struct ToStringIter(I); + +#[cfg(target_env = "sgx")] +impl Iterator for ToStringIter +where + I: Iterator, + T: ToString, +{ + type Item = String; + + fn next(&mut self) -> Option { + self.0.next().map(|t| t.to_string()) + } +} + impl ToSocketAddrs for &[SocketAddr] {} -impl sealed::ToSocketAddrsPriv for &[SocketAddr] { +impl<'a> sealed::ToSocketAddrsPriv for &'a [SocketAddr] { type Iter = std::vec::IntoIter; type Future = ReadyFuture; + #[cfg(target_env = "sgx")] + type StringIter = ToStringIter>; fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future { #[inline] @@ -154,6 +225,11 @@ impl sealed::ToSocketAddrsPriv for &[SocketAddr] { let iter = slice_to_vec(self).into_iter(); future::ready(Ok(iter)) } + + #[cfg(target_env = "sgx")] + fn to_string_addrs(&self) -> Self::StringIter { + ToStringIter(self.iter()) + } } cfg_net! { @@ -164,6 +240,8 @@ cfg_net! { impl sealed::ToSocketAddrsPriv for str { type Iter = sealed::OneOrMore; type Future = sealed::MaybeReady; + #[cfg(target_env = "sgx")] + type StringIter = iter::Once; fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future { use crate::blocking::spawn_blocking; @@ -183,6 +261,11 @@ cfg_net! { std::net::ToSocketAddrs::to_socket_addrs(&s) }))) } + + #[cfg(target_env = "sgx")] + fn to_string_addrs(&self) -> Self::StringIter { + iter::once(self.to_owned()) + } } // ===== impl (&str, u16) ===== @@ -192,6 +275,8 @@ cfg_net! { impl sealed::ToSocketAddrsPriv for (&str, u16) { type Iter = sealed::OneOrMore; type Future = sealed::MaybeReady; + #[cfg(target_env = "sgx")] + type StringIter = iter::Once; fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future { use crate::blocking::spawn_blocking; @@ -220,6 +305,11 @@ cfg_net! { std::net::ToSocketAddrs::to_socket_addrs(&(&host[..], port)) }))) } + + #[cfg(target_env = "sgx")] + fn to_string_addrs(&self) -> Self::StringIter { + iter::once(format!("{}:{}", self.0, self.1)) + } } // ===== impl (String, u16) ===== @@ -229,10 +319,17 @@ cfg_net! { impl sealed::ToSocketAddrsPriv for (String, u16) { type Iter = sealed::OneOrMore; type Future = sealed::MaybeReady; + #[cfg(target_env = "sgx")] + type StringIter = iter::Once; fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future { (self.0.as_str(), self.1).to_socket_addrs(sealed::Internal) } + + #[cfg(target_env = "sgx")] + fn to_string_addrs(&self) -> Self::StringIter { + iter::once(format!("{}:{}", self.0, self.1)) + } } // ===== impl String ===== @@ -242,10 +339,17 @@ cfg_net! { impl sealed::ToSocketAddrsPriv for String { type Iter = ::Iter; type Future = ::Future; + #[cfg(target_env = "sgx")] + type StringIter = iter::Once; fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future { self[..].to_socket_addrs(sealed::Internal) } + + #[cfg(target_env = "sgx")] + fn to_string_addrs(&self) -> Self::StringIter { + iter::once(self.clone()) + } } } @@ -262,8 +366,15 @@ pub(crate) mod sealed { pub trait ToSocketAddrsPriv { type Iter: Iterator + Send + 'static; type Future: Future> + Send + 'static; + #[cfg(target_env = "sgx")] + type StringIter: Iterator; fn to_socket_addrs(&self, internal: Internal) -> Self::Future; + + // There is no name resolution mechanism in SGX, but bind and connect + // take arbitrary addresses represented as strings. + #[cfg(target_env = "sgx")] + fn to_string_addrs(&self) -> Self::StringIter; } #[allow(missing_debug_implementations)] diff --git a/tokio/src/net/mod.rs b/tokio/src/net/mod.rs index abc270bd0d8..aefbc481fdf 100644 --- a/tokio/src/net/mod.rs +++ b/tokio/src/net/mod.rs @@ -25,6 +25,7 @@ mod addr; cfg_not_wasi! { #[cfg(feature = "net")] + #[cfg(not(target_env = "sgx"))] pub(crate) use addr::to_socket_addrs; } pub use addr::ToSocketAddrs; @@ -37,9 +38,12 @@ cfg_net! { pub use tcp::listener::TcpListener; pub use tcp::stream::TcpStream; cfg_not_wasi! { + #[cfg(not(target_env = "sgx"))] pub use tcp::socket::TcpSocket; + #[cfg(not(target_env = "sgx"))] mod udp; + #[cfg(not(target_env = "sgx"))] pub use udp::UdpSocket; } } diff --git a/tokio/src/net/tcp/listener.rs b/tokio/src/net/tcp/listener.rs index 3f6592abe19..1a753f8f8ce 100644 --- a/tokio/src/net/tcp/listener.rs +++ b/tokio/src/net/tcp/listener.rs @@ -2,7 +2,9 @@ use crate::io::{Interest, PollEvented}; use crate::net::tcp::TcpStream; cfg_not_wasi! { - use crate::net::{to_socket_addrs, ToSocketAddrs}; + #[cfg(not(target_env = "sgx"))] + use crate::net::to_socket_addrs; + use crate::net::ToSocketAddrs; } use std::fmt; @@ -98,7 +100,10 @@ impl TcpListener { /// } /// ``` pub async fn bind(addr: A) -> io::Result { - let addrs = to_socket_addrs(addr).await?; + let addrs = { + #[cfg(not(target_env = "sgx"))] { to_socket_addrs(addr).await? } + #[cfg(target_env = "sgx")] { addr.to_string_addrs() } + }; let mut last_err = None; @@ -117,6 +122,13 @@ impl TcpListener { })) } + #[cfg(target_env = "sgx")] + fn bind_addr(addr: String) -> io::Result { + let listener = mio::net::TcpListener::bind_str(&addr)?; + TcpListener::new(listener) + } + + #[cfg(not(target_env = "sgx"))] fn bind_addr(addr: SocketAddr) -> io::Result { let listener = mio::net::TcpListener::bind(addr)?; TcpListener::new(listener) @@ -262,10 +274,13 @@ impl TcpListener { /// [`tokio::net::TcpListener`]: TcpListener /// [`std::net::TcpListener`]: std::net::TcpListener /// [`set_nonblocking`]: fn@std::net::TcpListener::set_nonblocking + #[cfg(not(target_env = "sgx"))] // `TcpListener::into_raw_fd()` not support by `mio` for SGX platform pub fn into_std(self) -> io::Result { #[cfg(unix)] { + #[cfg(unix)] use std::os::unix::io::{FromRawFd, IntoRawFd}; + self.io .into_inner() .map(IntoRawFd::into_raw_fd) diff --git a/tokio/src/net/tcp/mod.rs b/tokio/src/net/tcp/mod.rs index 734eabe6dda..7898e1a4a28 100644 --- a/tokio/src/net/tcp/mod.rs +++ b/tokio/src/net/tcp/mod.rs @@ -3,6 +3,7 @@ pub(crate) mod listener; cfg_not_wasi! { + #[cfg(not(target_env = "sgx"))] pub(crate) mod socket; } diff --git a/tokio/src/net/tcp/stream.rs b/tokio/src/net/tcp/stream.rs index e20473e5cc3..dc6e8ae0284 100644 --- a/tokio/src/net/tcp/stream.rs +++ b/tokio/src/net/tcp/stream.rs @@ -1,6 +1,9 @@ cfg_not_wasi! { use crate::future::poll_fn; - use crate::net::{to_socket_addrs, ToSocketAddrs}; + use crate::net::ToSocketAddrs; + #[cfg(not(target_env = "sgx"))] + use crate::net::to_socket_addrs; + #[cfg(not(target_env = "sgx"))] use std::time::Duration; } @@ -112,7 +115,10 @@ impl TcpStream { /// [`write_all`]: fn@crate::io::AsyncWriteExt::write_all /// [`AsyncWriteExt`]: trait@crate::io::AsyncWriteExt pub async fn connect(addr: A) -> io::Result { - let addrs = to_socket_addrs(addr).await?; + let addrs = { + #[cfg(not(target_env = "sgx"))] { to_socket_addrs(addr).await? } + #[cfg(target_env = "sgx")] { addr.to_string_addrs() } + }; let mut last_err = None; @@ -132,11 +138,19 @@ impl TcpStream { } /// Establishes a connection to the specified `addr`. + #[cfg(not(target_env = "sgx"))] async fn connect_addr(addr: SocketAddr) -> io::Result { let sys = mio::net::TcpStream::connect(addr)?; TcpStream::connect_mio(sys).await } + /// Establishes a connection to the specified `addr`. + #[cfg(target_env = "sgx")] + async fn connect_addr(addr: String) -> io::Result { + let sys = mio::net::TcpStream::connect_str(&addr)?; + TcpStream::connect_mio(sys).await + } + pub(crate) async fn connect_mio(sys: mio::net::TcpStream) -> io::Result { let stream = TcpStream::new(sys)?; @@ -243,6 +257,7 @@ impl TcpStream { /// [`tokio::net::TcpStream`]: TcpStream /// [`std::net::TcpStream`]: std::net::TcpStream /// [`set_nonblocking`]: fn@std::net::TcpStream::set_nonblocking + #[cfg(not(target_env = "sgx"))] // `TcpStream::into_raw_fd()` not support by `mio` for SGX platform pub fn into_std(self) -> io::Result { #[cfg(unix)] { @@ -1154,6 +1169,7 @@ impl TcpStream { self.io.set_nodelay(nodelay) } + #[cfg(not(target_env = "sgx"))] cfg_not_wasi! { /// Reads the linger duration for this socket by getting the `SO_LINGER` /// option. diff --git a/tokio/src/net/udp.rs b/tokio/src/net/udp.rs index 4e2c140a856..53610a74cb8 100644 --- a/tokio/src/net/udp.rs +++ b/tokio/src/net/udp.rs @@ -1978,8 +1978,12 @@ impl UdpSocket { /// #[tokio::main] /// async fn main() -> io::Result<()> { /// // Create a socket + /// #[cfg(target_env = "sgx")] + /// assert!(UdpSocket::bind("0.0.0.0:8080").await.is_err()); + /// #[cfg(not(target_env = "sgx"))] /// let socket = UdpSocket::bind("0.0.0.0:8080").await?; /// + /// #[cfg(not(target_env = "sgx"))] /// if let Ok(Some(err)) = socket.take_error() { /// println!("Got error: {:?}", err); /// } diff --git a/tokio/src/runtime/blocking/pool.rs b/tokio/src/runtime/blocking/pool.rs index c74aea76568..48a783e036a 100644 --- a/tokio/src/runtime/blocking/pool.rs +++ b/tokio/src/runtime/blocking/pool.rs @@ -131,6 +131,7 @@ pub(crate) enum Mandatory { NonMandatory, } +#[derive(Debug)] pub(crate) enum SpawnError { /// Pool is shutting down and the task was not scheduled ShuttingDown, diff --git a/tokio/src/runtime/context.rs b/tokio/src/runtime/context.rs index 62e4fc9474c..4bf83d6ba8d 100644 --- a/tokio/src/runtime/context.rs +++ b/tokio/src/runtime/context.rs @@ -138,6 +138,13 @@ pub(super) fn budget(f: impl FnOnce(&Cell) -> R) -> Result bool { + CONTEXT.try_with(|ctx| { + ctx.thread_id.get().is_some() + }).unwrap_or(false) + } + pub(crate) fn thread_id() -> Result { CONTEXT.try_with(|ctx| { match ctx.thread_id.get() { diff --git a/tokio/src/runtime/io/registration.rs b/tokio/src/runtime/io/registration.rs index dc5961086f7..222e6297e4e 100644 --- a/tokio/src/runtime/io/registration.rs +++ b/tokio/src/runtime/io/registration.rs @@ -118,7 +118,7 @@ impl Registration { // Uses the poll path, requiring the caller to ensure mutual exclusion for // correctness. Only the last task to call this function is notified. - #[cfg(not(target_os = "wasi"))] + #[cfg(not(any(target_os = "wasi", target_env = "sgx")))] pub(crate) fn poll_read_io( &self, cx: &mut Context<'_>, diff --git a/tokio/src/task/local.rs b/tokio/src/task/local.rs index a40708d08c2..92e09642bd3 100644 --- a/tokio/src/task/local.rs +++ b/tokio/src/task/local.rs @@ -1143,6 +1143,14 @@ impl LocalState { #[track_caller] fn assert_called_from_owner_thread(&self) { + // Even when the thread is being destroyed, local data may still be initialized on the SGX + // platform. So calling `context::thread_id()` will always return a thread id. In line with + // the `debug_assert` below, we ignore such cases on the SGX platform. + #[cfg(target_env = "sgx")] + if !context::has_thread_id() { + return; + } + // FreeBSD has some weirdness around thread-local destruction. // TODO: remove this hack when thread id is cleaned up #[cfg(not(any(target_os = "openbsd", target_os = "freebsd")))] diff --git a/tokio/tests/_require_full.rs b/tokio/tests/_require_full.rs index d33943a960d..9927e2ab369 100644 --- a/tokio/tests/_require_full.rs +++ b/tokio/tests/_require_full.rs @@ -1,4 +1,4 @@ -#[cfg(not(any(feature = "full", target_family = "wasm")))] +#[cfg(not(any(feature = "full", target_family = "wasm", feature = "full-sgx")))] compile_error!("run main Tokio tests with `--features full`"); // CI sets `--cfg tokio_no_parking_lot` when trying to run tests with diff --git a/tokio/tests/async_send_sync.rs b/tokio/tests/async_send_sync.rs index dfd26f9e9e7..7356fab917d 100644 --- a/tokio/tests/async_send_sync.rs +++ b/tokio/tests/async_send_sync.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any(feature = "full", feature = "full-sgx"))] #![allow(clippy::type_complexity, clippy::diverging_sub_expression)] use std::cell::Cell; @@ -151,6 +151,7 @@ const _: fn() = || { AmbiguousIfUnpin::some_item(&f); }; +#[cfg(not(target_env = "sgx"))] cfg_not_wasi! { mod fs { use super::*; @@ -197,6 +198,7 @@ cfg_not_wasi! { } cfg_not_wasi! { + #[cfg(not(target_env = "sgx"))] assert_value!(tokio::net::TcpSocket: Send & Sync & Unpin); async_assert_fn!(tokio::net::TcpListener::bind(SocketAddr): Send & Sync & !Unpin); async_assert_fn!(tokio::net::TcpStream::connect(SocketAddr): Send & Sync & !Unpin); @@ -215,7 +217,8 @@ async_assert_fn!(tokio::net::TcpStream::readable(_): Send & Sync & !Unpin); async_assert_fn!(tokio::net::TcpStream::ready(_, tokio::io::Interest): Send & Sync & !Unpin); async_assert_fn!(tokio::net::TcpStream::writable(_): Send & Sync & !Unpin); -// Wasi does not support UDP +// Wasi and SGX do not support UDP +#[cfg(not(target_env = "sgx"))] cfg_not_wasi! { mod udp_socket { use super::*; @@ -296,6 +299,7 @@ mod windows_named_pipe { async_assert_fn!(NamedPipeServer::writable(_): Send & Sync & !Unpin); } +#[cfg(not(target_env = "sgx"))] cfg_not_wasi! { mod test_process { use super::*; diff --git a/tokio/tests/buffered.rs b/tokio/tests/buffered.rs index 27e75d10d52..2ba9aa6a44e 100644 --- a/tokio/tests/buffered.rs +++ b/tokio/tests/buffered.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi does not support bind() +#![cfg(all(any(feature = "full", feature = "full-sgx"), not(target_os = "wasi")))] // Wasi does not support bind() use tokio::net::TcpListener; use tokio_test::assert_ok; diff --git a/tokio/tests/io_async_read.rs b/tokio/tests/io_async_read.rs index aaeadfa4c11..77062b5334b 100644 --- a/tokio/tests/io_async_read.rs +++ b/tokio/tests/io_async_read.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any(feature = "full", feature = "full-sgx"))] use tokio::io::AsyncRead; diff --git a/tokio/tests/io_chain.rs b/tokio/tests/io_chain.rs index e2d59411a11..29a36290b7a 100644 --- a/tokio/tests/io_chain.rs +++ b/tokio/tests/io_chain.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any(feature = "full", feature = "full-sgx"))] use tokio::io::AsyncReadExt; use tokio_test::assert_ok; diff --git a/tokio/tests/io_copy.rs b/tokio/tests/io_copy.rs index 82d92a9688b..3037af04b85 100644 --- a/tokio/tests/io_copy.rs +++ b/tokio/tests/io_copy.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any(feature = "full", feature = "full-sgx"))] use bytes::BytesMut; use futures::ready; diff --git a/tokio/tests/io_driver.rs b/tokio/tests/io_driver.rs index 2e2c84746c9..5b18a254181 100644 --- a/tokio/tests/io_driver.rs +++ b/tokio/tests/io_driver.rs @@ -1,6 +1,6 @@ #![warn(rust_2018_idioms)] // Wasi does not support panic recovery or threading -#![cfg(all(feature = "full", not(target_os = "wasi")))] +#![cfg(all(any(feature = "full", feature = "full-sgx"), not(target_os = "wasi")))] use tokio::net::TcpListener; use tokio::runtime; diff --git a/tokio/tests/io_driver_drop.rs b/tokio/tests/io_driver_drop.rs index c3182637916..21b7c7bb9af 100644 --- a/tokio/tests/io_driver_drop.rs +++ b/tokio/tests/io_driver_drop.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi does not support bind +#![cfg(all(any(feature = "full", feature = "full-sgx"), not(target_os = "wasi")))] // Wasi does not support bind use tokio::net::TcpListener; use tokio::runtime; diff --git a/tokio/tests/io_lines.rs b/tokio/tests/io_lines.rs index 9996d81ca74..e172172c480 100644 --- a/tokio/tests/io_lines.rs +++ b/tokio/tests/io_lines.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any(feature = "full", feature = "full-sgx"))] use tokio::io::AsyncBufReadExt; use tokio_test::assert_ok; diff --git a/tokio/tests/io_read.rs b/tokio/tests/io_read.rs index 6bea0ac865e..40a76ac2b32 100644 --- a/tokio/tests/io_read.rs +++ b/tokio/tests/io_read.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi does not support panic recovery +#![cfg(all(any(feature = "full", feature = "full-sgx"), not(target_os = "wasi")))] // Wasi does not support panic recovery use tokio::io::{AsyncRead, AsyncReadExt, ReadBuf}; use tokio_test::assert_ok; diff --git a/tokio/tests/io_read_exact.rs b/tokio/tests/io_read_exact.rs index d0e659bd339..6040b86e08b 100644 --- a/tokio/tests/io_read_exact.rs +++ b/tokio/tests/io_read_exact.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any(feature = "full", feature = "full-sgx"))] use tokio::io::AsyncReadExt; use tokio_test::assert_ok; diff --git a/tokio/tests/io_read_line.rs b/tokio/tests/io_read_line.rs index 15841c9b49d..aed181056d4 100644 --- a/tokio/tests/io_read_line.rs +++ b/tokio/tests/io_read_line.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any(feature = "full", feature = "full-sgx"))] use std::io::ErrorKind; use tokio::io::{AsyncBufReadExt, BufReader, Error}; diff --git a/tokio/tests/io_read_to_end.rs b/tokio/tests/io_read_to_end.rs index 29b60becec4..743efef7882 100644 --- a/tokio/tests/io_read_to_end.rs +++ b/tokio/tests/io_read_to_end.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any(feature = "full", feature = "full-sgx"))] use std::pin::Pin; use std::task::{Context, Poll}; diff --git a/tokio/tests/io_read_to_string.rs b/tokio/tests/io_read_to_string.rs index f30c26caa88..2e554a33e1c 100644 --- a/tokio/tests/io_read_to_string.rs +++ b/tokio/tests/io_read_to_string.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any(feature = "full", feature = "full-sgx"))] use std::io; use tokio::io::AsyncReadExt; diff --git a/tokio/tests/io_read_until.rs b/tokio/tests/io_read_until.rs index 61800a0d9c1..629936b1eaa 100644 --- a/tokio/tests/io_read_until.rs +++ b/tokio/tests/io_read_until.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any(feature = "full", feature = "full-sgx"))] use std::io::ErrorKind; use tokio::io::{AsyncBufReadExt, BufReader, Error}; diff --git a/tokio/tests/io_split.rs b/tokio/tests/io_split.rs index 9f17c9eb14e..91e289e620c 100644 --- a/tokio/tests/io_split.rs +++ b/tokio/tests/io_split.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi does not support panic recovery +#![cfg(all(any(feature = "full", feature = "full-sgx"), not(target_os = "wasi")))] // Wasi does not support panic recovery use tokio::io::{ split, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, ReadBuf, ReadHalf, WriteHalf, diff --git a/tokio/tests/io_take.rs b/tokio/tests/io_take.rs index 539f17f3a2d..df0a2c4f5d9 100644 --- a/tokio/tests/io_take.rs +++ b/tokio/tests/io_take.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi does not support panic recovery +#![cfg(all(any(feature = "full", feature = "full-sgx"), not(target_os = "wasi")))] // Wasi does not support panic recovery use std::pin::Pin; use std::task::{Context, Poll}; diff --git a/tokio/tests/io_write.rs b/tokio/tests/io_write.rs index 96cebc3313b..0620566f9dc 100644 --- a/tokio/tests/io_write.rs +++ b/tokio/tests/io_write.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any(feature = "full", feature = "full-sgx"))] use tokio::io::{AsyncWrite, AsyncWriteExt}; use tokio_test::assert_ok; diff --git a/tokio/tests/io_write_all.rs b/tokio/tests/io_write_all.rs index 7ca02228a3c..c88aba46d22 100644 --- a/tokio/tests/io_write_all.rs +++ b/tokio/tests/io_write_all.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any(feature = "full", feature = "full-sgx"))] use tokio::io::{AsyncWrite, AsyncWriteExt}; use tokio_test::assert_ok; diff --git a/tokio/tests/io_write_int.rs b/tokio/tests/io_write_int.rs index 48a583d8c3f..af52ec97c55 100644 --- a/tokio/tests/io_write_int.rs +++ b/tokio/tests/io_write_int.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any(feature = "full", feature = "full-sgx"))] use tokio::io::{AsyncWrite, AsyncWriteExt}; diff --git a/tokio/tests/net_bind_resource.rs b/tokio/tests/net_bind_resource.rs index 05fd1604b87..24c99eebeab 100644 --- a/tokio/tests/net_bind_resource.rs +++ b/tokio/tests/net_bind_resource.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi doesn't support panic recovery or bind +#![cfg(all(any(feature = "full", feature = "full-sgx"), not(target_os = "wasi")))] // Wasi doesn't support panic recovery or bind use tokio::net::TcpListener; diff --git a/tokio/tests/rt_basic.rs b/tokio/tests/rt_basic.rs index 47bf2dfdc12..7afd4e339c1 100644 --- a/tokio/tests/rt_basic.rs +++ b/tokio/tests/rt_basic.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any(feature = "full", feature = "full-sgx"))] use tokio::runtime::Runtime; use tokio::sync::oneshot; diff --git a/tokio/tests/rt_common.rs b/tokio/tests/rt_common.rs index 11c44a8d1c2..9dfc12412e6 100644 --- a/tokio/tests/rt_common.rs +++ b/tokio/tests/rt_common.rs @@ -1,6 +1,6 @@ #![allow(clippy::needless_range_loop)] #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any(feature = "full", feature = "full-sgx"))] // Tests to run on both current-thread & multi-thread runtime variants. @@ -997,7 +997,7 @@ rt_test! { drop(rt); } - #[cfg(not(target_os="wasi"))] // Wasi doesn't support UDP or bind() + #[cfg(not(any(target_os="wasi", target_env = "sgx")))] // Wasi doesn't support UDP or bind(), SGX doesn't support UDP #[test] fn io_notify_while_shutting_down() { use tokio::net::UdpSocket; diff --git a/tokio/tests/rt_threaded.rs b/tokio/tests/rt_threaded.rs index 8a61c6ad38f..3773fbd5598 100644 --- a/tokio/tests/rt_threaded.rs +++ b/tokio/tests/rt_threaded.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] +#![cfg(all(any(feature = "full", feature = "full-sgx"), not(target_os = "wasi")))] use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::net::{TcpListener, TcpStream}; @@ -622,6 +622,7 @@ fn test_nested_block_in_place_with_block_on_between() { // is sufficient. If there is a regression, this test will hang. In theory, we // could add limits, but that would be likely to fail on CI. #[test] +#[cfg(not(target_env = "sgx"))] // Test freezes on SGX #[cfg(not(tokio_no_tuning_tests))] fn test_tuning() { use std::sync::atomic::AtomicBool; diff --git a/tokio/tests/sync_barrier.rs b/tokio/tests/sync_barrier.rs index ac5977f24d8..6997c3d36ba 100644 --- a/tokio/tests/sync_barrier.rs +++ b/tokio/tests/sync_barrier.rs @@ -1,6 +1,6 @@ #![allow(clippy::unnecessary_operation)] #![warn(rust_2018_idioms)] -#![cfg(feature = "sync")] +#![cfg(any(feature = "sync", feature = "full-sgx"))] #[cfg(all(target_family = "wasm", not(target_os = "wasi")))] use wasm_bindgen_test::wasm_bindgen_test as test; diff --git a/tokio/tests/sync_errors.rs b/tokio/tests/sync_errors.rs index 4e43c8f311e..3af6b4ed93e 100644 --- a/tokio/tests/sync_errors.rs +++ b/tokio/tests/sync_errors.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "sync")] +#![cfg(any(feature = "sync", feature = "full-sgx"))] #[cfg(all(target_family = "wasm", not(target_os = "wasi")))] use wasm_bindgen_test::wasm_bindgen_test as test; diff --git a/tokio/tests/sync_mpsc.rs b/tokio/tests/sync_mpsc.rs index 1b581ce98c1..85d8b21cf09 100644 --- a/tokio/tests/sync_mpsc.rs +++ b/tokio/tests/sync_mpsc.rs @@ -1,6 +1,6 @@ #![allow(clippy::redundant_clone)] #![warn(rust_2018_idioms)] -#![cfg(feature = "sync")] +#![cfg(any(feature = "sync", feature = "full-sgx"))] #[cfg(all(target_family = "wasm", not(target_os = "wasi")))] use wasm_bindgen_test::wasm_bindgen_test as test; diff --git a/tokio/tests/sync_mutex.rs b/tokio/tests/sync_mutex.rs index f423c82e7b1..2114a44ad2c 100644 --- a/tokio/tests/sync_mutex.rs +++ b/tokio/tests/sync_mutex.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "sync")] +#![cfg(any(feature = "sync", feature = "full-sgx"))] #[cfg(all(target_family = "wasm", not(target_os = "wasi")))] use wasm_bindgen_test::wasm_bindgen_test as test; diff --git a/tokio/tests/sync_mutex_owned.rs b/tokio/tests/sync_mutex_owned.rs index badcef3d08e..360fdfda1b2 100644 --- a/tokio/tests/sync_mutex_owned.rs +++ b/tokio/tests/sync_mutex_owned.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "sync")] +#![cfg(any(feature = "sync", feature = "full-sgx"))] #[cfg(all(target_family = "wasm", not(target_os = "wasi")))] use wasm_bindgen_test::wasm_bindgen_test as test; diff --git a/tokio/tests/sync_notify.rs b/tokio/tests/sync_notify.rs index e31b9d49cff..5fea4656fa3 100644 --- a/tokio/tests/sync_notify.rs +++ b/tokio/tests/sync_notify.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "sync")] +#![cfg(any(feature = "sync", feature = "full-sgx"))] #[cfg(all(target_family = "wasm", not(target_os = "wasi")))] use wasm_bindgen_test::wasm_bindgen_test as test; diff --git a/tokio/tests/sync_oneshot.rs b/tokio/tests/sync_oneshot.rs index 163d50de9d2..9ed3e333404 100644 --- a/tokio/tests/sync_oneshot.rs +++ b/tokio/tests/sync_oneshot.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "sync")] +#![cfg(any(feature = "sync", feature = "full-sgx"))] #[cfg(all(target_family = "wasm", not(target_os = "wasi")))] use wasm_bindgen_test::wasm_bindgen_test as test; diff --git a/tokio/tests/sync_semaphore.rs b/tokio/tests/sync_semaphore.rs index 40a5a0802a6..51cbca6e551 100644 --- a/tokio/tests/sync_semaphore.rs +++ b/tokio/tests/sync_semaphore.rs @@ -1,4 +1,4 @@ -#![cfg(feature = "sync")] +#![cfg(any(feature = "sync", feature = "full-sgx"))] #[cfg(all(target_family = "wasm", not(target_os = "wasi")))] use wasm_bindgen_test::wasm_bindgen_test as test; diff --git a/tokio/tests/sync_semaphore_owned.rs b/tokio/tests/sync_semaphore_owned.rs index d4b12d40e45..fa420d76791 100644 --- a/tokio/tests/sync_semaphore_owned.rs +++ b/tokio/tests/sync_semaphore_owned.rs @@ -1,4 +1,4 @@ -#![cfg(feature = "sync")] +#![cfg(any(feature = "sync", feature = "full-sgx"))] #[cfg(all(target_family = "wasm", not(target_os = "wasi")))] use wasm_bindgen_test::wasm_bindgen_test as test; diff --git a/tokio/tests/sync_watch.rs b/tokio/tests/sync_watch.rs index a5b229f7ddc..9abfe5a8d61 100644 --- a/tokio/tests/sync_watch.rs +++ b/tokio/tests/sync_watch.rs @@ -1,6 +1,6 @@ #![allow(clippy::cognitive_complexity)] #![warn(rust_2018_idioms)] -#![cfg(feature = "sync")] +#![cfg(any(feature = "sync", feature = "full-sgx"))] #[cfg(all(target_family = "wasm", not(target_os = "wasi")))] use wasm_bindgen_test::wasm_bindgen_test as test; diff --git a/tokio/tests/task_blocking.rs b/tokio/tests/task_blocking.rs index b9cce9a4aa4..1613fde72e6 100644 --- a/tokio/tests/task_blocking.rs +++ b/tokio/tests/task_blocking.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi doesn't support threads +#![cfg(all(any(feature = "full", feature = "full-sgx"), not(target_os = "wasi")))] // Wasi doesn't support threads use tokio::{runtime, task, time}; use tokio_test::assert_ok; diff --git a/tokio/tests/task_local_set.rs b/tokio/tests/task_local_set.rs index 168a05808bd..78bc45ead0e 100644 --- a/tokio/tests/task_local_set.rs +++ b/tokio/tests/task_local_set.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any(feature = "full", feature = "full-sgx"))] use futures::{ future::{pending, ready}, diff --git a/tokio/tests/tcp_accept.rs b/tokio/tests/tcp_accept.rs index d547c48daa3..9bfc94e2e21 100644 --- a/tokio/tests/tcp_accept.rs +++ b/tokio/tests/tcp_accept.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi doesn't support bind +#![cfg(all(any(feature = "full", feature = "full-sgx"), not(target_os = "wasi")))] // Wasi doesn't support bind use tokio::net::{TcpListener, TcpStream}; use tokio::sync::{mpsc, oneshot}; diff --git a/tokio/tests/tcp_connect.rs b/tokio/tests/tcp_connect.rs index 269ba8ef695..26f0d6a25d6 100644 --- a/tokio/tests/tcp_connect.rs +++ b/tokio/tests/tcp_connect.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi doesn't support bind +#![cfg(all(any(feature = "full", feature = "full-sgx"), not(target_os = "wasi")))] // Wasi doesn't support bind use tokio::net::{TcpListener, TcpStream}; use tokio::sync::oneshot; diff --git a/tokio/tests/tcp_echo.rs b/tokio/tests/tcp_echo.rs index dfd4dd7b9f4..2bf858beb5c 100644 --- a/tokio/tests/tcp_echo.rs +++ b/tokio/tests/tcp_echo.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi doesn't support bind +#![cfg(all(any(feature = "full", feature = "full-sgx"), not(target_os = "wasi")))] // Wasi doesn't support bind use tokio::io::{self, AsyncReadExt, AsyncWriteExt}; use tokio::net::{TcpListener, TcpStream}; diff --git a/tokio/tests/tcp_into_split.rs b/tokio/tests/tcp_into_split.rs index df8efadb50f..b98eaf97951 100644 --- a/tokio/tests/tcp_into_split.rs +++ b/tokio/tests/tcp_into_split.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi doesn't support bind +#![cfg(all(any(feature = "full", feature = "full-sgx"), not(target_os = "wasi")))] // Wasi doesn't support bind use std::io::{Error, ErrorKind, Result}; use std::io::{Read, Write}; @@ -44,6 +44,7 @@ async fn split() -> Result<()> { assert_eq!(peek_len1, peek_len2); let read_len = read_half.read(&mut read_buf[..]).await?; + #[cfg(not(target_env = "sgx"))] // peek always returns Ok(0) in SGX assert_eq!(peek_len1, read_len); assert_eq!(&read_buf[..read_len], MSG); Ok(()) @@ -81,6 +82,7 @@ async fn reunite() -> Result<()> { } /// Test that dropping the write half actually closes the stream. +#[cfg_attr(target_env = "sgx", ignore = "Shutdown is ineffective on SGX platform")] #[tokio::test] async fn drop_write() -> Result<()> { const MSG: &[u8] = b"split"; diff --git a/tokio/tests/tcp_split.rs b/tokio/tests/tcp_split.rs index 32aaa1f771b..53f350adfef 100644 --- a/tokio/tests/tcp_split.rs +++ b/tokio/tests/tcp_split.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi doesn't support bind +#![cfg(all(any(feature = "full", feature = "full-sgx"), not(target_os = "wasi")))] // Wasi doesn't support bind use std::io::Result; use std::io::{Read, Write}; @@ -33,6 +33,7 @@ async fn split() -> Result<()> { assert_eq!(peek_len1, peek_len2); let read_len = read_half.read(&mut read_buf[..]).await?; + #[cfg(not(target_env = "sgx"))] // peek always returns Ok(0) in SGX assert_eq!(peek_len1, read_len); assert_eq!(&read_buf[..read_len], MSG); diff --git a/tokio/tests/test_clock.rs b/tokio/tests/test_clock.rs index 891636fdb28..901eae23dbb 100644 --- a/tokio/tests/test_clock.rs +++ b/tokio/tests/test_clock.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any(feature = "full", feature = "full-sgx"))] use tokio::time::{self, Duration, Instant}; diff --git a/tokio/tests/time_interval.rs b/tokio/tests/time_interval.rs index 4f3e95b0d2a..aa8cc1fa68f 100644 --- a/tokio/tests/time_interval.rs +++ b/tokio/tests/time_interval.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any(feature = "full", feature = "full-sgx"))] use std::pin::Pin; use std::task::{Context, Poll}; diff --git a/tokio/tests/time_rt.rs b/tokio/tests/time_rt.rs index 13f888c1791..e0c58c3a87f 100644 --- a/tokio/tests/time_rt.rs +++ b/tokio/tests/time_rt.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any(feature = "full", feature = "full-sgx"))] use tokio::time::*; diff --git a/tokio/tests/time_sleep.rs b/tokio/tests/time_sleep.rs index 6da7ada0394..6cb9369880c 100644 --- a/tokio/tests/time_sleep.rs +++ b/tokio/tests/time_sleep.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any(feature = "full", feature = "full-sgx"))] use std::future::Future; use std::task::Context; diff --git a/tokio/tests/time_timeout.rs b/tokio/tests/time_timeout.rs index ec871cf62fe..055fdcd801a 100644 --- a/tokio/tests/time_timeout.rs +++ b/tokio/tests/time_timeout.rs @@ -1,5 +1,5 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "full")] +#![cfg(any(feature = "full", feature = "full-sgx"))] use tokio::sync::oneshot; use tokio::time::{self, timeout, timeout_at, Instant}; From ab2ae6ef11b121d5aacd0ee1208f04f86a1e48fa Mon Sep 17 00:00:00 2001 From: Raoul Strackx Date: Tue, 14 Nov 2023 16:26:23 +0100 Subject: [PATCH 2/2] Local CI support --- ct.sh | 23 +++++++++++++++++++++++ ct_env.sh | 10 ++++++++++ 2 files changed, 33 insertions(+) create mode 100755 ct.sh create mode 100755 ct_env.sh diff --git a/ct.sh b/ct.sh new file mode 100755 index 00000000000..6736f5a4dd8 --- /dev/null +++ b/ct.sh @@ -0,0 +1,23 @@ +#!/bin/bash -ex +repo_root=$(readlink -f $(dirname ${BASH_SOURCE[0]})) +cd ${repo_root} + +source ${repo_root}/ct_env.sh + +cargo test + +pushd tokio +cargo test --target x86_64-fortanix-unknown-sgx --features "full-sgx" +popd + +pushd tokio-macros +cargo test --target x86_64-fortanix-unknown-sgx +popd + +pushd tokio-stream +cargo test --target x86_64-fortanix-unknown-sgx +popd + +pushd stress-test +cargo test --target x86_64-fortanix-unknown-sgx +popd diff --git a/ct_env.sh b/ct_env.sh new file mode 100755 index 00000000000..3653206bfb6 --- /dev/null +++ b/ct_env.sh @@ -0,0 +1,10 @@ +#!/bin/bash -ex +repo_root=$(readlink -f $(dirname ${BASH_SOURCE[0]})) +cd ${repo_root} + +# Unfortunately, the `ftxsgx-runner-cargo` application doesn't enable us to point to a runner within the same workspace. We use a hack here by pointing to `enclave-runner` and making sure such an executable exists when running CI +pushd enclave-runner +cargo build +popd + +export PATH=${repo_root}/target/debug/:${PATH}