From 39895b537d09b20a6e19863641cb5d5371047665 Mon Sep 17 00:00:00 2001 From: Mohsen Zohrevandi Date: Mon, 29 Aug 2022 12:25:22 -0700 Subject: [PATCH] Remove almost all hacks --- intel-sgx/async-usercalls/src/batch_drop.rs | 3 +- intel-sgx/async-usercalls/src/callback.rs | 4 +- intel-sgx/async-usercalls/src/duplicated.rs | 168 ------------------ .../async-usercalls/src/hacks/async_queues.rs | 52 ------ intel-sgx/async-usercalls/src/lib.rs | 7 +- intel-sgx/async-usercalls/src/provider_api.rs | 2 +- .../async-usercalls/src/provider_core.rs | 2 +- intel-sgx/async-usercalls/src/queues.rs | 28 +-- intel-sgx/async-usercalls/src/raw.rs | 3 +- .../src/{hacks/mod.rs => utils.rs} | 25 +-- 10 files changed, 25 insertions(+), 269 deletions(-) delete mode 100644 intel-sgx/async-usercalls/src/duplicated.rs delete mode 100644 intel-sgx/async-usercalls/src/hacks/async_queues.rs rename intel-sgx/async-usercalls/src/{hacks/mod.rs => utils.rs} (56%) diff --git a/intel-sgx/async-usercalls/src/batch_drop.rs b/intel-sgx/async-usercalls/src/batch_drop.rs index 62435460..2f7bb698 100644 --- a/intel-sgx/async-usercalls/src/batch_drop.rs +++ b/intel-sgx/async-usercalls/src/batch_drop.rs @@ -1,10 +1,9 @@ -use crate::hacks::Usercall; use crate::provider_core::ProviderCore; use ipc_queue::Identified; use std::cell::RefCell; use std::mem; use std::os::fortanix_sgx::usercalls::alloc::{User, UserSafe}; -use std::os::fortanix_sgx::usercalls::raw::UsercallNrs; +use std::os::fortanix_sgx::usercalls::raw::{Usercall, UsercallNrs}; pub trait BatchDroppable: private::BatchDroppable {} impl BatchDroppable for T {} diff --git a/intel-sgx/async-usercalls/src/callback.rs b/intel-sgx/async-usercalls/src/callback.rs index 7586ebb0..b89fcaf9 100644 --- a/intel-sgx/async-usercalls/src/callback.rs +++ b/intel-sgx/async-usercalls/src/callback.rs @@ -1,7 +1,7 @@ -use crate::duplicated::{FromSgxResult, ReturnValue}; -use crate::hacks::Return; use fortanix_sgx_abi::{invoke_with_usercalls, Fd, Result}; use std::io; +use std::os::fortanix_sgx::usercalls::raw::{Return, ReturnValue}; +use std::os::fortanix_sgx::usercalls::FromSgxResult; pub struct CbFn(Box); diff --git a/intel-sgx/async-usercalls/src/duplicated.rs b/intel-sgx/async-usercalls/src/duplicated.rs deleted file mode 100644 index 0a39e5a1..00000000 --- a/intel-sgx/async-usercalls/src/duplicated.rs +++ /dev/null @@ -1,168 +0,0 @@ -//! this file contains code duplicated from libstd's sys/sgx -use fortanix_sgx_abi::{Error, Result, RESULT_SUCCESS}; -use std::io; -use std::ptr::NonNull; - -fn check_os_error(err: Result) -> i32 { - // FIXME: not sure how to make sure all variants of Error are covered - if err == Error::NotFound as _ - || err == Error::PermissionDenied as _ - || err == Error::ConnectionRefused as _ - || err == Error::ConnectionReset as _ - || err == Error::ConnectionAborted as _ - || err == Error::NotConnected as _ - || err == Error::AddrInUse as _ - || err == Error::AddrNotAvailable as _ - || err == Error::BrokenPipe as _ - || err == Error::AlreadyExists as _ - || err == Error::WouldBlock as _ - || err == Error::InvalidInput as _ - || err == Error::InvalidData as _ - || err == Error::TimedOut as _ - || err == Error::WriteZero as _ - || err == Error::Interrupted as _ - || err == Error::Other as _ - || err == Error::UnexpectedEof as _ - || ((Error::UserRangeStart as _)..=(Error::UserRangeEnd as _)).contains(&err) - { - err - } else { - panic!("Usercall: returned invalid error value {}", err) - } -} - -pub trait FromSgxResult { - type Return; - - fn from_sgx_result(self) -> io::Result; -} - -impl FromSgxResult for (Result, T) { - type Return = T; - - fn from_sgx_result(self) -> io::Result { - if self.0 == RESULT_SUCCESS { - Ok(self.1) - } else { - Err(io::Error::from_raw_os_error(check_os_error(self.0))) - } - } -} - -impl FromSgxResult for Result { - type Return = (); - - fn from_sgx_result(self) -> io::Result { - if self == RESULT_SUCCESS { - Ok(()) - } else { - Err(io::Error::from_raw_os_error(check_os_error(self))) - } - } -} - -type Register = u64; - -pub trait RegisterArgument { - fn from_register(_: Register) -> Self; - fn into_register(self) -> Register; -} - -pub trait ReturnValue { - fn from_registers(call: &'static str, regs: (Register, Register)) -> Self; -} - -macro_rules! define_ra { - (< $i:ident > $t:ty) => { - impl<$i> RegisterArgument for $t { - fn from_register(a: Register) -> Self { - a as _ - } - fn into_register(self) -> Register { - self as _ - } - } - }; - ($i:ty as $t:ty) => { - impl RegisterArgument for $t { - fn from_register(a: Register) -> Self { - a as $i as _ - } - fn into_register(self) -> Register { - self as $i as _ - } - } - }; - ($t:ty) => { - impl RegisterArgument for $t { - fn from_register(a: Register) -> Self { - a as _ - } - fn into_register(self) -> Register { - self as _ - } - } - }; -} - -define_ra!(Register); -define_ra!(i64); -define_ra!(u32); -define_ra!(u32 as i32); -define_ra!(u16); -define_ra!(u16 as i16); -define_ra!(u8); -define_ra!(u8 as i8); -define_ra!(usize); -define_ra!(usize as isize); -define_ra!( *const T); -define_ra!( *mut T); - -impl RegisterArgument for bool { - fn from_register(a: Register) -> bool { - if a != 0 { - true - } else { - false - } - } - fn into_register(self) -> Register { - self as _ - } -} - -impl RegisterArgument for Option> { - fn from_register(a: Register) -> Option> { - NonNull::new(a as _) - } - fn into_register(self) -> Register { - self.map_or(0 as _, NonNull::as_ptr) as _ - } -} - -impl ReturnValue for ! { - fn from_registers(call: &'static str, _regs: (Register, Register)) -> Self { - panic!("Usercall {}: did not expect to be re-entered", call); - } -} - -impl ReturnValue for () { - fn from_registers(_call: &'static str, usercall_retval: (Register, Register)) -> Self { - assert!(usercall_retval.0 == 0); - assert!(usercall_retval.1 == 0); - () - } -} - -impl ReturnValue for T { - fn from_registers(_call: &'static str, usercall_retval: (Register, Register)) -> Self { - assert!(usercall_retval.1 == 0); - T::from_register(usercall_retval.0) - } -} - -impl ReturnValue for (T, U) { - fn from_registers(_call: &'static str, regs: (Register, Register)) -> Self { - (T::from_register(regs.0), U::from_register(regs.1)) - } -} diff --git a/intel-sgx/async-usercalls/src/hacks/async_queues.rs b/intel-sgx/async-usercalls/src/hacks/async_queues.rs deleted file mode 100644 index 5e7a9252..00000000 --- a/intel-sgx/async-usercalls/src/hacks/async_queues.rs +++ /dev/null @@ -1,52 +0,0 @@ -use super::{Cancel, Return, Usercall}; -use crate::duplicated::ReturnValue; -use fortanix_sgx_abi::FifoDescriptor; -use std::num::NonZeroU64; -use std::os::fortanix_sgx::usercalls; -use std::os::fortanix_sgx::usercalls::raw; -use std::os::fortanix_sgx::usercalls::alloc::{UserSafeSized, User}; -use std::{mem, ptr}; - -// TODO: remove these once support for cancel queue is added in `std::os::fortanix_sgx` - -pub unsafe fn async_queues( - usercall_queue: *mut FifoDescriptor, - return_queue: *mut FifoDescriptor, - cancel_queue: *mut FifoDescriptor, -) -> raw::Result { - ReturnValue::from_registers( - "async_queues", - raw::do_usercall( - NonZeroU64::new(raw::UsercallNrs::async_queues as _).unwrap(), - usercall_queue as _, - return_queue as _, - cancel_queue as _, - 0, - false, - ), - ) -} - -pub unsafe fn alloc_descriptor() -> *mut FifoDescriptor { - #[repr(transparent)] - #[derive(Copy, Clone)] - struct WrappedFifoDescriptor(FifoDescriptor); - unsafe impl UserSafeSized for WrappedFifoDescriptor{} - - User::>::uninitialized().into_raw() as _ -} - -pub unsafe fn to_enclave(ptr: *mut FifoDescriptor) -> FifoDescriptor { - let mut dest: FifoDescriptor = mem::zeroed(); - ptr::copy( - ptr as *const u8, - (&mut dest) as *mut FifoDescriptor as *mut u8, - mem::size_of_val(&mut dest), - ); - usercalls::free( - ptr as _, - mem::size_of::>(), - mem::align_of::>(), - ); - dest -} diff --git a/intel-sgx/async-usercalls/src/lib.rs b/intel-sgx/async-usercalls/src/lib.rs index 13edc5e7..f8b5b429 100644 --- a/intel-sgx/async-usercalls/src/lib.rs +++ b/intel-sgx/async-usercalls/src/lib.rs @@ -42,13 +42,12 @@ use crossbeam_channel as mpmc; use ipc_queue::Identified; use std::collections::HashMap; +use std::os::fortanix_sgx::usercalls::raw::{Cancel, Return, Usercall}; use std::sync::Mutex; use std::time::Duration; mod batch_drop; mod callback; -mod duplicated; -mod hacks; mod io_bufs; mod provider_api; mod provider_core; @@ -56,6 +55,7 @@ mod queues; mod raw; #[cfg(test)] mod test_support; +mod utils; pub use self::batch_drop::batch_drop; pub use self::callback::CbFn; @@ -63,7 +63,6 @@ pub use self::io_bufs::{ReadBuffer, UserBuf, WriteBuffer}; pub use self::raw::RawApi; use self::callback::*; -use self::hacks::{Cancel, Return, Usercall}; use self::provider_core::ProviderCore; use self::queues::*; @@ -235,8 +234,8 @@ impl CallbackHandler { #[cfg(test)] mod tests { use super::*; - use crate::hacks::MakeSend; use crate::test_support::*; + use crate::utils::MakeSend; use crossbeam_channel as mpmc; use std::io; use std::net::{TcpListener, TcpStream}; diff --git a/intel-sgx/async-usercalls/src/provider_api.rs b/intel-sgx/async-usercalls/src/provider_api.rs index ca307b17..ae795cd9 100644 --- a/intel-sgx/async-usercalls/src/provider_api.rs +++ b/intel-sgx/async-usercalls/src/provider_api.rs @@ -1,7 +1,7 @@ use crate::batch_drop; -use crate::hacks::MakeSend; use crate::io_bufs::UserBuf; use crate::raw::RawApi; +use crate::utils::MakeSend; use crate::{AsyncUsercallProvider, CancelHandle}; use fortanix_sgx_abi::Fd; use std::io; diff --git a/intel-sgx/async-usercalls/src/provider_core.rs b/intel-sgx/async-usercalls/src/provider_core.rs index dabd7bc5..5ea3a6ae 100644 --- a/intel-sgx/async-usercalls/src/provider_core.rs +++ b/intel-sgx/async-usercalls/src/provider_core.rs @@ -1,8 +1,8 @@ -use crate::hacks::{Cancel, Return, Usercall}; use crate::queues::*; use crate::CancelHandle; use crossbeam_channel as mpmc; use ipc_queue::Identified; +use std::os::fortanix_sgx::usercalls::raw::{Cancel, Return, Usercall}; use std::sync::atomic::{AtomicU32, Ordering}; pub(crate) struct ProviderCore { diff --git a/intel-sgx/async-usercalls/src/queues.rs b/intel-sgx/async-usercalls/src/queues.rs index c3a50eb1..d33b22ab 100644 --- a/intel-sgx/async-usercalls/src/queues.rs +++ b/intel-sgx/async-usercalls/src/queues.rs @@ -1,10 +1,12 @@ -use crate::hacks::{alloc_descriptor, async_queues, to_enclave, Cancel, Return, Usercall}; use crate::provider_core::ProviderId; use crossbeam_channel as mpmc; use fortanix_sgx_abi::{EV_CANCELQ_NOT_FULL, EV_RETURNQ_NOT_EMPTY, EV_USERCALLQ_NOT_FULL}; use ipc_queue::{self, Identified, QueueEvent, RecvError, SynchronizationError, Synchronizer}; use lazy_static::lazy_static; -use std::os::fortanix_sgx::usercalls::raw; +use std::os::fortanix_sgx::usercalls::alloc::User; +use std::os::fortanix_sgx::usercalls::raw::{ + self, async_queues, Cancel, FifoDescriptor, Return, Usercall, +}; use std::sync::{Arc, Mutex}; use std::{io, iter, thread}; @@ -54,24 +56,24 @@ lazy_static! { } fn init_async_queues() -> io::Result<(Sender, Sender, Receiver)> { - // FIXME: this is just a hack. Replace these with `User::>::uninitialized().into_raw()` - let usercall_q = unsafe { alloc_descriptor::() }; - let cancel_q = unsafe { alloc_descriptor::() }; - let return_q = unsafe { alloc_descriptor::() }; + let usercall_q = User::>::uninitialized().into_raw(); + let cancel_q = User::>::uninitialized().into_raw(); + let return_q = User::>::uninitialized().into_raw(); let r = unsafe { async_queues(usercall_q, return_q, cancel_q) }; if r != 0 { return Err(io::Error::from_raw_os_error(r)); } - // FIXME: this is another hack, replace with `unsafe { User::>::from_raw(q) }.to_enclave()` - let usercall_queue = unsafe { to_enclave(usercall_q) }; - let cancel_queue = unsafe { to_enclave(cancel_q) }; - let return_queue = unsafe { to_enclave(return_q) }; + let usercall_queue = unsafe { User::>::from_raw(usercall_q) }.to_enclave(); + let cancel_queue = unsafe { User::>::from_raw(cancel_q) }.to_enclave(); + let return_queue = unsafe { User::>::from_raw(return_q) }.to_enclave(); - let utx = unsafe { Sender::from_descriptor(usercall_queue, QueueSynchronizer { queue: Queue::Usercall }) }; - let ctx = unsafe { Sender::from_descriptor(cancel_queue, QueueSynchronizer { queue: Queue::Cancel }) }; - let rx = unsafe { Receiver::from_descriptor(return_queue, QueueSynchronizer { queue: Queue::Return }) }; + // FIXME: once `WithId` is exported from `std::os::fortanix_sgx::usercalls::raw`, we can remove + // `transmute` calls here and use FifoDescriptor/WithId from std everywhere including in ipc-queue. + let utx = unsafe { Sender::from_descriptor(std::mem::transmute(usercall_queue), QueueSynchronizer { queue: Queue::Usercall }) }; + let ctx = unsafe { Sender::from_descriptor(std::mem::transmute(cancel_queue), QueueSynchronizer { queue: Queue::Cancel }) }; + let rx = unsafe { Receiver::from_descriptor(std::mem::transmute(return_queue), QueueSynchronizer { queue: Queue::Return }) }; Ok((utx, ctx, rx)) } diff --git a/intel-sgx/async-usercalls/src/raw.rs b/intel-sgx/async-usercalls/src/raw.rs index 7edaa7eb..2939e0ae 100644 --- a/intel-sgx/async-usercalls/src/raw.rs +++ b/intel-sgx/async-usercalls/src/raw.rs @@ -1,10 +1,9 @@ use crate::callback::*; -use crate::hacks::Usercall; use crate::{AsyncUsercallProvider, CancelHandle}; use fortanix_sgx_abi::Fd; use std::io; use std::os::fortanix_sgx::usercalls::raw::ByteBuffer; -use std::os::fortanix_sgx::usercalls::raw::UsercallNrs; +use std::os::fortanix_sgx::usercalls::raw::{Usercall, UsercallNrs}; pub trait RawApi { unsafe fn raw_read( diff --git a/intel-sgx/async-usercalls/src/hacks/mod.rs b/intel-sgx/async-usercalls/src/utils.rs similarity index 56% rename from intel-sgx/async-usercalls/src/hacks/mod.rs rename to intel-sgx/async-usercalls/src/utils.rs index 5fe7a2df..78f3c051 100644 --- a/intel-sgx/async-usercalls/src/hacks/mod.rs +++ b/intel-sgx/async-usercalls/src/utils.rs @@ -1,32 +1,9 @@ use std::ops::{Deref, DerefMut}; -use std::os::fortanix_sgx::usercalls::alloc::{User, UserSafeSized}; +use std::os::fortanix_sgx::usercalls::alloc::User; use std::os::fortanix_sgx::usercalls::raw::ByteBuffer; -mod async_queues; - -pub use self::async_queues::{alloc_descriptor, async_queues, to_enclave}; - -#[repr(C)] -#[derive(Copy, Clone, Default)] -pub struct Usercall(pub u64, pub u64, pub u64, pub u64, pub u64); - -unsafe impl UserSafeSized for Usercall {} - -#[repr(C)] -#[derive(Copy, Clone, Default)] -pub struct Return(pub u64, pub u64); - -unsafe impl UserSafeSized for Return {} - -#[repr(C)] -#[derive(Copy, Clone, Default)] -pub struct Cancel; - -unsafe impl UserSafeSized for Cancel {} - pub(crate) trait MakeSendMarker {} -// Interim solution until we mark the target types appropriately pub(crate) struct MakeSend(T); impl MakeSend {