Skip to content
This repository has been archived by the owner on Oct 26, 2021. It is now read-only.

WIP: fd validation #305

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions internal/shim-sev/src/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::shim_stack::init_stack_with_guard;
use crate::usermode::usermode;
use crate::{BOOT_INFO, PAYLOAD_READY};

use crate::spin::RWLocked;
use core::ops::DerefMut;
use core::sync::atomic::Ordering;
use crt0stack::{self, Builder, Entry};
Expand Down Expand Up @@ -63,6 +64,22 @@ pub static NEXT_MMAP_RWLOCK: Lazy<RwLock<VirtAddr>> = Lazy::new(|| {
RwLock::<VirtAddr>::const_new(spinning::RawRwLock::const_new(), mmap_start)
});

/// The process context
pub struct ProcessContext {
/// used file handles, one bit per fd, up to 65536
pub files: [u8; 8192],
}

/// The process context global variable
pub static PROCESS_CONTEXT: Lazy<RWLocked<ProcessContext>> = Lazy::new(|| {
let mut ctx = ProcessContext { files: [0u8; 8192] };

// FIXME: might want to remove in the future
ctx.files[0] = 7; // validate fd 0, 1, 2

RWLocked::new(ctx)
});

/// load the elf binary
fn map_elf(app_virt_start: VirtAddr) -> &'static Header {
let (code_start, code_end) = {
Expand Down
53 changes: 51 additions & 2 deletions internal/shim-sev/src/syscall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ use crate::attestation::SEV_SECRET;
use crate::eprintln;
use crate::hostcall::{HostCall, HOST_CALL_ALLOC};
use crate::paging::SHIM_PAGETABLE;
use crate::payload::{NEXT_BRK_RWLOCK, NEXT_MMAP_RWLOCK};
use crate::payload::{NEXT_BRK_RWLOCK, NEXT_MMAP_RWLOCK, PROCESS_CONTEXT};
use core::convert::TryFrom;
use core::mem::size_of;
use core::ops::{Deref, DerefMut};
use primordial::{Address, Register};
use sallyport::{Cursor, Request};
use syscall::{
BaseSyscallHandler, EnarxSyscallHandler, FileSyscallHandler, MemorySyscallHandler,
BaseSyscallHandler, EnarxSyscallHandler, FdHandler, FileSyscallHandler, MemorySyscallHandler,
NetworkSyscallHandler, ProcessSyscallHandler, SyscallHandler, SystemSyscallHandler,
ARCH_GET_FS, ARCH_GET_GS, ARCH_SET_FS, ARCH_SET_GS, SEV_TECH,
};
Expand Down Expand Up @@ -171,6 +171,55 @@ impl SystemSyscallHandler for Handler {}
impl NetworkSyscallHandler for Handler {}
impl FileSyscallHandler for Handler {}

impl FdHandler for Handler {
fn fd_register(&mut self, fd: i32) {
let i: usize = (fd / 8) as _;
let b: u8 = 1u8 << (fd % 8);

let mut context = PROCESS_CONTEXT.write();

if context.files[i] & b != 0 {
panic!("Register already registered fd")
}

context.files[i] = context.files[i] | b;
}

fn fd_unregister(&mut self, fd: i32) {
let i: usize = (fd / 8) as _;
let b: u8 = 1u8 << (fd % 8);

let mut context = PROCESS_CONTEXT.write();

if context.files[i] & b == 0 {
panic!("Unregister not registered fd")
}

context.files[i] = context.files[i] & (!b);
}

fn fd_is_valid(&mut self, fd: i32) -> sallyport::Result {
let i: usize = (fd / 8) as _;
let b: u8 = 1u8 << (fd % 8);

let context = PROCESS_CONTEXT.read();

if context.files[i] & b == 0 {
return Err(libc::EBADFD);
}

Ok(Default::default())
}

fn fd_epoll_ctl(&mut self, epfd: i32, op: i32, fd: i32, event: libc::epoll_event) {
unimplemented!()
}

fn fd_get_epoll_event_data(&mut self, epfd: i32, fd: i32) -> u64 {
unimplemented!()
}
}

impl BaseSyscallHandler for Handler {
fn unknown_syscall(
&mut self,
Expand Down
25 changes: 25 additions & 0 deletions internal/shim-sgx/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions internal/shim-sgx/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ nbytes = "0.1"
lset = "0.1"
xsave = "0.1.1"
const-default = { version = "0.1" }
spinning = { version = "0.1", default-features = false }

[profile.dev.package.rcrt1]
opt-level = 3
Expand Down
69 changes: 68 additions & 1 deletion internal/shim-sgx/src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ use sgx::{
},
};
use sgx_heap::Heap;
use spinning::Lazy;
use syscall::{
BaseSyscallHandler, EnarxSyscallHandler, FileSyscallHandler, MemorySyscallHandler,
BaseSyscallHandler, EnarxSyscallHandler, FdHandler, FileSyscallHandler, MemorySyscallHandler,
NetworkSyscallHandler, ProcessSyscallHandler, SyscallHandler, SystemSyscallHandler,
ARCH_GET_FS, ARCH_GET_GS, ARCH_SET_FS, ARCH_SET_GS, SGX_DUMMY_QUOTE, SGX_DUMMY_TI,
SGX_QUOTE_SIZE, SGX_TECH, SYS_ENARX_CPUID, SYS_ENARX_GETATT,
Expand All @@ -27,6 +28,7 @@ use untrusted::{AddressValidator, UntrustedRef, UntrustedRefMut, ValidateSlice};

pub const TRACE: bool = false;
use crate::enclave::{syscall, Context};
use crate::spin::RWLocked;

pub struct Handler<'a> {
pub aex: &'a mut StateSaveArea,
Expand Down Expand Up @@ -126,6 +128,71 @@ impl<'a> SyscallHandler for Handler<'a> {}
impl<'a> SystemSyscallHandler for Handler<'a> {}
impl<'a> NetworkSyscallHandler for Handler<'a> {}

/// The process context
pub struct ProcessContext {
/// used file handles, one bit per fd, up to 65536
pub files: [u8; 8192],
}

/// The process context global variable
pub static PROCESS_CONTEXT: Lazy<RWLocked<ProcessContext>> = Lazy::new(|| {
let mut ctx = ProcessContext { files: [0u8; 8192] };

// FIXME: might want to remove in the future
ctx.files[0] = 7; // validate fd 0, 1, 2

RWLocked::new(ctx)
});

impl<'a> FdHandler for Handler<'a> {
fn fd_register(&mut self, fd: i32) {
let i: usize = (fd / 8) as _;
let b: u8 = 1u8 << (fd % 8);

let mut context = PROCESS_CONTEXT.write();

if context.files[i] & b != 0 {
panic!("Register already registered fd")
}

context.files[i] = context.files[i] | b;
}

fn fd_unregister(&mut self, fd: i32) {
let i: usize = (fd / 8) as _;
let b: u8 = 1u8 << (fd % 8);

let mut context = PROCESS_CONTEXT.write();

if context.files[i] & b == 0 {
panic!("Unregister not registered fd")
}

context.files[i] = context.files[i] & (!b);
}

fn fd_is_valid(&mut self, fd: i32) -> sallyport::Result {
let i: usize = (fd / 8) as _;
let b: u8 = 1u8 << (fd % 8);

let context = PROCESS_CONTEXT.read();

if context.files[i] & b == 0 {
return Err(libc::EBADFD);
}

Ok(Default::default())
}

fn fd_epoll_ctl(&mut self, epfd: i32, op: i32, fd: i32, event: libc::epoll_event) {
unimplemented!()
}

fn fd_get_epoll_event_data(&mut self, epfd: i32, fd: i32) -> u64 {
unimplemented!()
}
}

impl<'a> BaseSyscallHandler for Handler<'a> {
fn translate_shim_to_host_addr<T>(buf: *const T) -> usize {
buf as _
Expand Down
1 change: 1 addition & 0 deletions internal/shim-sgx/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,6 @@ mod entry;
mod event;
mod handler;
mod hostlib;
mod spin;

use hostlib::Layout;
55 changes: 55 additions & 0 deletions internal/shim-sgx/src/spin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// SPDX-License-Identifier: Apache-2.0

//! wrapper around spinning types to permit trait implementations.

#![allow(dead_code)]

use spinning::{Mutex, MutexGuard, RawMutex, RawRwLock, RwLock, RwLockReadGuard, RwLockWriteGuard};

/// A wrapper around spinning::Mutex to permit trait implementations.
pub struct Locked<A> {
inner: Mutex<A>,
}

impl<A> Locked<A> {
/// Constructor
#[inline]
pub const fn new(inner: A) -> Self {
Self {
inner: Mutex::const_new(RawMutex::const_new(), inner),
}
}

/// get a [`MutexGuard`](spinning::MutexGuard)
#[inline]
pub fn lock(&self) -> MutexGuard<A> {
self.inner.lock()
}
}

/// A wrapper around spinning::RwLock to permit trait implementations.
pub struct RWLocked<A> {
inner: RwLock<A>,
}

impl<A> RWLocked<A> {
/// Constructor
#[inline]
pub const fn new(inner: A) -> Self {
Self {
inner: RwLock::const_new(RawRwLock::const_new(), inner),
}
}

/// get a [`RwLockReadGuard`](spinning::RwLockReadGuard)
#[inline]
pub fn read(&self) -> RwLockReadGuard<A> {
self.inner.read()
}

/// get a [`RwLockWriteGuard`](spinning::RwLockWriteGuard)
#[inline]
pub fn write(&self) -> RwLockWriteGuard<A> {
self.inner.write()
}
}
31 changes: 31 additions & 0 deletions internal/syscall/src/fdhandle.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// SPDX-License-Identifier: Apache-2.0

//! internal fd book keeping

use sallyport::Result;

/// internal fd book keeping
pub trait FdHandler {
/// register a valid fd
fn fd_register(&mut self, fd: libc::c_int);

/// unregister a valid fd
fn fd_unregister(&mut self, fd: libc::c_int);

/// check, if an fd is valid
///
/// returns `Err(libc::EBADFD)` if not
fn fd_is_valid(&mut self, fd: libc::c_int) -> Result;

/// shadow epoll_ctl
fn fd_epoll_ctl(
&mut self,
epfd: libc::c_int,
op: libc::c_int,
fd: libc::c_int,
event: libc::epoll_event,
);

/// get the event data for an fd
fn fd_get_epoll_event_data(&mut self, epfd: libc::c_int, fd: libc::c_int) -> u64;
}
Loading