Fix not passing null pointers to ocalls for empty slices

It gets a non-null fat pointer when an empty slice simply calls as_ptr
or as_mut_ptr.
This commit is contained in:
He Sun 2020-04-26 14:51:37 +08:00 committed by Tate, Hongliang Tian
parent 58403f8415
commit e651be4403
9 changed files with 32 additions and 24 deletions

@ -9,8 +9,7 @@ extern "C" {
impl File for DevRandom { impl File for DevRandom {
fn read(&self, _buf: &mut [u8]) -> Result<usize> { fn read(&self, _buf: &mut [u8]) -> Result<usize> {
let buf = _buf.as_mut_ptr(); let (buf, size) = _buf.as_mut().as_mut_ptr_and_len();
let size = _buf.len();
let status = unsafe { sgx_read_rand(buf, size) }; let status = unsafe { sgx_read_rand(buf, size) };
if status != sgx_status_t::SGX_SUCCESS { if status != sgx_status_t::SGX_SUCCESS {
return_errno!(EAGAIN, "failed to get random number from sgx"); return_errno!(EAGAIN, "failed to get random number from sgx");

@ -47,20 +47,23 @@ impl Drop for EventFile {
impl File for EventFile { impl File for EventFile {
fn read(&self, buf: &mut [u8]) -> Result<usize> { fn read(&self, buf: &mut [u8]) -> Result<usize> {
let (buf_ptr, buf_len) = buf.as_mut().as_mut_ptr_and_len();
let ret = try_libc!(libc::ocall::read( let ret = try_libc!(libc::ocall::read(
self.host_fd, self.host_fd,
buf.as_mut_ptr() as *mut c_void, buf_ptr as *mut c_void,
buf.len() buf_len
)) as usize; )) as usize;
assert!(ret <= buf.len()); assert!(ret <= buf.len());
Ok(ret) Ok(ret)
} }
fn write(&self, buf: &[u8]) -> Result<usize> { fn write(&self, buf: &[u8]) -> Result<usize> {
let (buf_ptr, buf_len) = buf.as_ptr_and_len();
let ret = try_libc!(libc::ocall::write( let ret = try_libc!(libc::ocall::write(
self.host_fd, self.host_fd,
buf.as_ptr() as *const c_void, buf_ptr as *const c_void,
buf.len() buf_len
)) as usize; )) as usize;
assert!(ret <= buf.len()); assert!(ret <= buf.len());
Ok(ret) Ok(ret)

@ -8,6 +8,7 @@ use std::fmt;
use std::io::{Read, Seek, SeekFrom, Write}; use std::io::{Read, Seek, SeekFrom, Write};
use std::mem::MaybeUninit; use std::mem::MaybeUninit;
use std::path::Path; use std::path::Path;
use untrusted::{SliceAsMutPtrAndLen, SliceAsPtrAndLen};
pub use self::dev_fs::AsDevRandom; pub use self::dev_fs::AsDevRandom;
pub use self::event_file::{AsEvent, EventFile}; pub use self::event_file::{AsEvent, EventFile};

@ -63,9 +63,10 @@ impl StdoutRaw {
impl std::io::Write for StdoutRaw { impl std::io::Write for StdoutRaw {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> { fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
let writting_len = cmp::min(buf.len(), size_t::max_value() as usize); let writting_len = cmp::min(buf.len(), size_t::max_value() as usize);
let (buf_ptr, _) = buf.as_ptr_and_len();
let ret = try_libc_stdio!(libc::ocall::write( let ret = try_libc_stdio!(libc::ocall::write(
self.host_fd, self.host_fd,
buf.as_ptr() as *const c_void, buf_ptr as *const c_void,
writting_len, writting_len,
)) ))
.unwrap_or_else(|err| { .unwrap_or_else(|err| {
@ -220,9 +221,10 @@ impl StdinRaw {
impl std::io::Read for StdinRaw { impl std::io::Read for StdinRaw {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> { fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
let reading_len = cmp::min(buf.len(), size_t::max_value() as usize); let reading_len = cmp::min(buf.len(), size_t::max_value() as usize);
let (buf_ptr, _) = buf.as_mut().as_mut_ptr_and_len();
let ret = try_libc_stdio!(libc::ocall::read( let ret = try_libc_stdio!(libc::ocall::read(
self.host_fd, self.host_fd,
buf.as_mut_ptr() as *mut c_void, buf_ptr as *mut c_void,
reading_len, reading_len,
)) ))
.unwrap_or_else(|err| { .unwrap_or_else(|err| {

@ -53,9 +53,11 @@ pub fn do_poll(pollfds: &mut [libc::pollfd], timeout: c_int) -> Result<usize> {
} }
} }
let (u_pollfds_ptr, u_pollfds_len) = u_pollfds.as_mut_slice().as_mut_ptr_and_len();
let num_events = try_libc!(libc::ocall::poll( let num_events = try_libc!(libc::ocall::poll(
u_pollfds.as_mut_ptr(), u_pollfds_ptr,
u_pollfds.len() as u64, u_pollfds_len as u64,
timeout timeout
)) as usize; )) as usize;
assert!(num_events <= pollfds.len()); assert!(num_events <= pollfds.len());

@ -85,11 +85,8 @@ pub fn do_select(
Some(tv) => (tv.tv_sec * 1000 + tv.tv_usec / 1000) as i32, Some(tv) => (tv.tv_sec * 1000 + tv.tv_usec / 1000) as i32,
}; };
let ret = try_libc!(libc::ocall::poll( let (polls_ptr, polls_len) = polls.as_mut_slice().as_mut_ptr_and_len();
polls.as_mut_ptr(), let ret = try_libc!(libc::ocall::poll(polls_ptr, polls_len as u64, timeout));
polls.len() as u64,
timeout
));
// convert fd back and write fdset // convert fd back and write fdset
readfds.clear(); readfds.clear();

@ -1,5 +1,6 @@
use super::*; use super::*;
use std; use std;
use untrusted::{SliceAsMutPtrAndLen, SliceAsPtrAndLen, UntrustedSliceAlloc};
mod io_multiplexing; mod io_multiplexing;
mod iovs; mod iovs;

@ -45,21 +45,25 @@ impl Drop for SocketFile {
// TODO: implement readfrom/sendto // TODO: implement readfrom/sendto
impl File for SocketFile { impl File for SocketFile {
fn read(&self, buf: &mut [u8]) -> Result<usize> { fn read(&self, buf: &mut [u8]) -> Result<usize> {
let (buf_ptr, buf_len) = buf.as_mut().as_mut_ptr_and_len();
let ret = try_libc!(libc::ocall::read( let ret = try_libc!(libc::ocall::read(
self.host_fd, self.host_fd,
buf.as_mut_ptr() as *mut c_void, buf_ptr as *mut c_void,
buf.len() buf_len
)); )) as usize;
Ok(ret as usize) assert!(ret <= buf_len);
Ok(ret)
} }
fn write(&self, buf: &[u8]) -> Result<usize> { fn write(&self, buf: &[u8]) -> Result<usize> {
let (buf_ptr, buf_len) = buf.as_ptr_and_len();
let ret = try_libc!(libc::ocall::write( let ret = try_libc!(libc::ocall::write(
self.host_fd, self.host_fd,
buf.as_ptr() as *const c_void, buf_ptr as *const c_void,
buf.len() buf_len
)); )) as usize;
Ok(ret as usize) assert!(ret <= buf_len);
Ok(ret)
} }
fn read_at(&self, _offset: usize, buf: &mut [u8]) -> Result<usize> { fn read_at(&self, _offset: usize, buf: &mut [u8]) -> Result<usize> {

@ -1,5 +1,4 @@
use super::*; use super::*;
use crate::untrusted::{SliceAsMutPtrAndLen, SliceAsPtrAndLen, UntrustedSliceAlloc};
impl SocketFile { impl SocketFile {
// TODO: need sockaddr type to implement send/sento // TODO: need sockaddr type to implement send/sento