Skip to content

Commit

Permalink
Auto merge of #57119 - jethrogb:jb/sgx-os-mod2, r=joshtriplett
Browse files Browse the repository at this point in the history
Add `io` and `arch` modules to `std::os::fortanix_sgx`

This PR adds two more (unstable) modules to `std::os::fortanix_sgx` for the `x86_64-fortanix-unknown-sgx` target.

### io
`io` allows conversion between raw file descriptors and Rust types, similar to `std::os::unix::io`.

### arch
`arch` exposes the `ENCLU[EREPORT]` and `ENCLU[EGETKEY]` instructions. The current functions are very likely not going to be the final form of these functions (see also fortanix/rust-sgx#15), but this should be sufficient to enable experimentation in libraries. I tried using the actual types (from the [`sgx-isa` crate](https://crates.io/crates/sgx-isa)) instead of byte arrays, but that would make `std` dependent on the `bitflags` crate which I didn't want to do at this time.
  • Loading branch information
bors committed Dec 27, 2018
2 parents 39bc8f5 + be56561 commit d298697
Show file tree
Hide file tree
Showing 8 changed files with 307 additions and 11 deletions.
3 changes: 2 additions & 1 deletion src/libstd/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,8 @@
#![feature(alloc_layout_extra)]
#![feature(maybe_uninit)]
#![cfg_attr(target_env = "sgx", feature(global_asm, range_contains, slice_index_methods,
decl_macro, coerce_unsized, sgx_platform))]
decl_macro, coerce_unsized, sgx_platform,
min_const_unsafe_fn))]

#![default_lib_allocator]

Expand Down
2 changes: 2 additions & 0 deletions src/libstd/os/fortanix_sgx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,5 @@ pub mod usercalls {
pub mod mem {
pub use sys::abi::mem::*;
}

pub use sys::ext::{io, arch};
84 changes: 84 additions & 0 deletions src/libstd/sys/sgx/ext/arch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! SGX-specific access to architectural features.
//!
//! The functionality in this module is further documented in the Intel
//! Software Developer's Manual, Volume 3, Chapter 40.
#![unstable(feature = "sgx_platform", issue = "56975")]

use mem::MaybeUninit;

/// Wrapper struct to force 16-byte alignment.
#[repr(align(16))]
#[unstable(feature = "sgx_platform", issue = "56975")]
pub struct Align16<T>(pub T);

/// Wrapper struct to force 128-byte alignment.
#[repr(align(128))]
#[unstable(feature = "sgx_platform", issue = "56975")]
pub struct Align128<T>(pub T);

/// Wrapper struct to force 512-byte alignment.
#[repr(align(512))]
#[unstable(feature = "sgx_platform", issue = "56975")]
pub struct Align512<T>(pub T);

const ENCLU_EREPORT: u32 = 0;
const ENCLU_EGETKEY: u32 = 1;

/// Call the `EGETKEY` instruction to obtain a 128-bit secret key.
#[unstable(feature = "sgx_platform", issue = "56975")]
pub fn egetkey(request: &Align512<[u8; 512]>) -> Result<Align16<[u8; 16]>, u32> {
unsafe {
let mut out = MaybeUninit::uninitialized();
let error;

asm!(
"enclu"
: "={eax}"(error)
: "{eax}"(ENCLU_EGETKEY),
"{rbx}"(request),
"{rcx}"(out.get_mut())
: "flags"
);

match error {
0 => Ok(out.into_inner()),
err => Err(err),
}
}
}

/// Call the `EREPORT` instruction.
///
/// This creates a cryptographic report describing the contents of the current
/// enclave. The report may be verified by the enclave described in
/// `targetinfo`.
#[unstable(feature = "sgx_platform", issue = "56975")]
pub fn ereport(
targetinfo: &Align512<[u8; 512]>,
reportdata: &Align128<[u8; 64]>,
) -> Align512<[u8; 432]> {
unsafe {
let mut report = MaybeUninit::uninitialized();

asm!(
"enclu"
: /* no output registers */
: "{eax}"(ENCLU_EREPORT),
"{rbx}"(targetinfo),
"{rcx}"(reportdata),
"{rdx}"(report.get_mut())
);

report.into_inner()
}
}
119 changes: 119 additions & 0 deletions src/libstd/sys/sgx/ext/io.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! SGX-specific extensions to general I/O primitives
//!
//! SGX file descriptors behave differently from Unix file descriptors. See the
//! description of [`TryIntoRawFd`](trait.TryIntoRawFd.html) for more details.
#![unstable(feature = "sgx_platform", issue = "56975")]

pub use sys::abi::usercalls::raw::Fd as RawFd;
use net;
use sys::{self, AsInner, FromInner, IntoInner, TryIntoInner};

/// A trait to extract the raw SGX file descriptor from an underlying
/// object.
#[unstable(feature = "sgx_platform", issue = "56975")]
pub trait AsRawFd {
/// Extracts the raw file descriptor.
///
/// This method does **not** pass ownership of the raw file descriptor
/// to the caller. The descriptor is only guaranteed to be valid while
/// the original object has not yet been destroyed.
#[unstable(feature = "sgx_platform", issue = "56975")]
fn as_raw_fd(&self) -> RawFd;
}

/// A trait to express the ability to construct an object from a raw file
/// descriptor.
#[unstable(feature = "sgx_platform", issue = "56975")]
pub trait FromRawFd {
/// Constructs a new instance of `Self` from the given raw file
/// descriptor.
///
/// This function **consumes ownership** of the specified file
/// descriptor. The returned object will take responsibility for closing
/// it when the object goes out of scope.
///
/// This function is also unsafe as the primitives currently returned
/// have the contract that they are the sole owner of the file
/// descriptor they are wrapping. Usage of this function could
/// accidentally allow violating this contract which can cause memory
/// unsafety in code that relies on it being true.
#[unstable(feature = "sgx_platform", issue = "56975")]
unsafe fn from_raw_fd(fd: RawFd) -> Self;
}

/// A trait to express the ability to consume an object and acquire ownership of
/// its raw file descriptor.
#[unstable(feature = "sgx_platform", issue = "56975")]
pub trait TryIntoRawFd: Sized {
/// Consumes this object, returning the raw underlying file descriptor, if
/// this object is not cloned.
///
/// This function **transfers ownership** of the underlying file descriptor
/// to the caller. Callers are then the unique owners of the file descriptor
/// and must close the descriptor once it's no longer needed.
///
/// Unlike other platforms, on SGX, the file descriptor is shared between
/// all clones of an object. To avoid race conditions, this function will
/// only return `Ok` when called on the final clone.
#[unstable(feature = "sgx_platform", issue = "56975")]
fn try_into_raw_fd(self) -> Result<RawFd, Self>;
}

impl AsRawFd for net::TcpStream {
fn as_raw_fd(&self) -> RawFd { *self.as_inner().as_inner().as_inner().as_inner() }
}

impl AsRawFd for net::TcpListener {
fn as_raw_fd(&self) -> RawFd { *self.as_inner().as_inner().as_inner().as_inner() }
}

impl FromRawFd for net::TcpStream {
unsafe fn from_raw_fd(fd: RawFd) -> net::TcpStream {
let fd = sys::fd::FileDesc::from_inner(fd);
let socket = sys::net::Socket::from_inner(fd);
net::TcpStream::from_inner(sys::net::TcpStream::from_inner((socket, None)))
}
}

impl FromRawFd for net::TcpListener {
unsafe fn from_raw_fd(fd: RawFd) -> net::TcpListener {
let fd = sys::fd::FileDesc::from_inner(fd);
let socket = sys::net::Socket::from_inner(fd);
net::TcpListener::from_inner(sys::net::TcpListener::from_inner(socket))
}
}

impl TryIntoRawFd for net::TcpStream {
fn try_into_raw_fd(self) -> Result<RawFd, Self> {
let (socket, peer_addr) = self.into_inner().into_inner();
match socket.try_into_inner() {
Ok(fd) => Ok(fd.into_inner()),
Err(socket) => {
let sys = sys::net::TcpStream::from_inner((socket, peer_addr));
Err(net::TcpStream::from_inner(sys))
}
}
}
}

impl TryIntoRawFd for net::TcpListener {
fn try_into_raw_fd(self) -> Result<RawFd, Self> {
match self.into_inner().into_inner().try_into_inner() {
Ok(fd) => Ok(fd.into_inner()),
Err(socket) => {
let sys = sys::net::TcpListener::from_inner(socket);
Err(net::TcpListener::from_inner(sys))
}
}
}
}
14 changes: 14 additions & 0 deletions src/libstd/sys/sgx/ext/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![unstable(feature = "sgx_platform", issue = "56975")]

pub mod arch;
pub mod io;
16 changes: 15 additions & 1 deletion src/libstd/sys/sgx/fd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use fortanix_sgx_abi::Fd;

use io;
use mem;
use sys_common::AsInner;
use sys::{AsInner, FromInner, IntoInner};
use super::abi::usercalls;

#[derive(Debug)]
Expand Down Expand Up @@ -41,6 +41,20 @@ impl AsInner<Fd> for FileDesc {
fn as_inner(&self) -> &Fd { &self.fd }
}

impl IntoInner<Fd> for FileDesc {
fn into_inner(self) -> Fd {
let fd = self.fd;
mem::forget(self);
fd
}
}

impl FromInner<Fd> for FileDesc {
fn from_inner(fd: Fd) -> FileDesc {
FileDesc { fd }
}
}

impl Drop for FileDesc {
fn drop(&mut self) {
usercalls::close(self.fd)
Expand Down
7 changes: 7 additions & 0 deletions src/libstd/sys/sgx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub mod backtrace;
pub mod cmath;
pub mod condvar;
pub mod env;
pub mod ext;
pub mod fd;
pub mod fs;
pub mod memchr;
Expand Down Expand Up @@ -141,3 +142,9 @@ pub fn hashmap_random_keys() -> (u64, u64) {
}
(rdrand64(), rdrand64())
}

pub use sys_common::{AsInner, FromInner, IntoInner};

pub trait TryIntoInner<Inner>: Sized {
fn try_into_inner(self) -> Result<Inner, Self>;
}
Loading

0 comments on commit d298697

Please sign in to comment.