Skip to content

Commit

Permalink
Add the writev() syscall handler
Browse files Browse the repository at this point in the history
  • Loading branch information
lkatalin committed Apr 2, 2020
1 parent 204a4ce commit 9b839f2
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 0 deletions.
1 change: 1 addition & 0 deletions enarx-keep-sgx-shim/src/event.rs
Expand Up @@ -26,6 +26,7 @@ pub extern "C" fn event(
SysCall::READ => h.read(),
SysCall::READV => h.readv(),
SysCall::WRITE => h.write(),
SysCall::WRITEV => h.writev(),
SysCall::GETUID => h.getuid(),
SysCall::EXIT => h.exit(None),
_ => h.exit(254),
Expand Down
63 changes: 63 additions & 0 deletions enarx-keep-sgx-shim/src/handler.rs
Expand Up @@ -254,4 +254,67 @@ impl<'a> Handler<'a> {
unsafe { self.ufree(map.as_ptr() as *mut u8, size as u64) };
ret
}

/// Do a writev() syscall
pub fn writev(&mut self) -> u64 {
let fd = self.aex.gpr.rdi;
let trusted = unsafe {
from_raw_parts_mut(self.aex.gpr.rsi as *mut Iovec, self.aex.gpr.rdx as usize)
};

// Add up total size of buffers and size of iovec array.
let bufsize = trusted.iter().fold(0, |a, e| a + e.size);
let iovecsize = size_of::<Iovec>() * trusted.len();
let size = bufsize + iovecsize;

// Allocate some unencrypted memory.
let map = match self.ualloc(size as u64) {
Err(errno) => return errno.into_syscall(),
Ok(map) => unsafe { from_raw_parts_mut(map, size as usize) },
};

// Split allocated memory into that used by the iovec struct array
// and that used by its buffers.
let (uiovec, ubuffer) = map.split_at_mut(iovecsize);

// Convert the prefix from a byte slice into an iovec slice.
let (_, untrusted, _) = unsafe { uiovec.align_to_mut::<Iovec>() };
if untrusted.len() != trusted.len() {
self.attacked();
}

// Set pointers in unencrypted iovec slice to use the rest
// of the allocated memory, then copy the encrypted input
// into unencrypted memory. The offset is into the buffer
// area allocated immediately after the iovec struct array,
// measured in bytes.
let mut offset = 0;
for (t, mut u) in trusted.iter_mut().zip(untrusted.iter_mut()) {
u.base = ubuffer[offset..].as_mut_ptr();
u.size = t.size;
u.as_mut().copy_from_slice(t.as_ref());
offset += t.size;
}

// Do the syscall; replace encrypted memory with unencrypted memory.
let ret = unsafe {
self.syscall(
SysCall::WRITEV,
fd,
untrusted.as_ptr() as _,
untrusted.len() as u64,
0,
0,
0,
)
};

unsafe { self.ufree(map.as_ptr() as *mut u8, size as u64) };

if ErrNo::from_syscall(ret).is_none() && ret > size as u64 {
self.attacked()
}

ret
}
}

0 comments on commit 9b839f2

Please sign in to comment.