2018-08-28 04:33:26 +00:00
|
|
|
//! System bindings for the Fortanix SGX platform
|
|
|
|
//!
|
|
|
|
//! This module contains the facade (aka platform-specific) implementations of
|
|
|
|
//! OS level functionality for Fortanix SGX.
|
2020-09-29 20:27:56 +00:00
|
|
|
#![deny(unsafe_op_in_unsafe_fn)]
|
2018-08-28 04:33:26 +00:00
|
|
|
|
2019-02-10 19:23:21 +00:00
|
|
|
use crate::io::ErrorKind;
|
|
|
|
use crate::os::raw::c_char;
|
|
|
|
use crate::sync::atomic::{AtomicBool, Ordering};
|
2018-08-28 04:33:26 +00:00
|
|
|
|
|
|
|
pub mod abi;
|
2018-09-05 23:19:35 +00:00
|
|
|
mod waitqueue;
|
2018-08-28 04:33:26 +00:00
|
|
|
|
|
|
|
pub mod alloc;
|
|
|
|
pub mod args;
|
|
|
|
pub mod cmath;
|
|
|
|
pub mod condvar;
|
|
|
|
pub mod env;
|
2018-12-25 07:41:04 +00:00
|
|
|
pub mod ext;
|
2018-09-17 23:22:59 +00:00
|
|
|
pub mod fd;
|
2020-08-20 17:45:18 +00:00
|
|
|
#[path = "../unsupported/fs.rs"]
|
2018-08-28 04:33:26 +00:00
|
|
|
pub mod fs;
|
2020-08-20 17:45:18 +00:00
|
|
|
#[path = "../unsupported/io.rs"]
|
2019-02-08 19:42:34 +00:00
|
|
|
pub mod io;
|
2018-08-28 04:33:26 +00:00
|
|
|
pub mod memchr;
|
|
|
|
pub mod mutex;
|
|
|
|
pub mod net;
|
|
|
|
pub mod os;
|
|
|
|
pub mod path;
|
2020-08-20 17:45:18 +00:00
|
|
|
#[path = "../unsupported/pipe.rs"]
|
2018-08-28 04:33:26 +00:00
|
|
|
pub mod pipe;
|
2020-08-20 17:45:18 +00:00
|
|
|
#[path = "../unsupported/process.rs"]
|
2018-08-28 04:33:26 +00:00
|
|
|
pub mod process;
|
|
|
|
pub mod rwlock;
|
2019-12-22 22:42:04 +00:00
|
|
|
pub mod stdio;
|
2018-08-28 04:33:26 +00:00
|
|
|
pub mod thread;
|
2020-07-12 09:45:04 +00:00
|
|
|
pub mod thread_local_key;
|
2018-08-28 04:33:26 +00:00
|
|
|
pub mod time;
|
|
|
|
|
2019-03-05 23:05:44 +00:00
|
|
|
pub use crate::sys_common::os_str_bytes as os_str;
|
|
|
|
|
2021-04-11 05:05:39 +00:00
|
|
|
// SAFETY: must be called only once during runtime initialization.
|
2021-04-11 21:48:10 +00:00
|
|
|
pub unsafe fn init(argc: isize, argv: *const *const u8) {
|
|
|
|
unsafe {
|
|
|
|
args::init(argc, argv);
|
|
|
|
}
|
|
|
|
}
|
2021-04-11 05:05:39 +00:00
|
|
|
|
|
|
|
// SAFETY: must be called only once during runtime cleanup.
|
|
|
|
pub unsafe fn cleanup() {}
|
2018-08-28 04:33:26 +00:00
|
|
|
|
|
|
|
/// This function is used to implement functionality that simply doesn't exist.
|
|
|
|
/// Programs relying on this functionality will need to deal with the error.
|
2019-02-10 19:23:21 +00:00
|
|
|
pub fn unsupported<T>() -> crate::io::Result<T> {
|
2018-08-28 04:33:26 +00:00
|
|
|
Err(unsupported_err())
|
|
|
|
}
|
|
|
|
|
2019-02-10 19:23:21 +00:00
|
|
|
pub fn unsupported_err() -> crate::io::Error {
|
2021-03-19 00:39:20 +00:00
|
|
|
crate::io::Error::new_const(ErrorKind::Unsupported, &"operation not supported on SGX yet")
|
2018-08-28 04:33:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// This function is used to implement various functions that doesn't exist,
|
|
|
|
/// but the lack of which might not be reason for error. If no error is
|
|
|
|
/// returned, the program might very well be able to function normally. This is
|
|
|
|
/// what happens when `SGX_INEFFECTIVE_ERROR` is set to `true`. If it is
|
|
|
|
/// `false`, the behavior is the same as `unsupported`.
|
2019-02-10 19:23:21 +00:00
|
|
|
pub fn sgx_ineffective<T>(v: T) -> crate::io::Result<T> {
|
2018-08-28 04:33:26 +00:00
|
|
|
static SGX_INEFFECTIVE_ERROR: AtomicBool = AtomicBool::new(false);
|
|
|
|
if SGX_INEFFECTIVE_ERROR.load(Ordering::Relaxed) {
|
2021-03-21 19:22:38 +00:00
|
|
|
Err(crate::io::Error::new_const(
|
2019-12-22 22:42:04 +00:00
|
|
|
ErrorKind::Other,
|
2021-03-21 19:22:38 +00:00
|
|
|
&"operation can't be trusted to have any effect on SGX",
|
2019-12-22 22:42:04 +00:00
|
|
|
))
|
2018-08-28 04:33:26 +00:00
|
|
|
} else {
|
|
|
|
Ok(v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-10 19:23:21 +00:00
|
|
|
pub fn decode_error_kind(code: i32) -> ErrorKind {
|
2018-08-28 04:33:26 +00:00
|
|
|
use fortanix_sgx_abi::Error;
|
|
|
|
|
|
|
|
// FIXME: not sure how to make sure all variants of Error are covered
|
|
|
|
if code == Error::NotFound as _ {
|
2019-02-10 19:23:21 +00:00
|
|
|
ErrorKind::NotFound
|
2018-08-28 04:33:26 +00:00
|
|
|
} else if code == Error::PermissionDenied as _ {
|
2019-02-10 19:23:21 +00:00
|
|
|
ErrorKind::PermissionDenied
|
2018-08-28 04:33:26 +00:00
|
|
|
} else if code == Error::ConnectionRefused as _ {
|
2019-02-10 19:23:21 +00:00
|
|
|
ErrorKind::ConnectionRefused
|
2018-08-28 04:33:26 +00:00
|
|
|
} else if code == Error::ConnectionReset as _ {
|
2019-02-10 19:23:21 +00:00
|
|
|
ErrorKind::ConnectionReset
|
2018-08-28 04:33:26 +00:00
|
|
|
} else if code == Error::ConnectionAborted as _ {
|
2019-02-10 19:23:21 +00:00
|
|
|
ErrorKind::ConnectionAborted
|
2018-08-28 04:33:26 +00:00
|
|
|
} else if code == Error::NotConnected as _ {
|
2019-02-10 19:23:21 +00:00
|
|
|
ErrorKind::NotConnected
|
2018-08-28 04:33:26 +00:00
|
|
|
} else if code == Error::AddrInUse as _ {
|
2019-02-10 19:23:21 +00:00
|
|
|
ErrorKind::AddrInUse
|
2018-08-28 04:33:26 +00:00
|
|
|
} else if code == Error::AddrNotAvailable as _ {
|
2019-02-10 19:23:21 +00:00
|
|
|
ErrorKind::AddrNotAvailable
|
2018-08-28 04:33:26 +00:00
|
|
|
} else if code == Error::BrokenPipe as _ {
|
2019-02-10 19:23:21 +00:00
|
|
|
ErrorKind::BrokenPipe
|
2018-08-28 04:33:26 +00:00
|
|
|
} else if code == Error::AlreadyExists as _ {
|
2019-02-10 19:23:21 +00:00
|
|
|
ErrorKind::AlreadyExists
|
2018-08-28 04:33:26 +00:00
|
|
|
} else if code == Error::WouldBlock as _ {
|
2019-02-10 19:23:21 +00:00
|
|
|
ErrorKind::WouldBlock
|
2018-08-28 04:33:26 +00:00
|
|
|
} else if code == Error::InvalidInput as _ {
|
2019-02-10 19:23:21 +00:00
|
|
|
ErrorKind::InvalidInput
|
2018-08-28 04:33:26 +00:00
|
|
|
} else if code == Error::InvalidData as _ {
|
2019-02-10 19:23:21 +00:00
|
|
|
ErrorKind::InvalidData
|
2018-08-28 04:33:26 +00:00
|
|
|
} else if code == Error::TimedOut as _ {
|
2019-02-10 19:23:21 +00:00
|
|
|
ErrorKind::TimedOut
|
2018-08-28 04:33:26 +00:00
|
|
|
} else if code == Error::WriteZero as _ {
|
2019-02-10 19:23:21 +00:00
|
|
|
ErrorKind::WriteZero
|
2018-08-28 04:33:26 +00:00
|
|
|
} else if code == Error::Interrupted as _ {
|
2019-02-10 19:23:21 +00:00
|
|
|
ErrorKind::Interrupted
|
2018-08-28 04:33:26 +00:00
|
|
|
} else if code == Error::Other as _ {
|
2019-02-10 19:23:21 +00:00
|
|
|
ErrorKind::Other
|
2018-08-28 04:33:26 +00:00
|
|
|
} else if code == Error::UnexpectedEof as _ {
|
2019-02-10 19:23:21 +00:00
|
|
|
ErrorKind::UnexpectedEof
|
2018-08-28 04:33:26 +00:00
|
|
|
} else {
|
2019-02-10 19:23:21 +00:00
|
|
|
ErrorKind::Other
|
2018-08-28 04:33:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub unsafe fn strlen(mut s: *const c_char) -> usize {
|
|
|
|
let mut n = 0;
|
2020-09-29 20:27:56 +00:00
|
|
|
while unsafe { *s } != 0 {
|
2018-08-28 04:33:26 +00:00
|
|
|
n += 1;
|
2020-09-29 20:27:56 +00:00
|
|
|
s = unsafe { s.offset(1) };
|
2018-08-28 04:33:26 +00:00
|
|
|
}
|
2019-12-22 22:42:04 +00:00
|
|
|
return n;
|
2018-08-28 04:33:26 +00:00
|
|
|
}
|
|
|
|
|
2020-05-17 17:37:44 +00:00
|
|
|
pub fn abort_internal() -> ! {
|
2019-02-06 16:58:45 +00:00
|
|
|
abi::usercalls::exit(true)
|
2018-08-28 04:33:26 +00:00
|
|
|
}
|
|
|
|
|
2019-04-02 00:41:37 +00:00
|
|
|
// This function is needed by the panic runtime. The symbol is named in
|
|
|
|
// pre-link args for the target specification, so keep that in sync.
|
|
|
|
#[cfg(not(test))]
|
|
|
|
#[no_mangle]
|
|
|
|
// NB. used by both libunwind and libpanic_abort
|
2020-05-17 17:37:44 +00:00
|
|
|
pub extern "C" fn __rust_abort() {
|
2019-04-02 00:41:37 +00:00
|
|
|
abort_internal();
|
|
|
|
}
|
|
|
|
|
2020-06-12 00:44:21 +00:00
|
|
|
pub mod rand {
|
|
|
|
pub fn rdrand64() -> u64 {
|
2018-08-28 04:33:26 +00:00
|
|
|
unsafe {
|
2019-07-05 16:03:49 +00:00
|
|
|
let mut ret: u64 = 0;
|
2018-08-28 04:33:26 +00:00
|
|
|
for _ in 0..10 {
|
2019-02-10 19:23:21 +00:00
|
|
|
if crate::arch::x86_64::_rdrand64_step(&mut ret) == 1 {
|
2018-08-28 04:33:26 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
2019-02-17 10:01:46 +00:00
|
|
|
rtabort!("Failed to obtain random data");
|
2018-08-28 04:33:26 +00:00
|
|
|
}
|
|
|
|
}
|
2020-06-12 00:44:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn hashmap_random_keys() -> (u64, u64) {
|
|
|
|
(self::rand::rdrand64(), self::rand::rdrand64())
|
2018-08-28 04:33:26 +00:00
|
|
|
}
|
2018-12-25 07:41:04 +00:00
|
|
|
|
2019-02-10 19:23:21 +00:00
|
|
|
pub use crate::sys_common::{AsInner, FromInner, IntoInner};
|
2018-12-25 07:41:04 +00:00
|
|
|
|
|
|
|
pub trait TryIntoInner<Inner>: Sized {
|
|
|
|
fn try_into_inner(self) -> Result<Inner, Self>;
|
|
|
|
}
|