fix memory access in WasmPtr

This commit is contained in:
Mark McCaskey
2019-04-18 17:48:14 -07:00
parent 7e58c4258c
commit 19e830d25a
4 changed files with 71 additions and 28 deletions

View File

@ -36,10 +36,11 @@ impl<T: Copy + ValueType> WasmPtr<T, Item> {
return Err(__WASI_EFAULT); return Err(__WASI_EFAULT);
} }
unsafe { unsafe {
let cell_ptr = memory let aligner = |ptr: usize, align: usize| ptr & !(align - 1);
.view::<T>() let cell_ptr = aligner(
.get_unchecked((self.offset() as usize) / mem::size_of::<T>()) memory.view::<u8>().as_ptr().add(self.offset as usize) as usize,
as *const _; mem::align_of::<T>(),
) as *const Cell<T>;
Ok(&*cell_ptr) Ok(&*cell_ptr)
} }
} }

View File

@ -16,6 +16,7 @@ use zbox::{init_env as zbox_init_env, FileType, OpenOptions, Repo, RepoOpener};
pub const MAX_SYMLINKS: usize = 100; pub const MAX_SYMLINKS: usize = 100;
#[derive(Debug)]
pub enum WasiFile { pub enum WasiFile {
ZboxFile(zbox::File), ZboxFile(zbox::File),
HostFile(fs::File), HostFile(fs::File),
@ -90,6 +91,7 @@ impl Seek for WasiFile {
} }
} }
#[derive(Debug)]
pub struct InodeVal { pub struct InodeVal {
pub stat: __wasi_filestat_t, pub stat: __wasi_filestat_t,
pub is_preopened: bool, pub is_preopened: bool,
@ -98,6 +100,7 @@ pub struct InodeVal {
} }
#[allow(dead_code)] #[allow(dead_code)]
#[derive(Debug)]
pub enum Kind { pub enum Kind {
File { File {
handle: WasiFile, handle: WasiFile,
@ -155,9 +158,13 @@ impl WasiFs {
for file in preopened_files { for file in preopened_files {
debug!("Attempting to preopen {}", &file); debug!("Attempting to preopen {}", &file);
// TODO: think about this // TODO: think about this
let default_rights = 0x1FFFFFFF; let default_rights = 0x1FFFFFFF; // all rights
let cur_file: fs::File = fs::File::open(file).expect("Could not find file"); let cur_file: fs::File = fs::OpenOptions::new()
let kind = if cur_file.metadata().unwrap().is_dir() { .read(true)
.open(file)
.expect("Could not find file");
let cur_file_metadata = cur_file.metadata().unwrap();
let kind = if cur_file_metadata.is_dir() {
// it seems bad to open every file recursively; can do it lazily though // it seems bad to open every file recursively; can do it lazily though
Kind::Dir { Kind::Dir {
handle: WasiFile::HostFile(cur_file), handle: WasiFile::HostFile(cur_file),
@ -173,13 +180,36 @@ impl WasiFs {
)); ));
}; };
let inode_val = InodeVal { let inode_val = InodeVal {
stat: __wasi_filestat_t::default(), stat: __wasi_filestat_t {
st_filetype: __WASI_FILETYPE_DIRECTORY,
st_size: cur_file_metadata.len(),
st_atim: cur_file_metadata
.accessed()
.ok()
.and_then(|sys_time| sys_time.duration_since(SystemTime::UNIX_EPOCH).ok())
.map(|duration| duration.as_nanos() as u64)
.unwrap_or(0),
st_ctim: cur_file_metadata
.created()
.ok()
.and_then(|sys_time| sys_time.duration_since(SystemTime::UNIX_EPOCH).ok())
.map(|duration| duration.as_nanos() as u64)
.unwrap_or(0),
st_mtim: cur_file_metadata
.modified()
.ok()
.and_then(|sys_time| sys_time.duration_since(SystemTime::UNIX_EPOCH).ok())
.map(|duration| duration.as_nanos() as u64)
.unwrap_or(0),
..__wasi_filestat_t::default()
},
is_preopened: true, is_preopened: true,
// this is incorrect // this is incorrect
name: file.clone(), name: file.clone(),
kind, kind,
}; };
let inode = wasi_fs.inodes.insert(inode_val); let inode = wasi_fs.inodes.insert(inode_val);
wasi_fs.inodes[inode].stat.st_ino = wasi_fs.inode_counter.get();
wasi_fs wasi_fs
.create_fd(default_rights, default_rights, 0, inode) .create_fd(default_rights, default_rights, 0, inode)
.expect("Could not open fd"); .expect("Could not open fd");
@ -304,7 +334,7 @@ impl WasiFs {
debug!("fdstat: {:?}", fd); debug!("fdstat: {:?}", fd);
dbg!(Ok(__wasi_fdstat_t { Ok(__wasi_fdstat_t {
fs_filetype: match self.inodes[fd.inode].kind { fs_filetype: match self.inodes[fd.inode].kind {
Kind::File { .. } => __WASI_FILETYPE_REGULAR_FILE, Kind::File { .. } => __WASI_FILETYPE_REGULAR_FILE,
Kind::Dir { .. } => __WASI_FILETYPE_DIRECTORY, Kind::Dir { .. } => __WASI_FILETYPE_DIRECTORY,
@ -313,8 +343,8 @@ impl WasiFs {
}, },
fs_flags: fd.flags, fs_flags: fd.flags,
fs_rights_base: fd.rights, fs_rights_base: fd.rights,
fs_rights_inheriting: fd.rights, // TODO(lachlan): Is this right? fs_rights_inheriting: fd.rights_inheriting, // TODO(lachlan): Is this right?
})) })
} }
pub fn prestat_fd(&self, fd: __wasi_fd_t) -> Result<__wasi_prestat_t, __wasi_errno_t> { pub fn prestat_fd(&self, fd: __wasi_fd_t) -> Result<__wasi_prestat_t, __wasi_errno_t> {
@ -327,7 +357,8 @@ impl WasiFs {
Ok(__wasi_prestat_t { Ok(__wasi_prestat_t {
pr_type: __WASI_PREOPENTYPE_DIR, pr_type: __WASI_PREOPENTYPE_DIR,
u: PrestatEnum::Dir { u: PrestatEnum::Dir {
pr_name_len: inode_val.name.len() as u32, // REVIEW:
pr_name_len: inode_val.name.len() as u32 + 1,
} }
.untagged(), .untagged(),
}) })

View File

@ -324,15 +324,18 @@ pub fn fd_datasync(ctx: &mut Ctx, fd: __wasi_fd_t) -> __wasi_errno_t {
pub fn fd_fdstat_get( pub fn fd_fdstat_get(
ctx: &mut Ctx, ctx: &mut Ctx,
fd: __wasi_fd_t, fd: __wasi_fd_t,
buf: WasmPtr<__wasi_fdstat_t>, buf_ptr: WasmPtr<__wasi_fdstat_t>,
) -> __wasi_errno_t { ) -> __wasi_errno_t {
debug!("wasi::fd_fdstat_get: fd={}", fd); debug!(
"wasi::fd_fdstat_get: fd={}, buf_ptr={}",
fd,
buf_ptr.offset()
);
let mut state = get_wasi_state(ctx); let mut state = get_wasi_state(ctx);
let memory = ctx.memory(0); let memory = ctx.memory(0);
let stat = wasi_try!(state.fs.fdstat(fd)); let stat = wasi_try!(state.fs.fdstat(fd));
let buf = wasi_try!(buf_ptr.deref(memory));
let buf = wasi_try!(buf.deref(memory));
buf.set(stat); buf.set(stat);
__WASI_ESUCCESS __WASI_ESUCCESS
@ -543,9 +546,19 @@ pub fn fd_prestat_dir_name(
if let Kind::Dir { .. } = inode_val.kind { if let Kind::Dir { .. } = inode_val.kind {
// TODO: verify this: null termination, etc // TODO: verify this: null termination, etc
if inode_val.name.len() <= path_len as usize { if inode_val.name.len() <= path_len as usize {
for (i, c) in inode_val.name.bytes().enumerate() { let mut i = 0;
for c in inode_val.name.bytes() {
path_chars[i].set(c); path_chars[i].set(c);
i += 1
} }
path_chars[i].set(0);
debug!(
"=> result: \"{}\"",
::std::str::from_utf8(unsafe { &*(&path_chars[..] as *const [_] as *const [u8]) })
.unwrap()
);
__WASI_ESUCCESS __WASI_ESUCCESS
} else { } else {
__WASI_EOVERFLOW __WASI_EOVERFLOW
@ -669,13 +682,10 @@ pub fn fd_read(
for iov in iovs_arr_cell { for iov in iovs_arr_cell {
let iov_inner = iov.get(); let iov_inner = iov.get();
let bytes = iov_inner.buf.deref(memory, 0, dbg!(iov_inner.buf_len))?; let bytes = iov_inner.buf.deref(memory, 0, iov_inner.buf_len)?;
let mut raw_bytes: &mut [u8] = let mut raw_bytes: &mut [u8] =
unsafe { &mut *(bytes as *const [_] as *mut [_] as *mut [u8]) }; unsafe { &mut *(bytes as *const [_] as *mut [_] as *mut [u8]) };
bytes_read += dbg!(reader.read(raw_bytes).map_err(|e| { bytes_read += reader.read(raw_bytes).map_err(|e| __WASI_EIO)? as u32;
dbg!(e);
__WASI_EIO
})? as u32);
} }
Ok(bytes_read) Ok(bytes_read)
} }
@ -722,7 +732,7 @@ pub fn fd_read(
} }
}; };
nread_cell.set(dbg!(bytes_read)); nread_cell.set(bytes_read);
__WASI_ESUCCESS __WASI_ESUCCESS
} }
@ -819,7 +829,7 @@ pub fn fd_seek(
// TODO: handle case if fd is a dir? // TODO: handle case if fd is a dir?
match whence { match whence {
__WASI_WHENCE_CUR => fd_entry.offset = (dbg!(fd_entry.offset) as i64 + offset) as u64, __WASI_WHENCE_CUR => fd_entry.offset = (fd_entry.offset as i64 + offset) as u64,
__WASI_WHENCE_END => unimplemented!(), __WASI_WHENCE_END => unimplemented!(),
__WASI_WHENCE_SET => fd_entry.offset = offset as u64, __WASI_WHENCE_SET => fd_entry.offset = offset as u64,
_ => return __WASI_EINVAL, _ => return __WASI_EINVAL,
@ -838,7 +848,7 @@ pub fn fd_seek(
/// Errors: /// Errors:
/// TODO: figure out which errors this should return /// TODO: figure out which errors this should return
/// - `__WASI_EPERM` /// - `__WASI_EPERM`
/// - `__WAIS_ENOTCAPABLE` /// - `__WASI_ENOTCAPABLE`
pub fn fd_sync(ctx: &mut Ctx, fd: __wasi_fd_t) -> __wasi_errno_t { pub fn fd_sync(ctx: &mut Ctx, fd: __wasi_fd_t) -> __wasi_errno_t {
debug!("wasi::fd_sync"); debug!("wasi::fd_sync");
// TODO: check __WASI_RIGHT_FD_SYNC // TODO: check __WASI_RIGHT_FD_SYNC
@ -949,7 +959,7 @@ pub fn fd_write(
} }
}; };
nwritten_cell.set(dbg!(bytes_written)); nwritten_cell.set(bytes_written);
__WASI_ESUCCESS __WASI_ESUCCESS
} }
@ -1042,7 +1052,9 @@ pub fn path_filestat_get(
return __WASI_ELOOP; return __WASI_ELOOP;
} }
} }
_ => return __WASI_ENOTDIR, _ => {
return __WASI_ENOTDIR;
}
} }
} }
} }

View File

@ -123,7 +123,6 @@ impl FromStr for Backend {
_ => Err(format!("The backend {} doesn't exist", s)), _ => Err(format!("The backend {} doesn't exist", s)),
} }
} }
>>>>>>> origin/master
} }
#[derive(Debug, StructOpt)] #[derive(Debug, StructOpt)]