From 19e830d25a193dfbdc190e4d187f22f9dd458217 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Thu, 18 Apr 2019 17:48:14 -0700 Subject: [PATCH] fix memory access in WasmPtr --- lib/wasi/src/ptr.rs | 9 ++++--- lib/wasi/src/state.rs | 47 ++++++++++++++++++++++++++++++------ lib/wasi/src/syscalls/mod.rs | 42 ++++++++++++++++++++------------ src/bin/wasmer.rs | 1 - 4 files changed, 71 insertions(+), 28 deletions(-) diff --git a/lib/wasi/src/ptr.rs b/lib/wasi/src/ptr.rs index da892d1bf..32c19655e 100644 --- a/lib/wasi/src/ptr.rs +++ b/lib/wasi/src/ptr.rs @@ -36,10 +36,11 @@ impl WasmPtr { return Err(__WASI_EFAULT); } unsafe { - let cell_ptr = memory - .view::() - .get_unchecked((self.offset() as usize) / mem::size_of::()) - as *const _; + let aligner = |ptr: usize, align: usize| ptr & !(align - 1); + let cell_ptr = aligner( + memory.view::().as_ptr().add(self.offset as usize) as usize, + mem::align_of::(), + ) as *const Cell; Ok(&*cell_ptr) } } diff --git a/lib/wasi/src/state.rs b/lib/wasi/src/state.rs index 43b2c9399..6cb684b85 100644 --- a/lib/wasi/src/state.rs +++ b/lib/wasi/src/state.rs @@ -16,6 +16,7 @@ use zbox::{init_env as zbox_init_env, FileType, OpenOptions, Repo, RepoOpener}; pub const MAX_SYMLINKS: usize = 100; +#[derive(Debug)] pub enum WasiFile { ZboxFile(zbox::File), HostFile(fs::File), @@ -90,6 +91,7 @@ impl Seek for WasiFile { } } +#[derive(Debug)] pub struct InodeVal { pub stat: __wasi_filestat_t, pub is_preopened: bool, @@ -98,6 +100,7 @@ pub struct InodeVal { } #[allow(dead_code)] +#[derive(Debug)] pub enum Kind { File { handle: WasiFile, @@ -155,9 +158,13 @@ impl WasiFs { for file in preopened_files { debug!("Attempting to preopen {}", &file); // TODO: think about this - let default_rights = 0x1FFFFFFF; - let cur_file: fs::File = fs::File::open(file).expect("Could not find file"); - let kind = if cur_file.metadata().unwrap().is_dir() { + let default_rights = 0x1FFFFFFF; // all rights + let cur_file: fs::File = fs::OpenOptions::new() + .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 Kind::Dir { handle: WasiFile::HostFile(cur_file), @@ -173,13 +180,36 @@ impl WasiFs { )); }; 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, // this is incorrect name: file.clone(), kind, }; let inode = wasi_fs.inodes.insert(inode_val); + wasi_fs.inodes[inode].stat.st_ino = wasi_fs.inode_counter.get(); wasi_fs .create_fd(default_rights, default_rights, 0, inode) .expect("Could not open fd"); @@ -304,7 +334,7 @@ impl WasiFs { debug!("fdstat: {:?}", fd); - dbg!(Ok(__wasi_fdstat_t { + Ok(__wasi_fdstat_t { fs_filetype: match self.inodes[fd.inode].kind { Kind::File { .. } => __WASI_FILETYPE_REGULAR_FILE, Kind::Dir { .. } => __WASI_FILETYPE_DIRECTORY, @@ -313,8 +343,8 @@ impl WasiFs { }, fs_flags: fd.flags, 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> { @@ -327,7 +357,8 @@ impl WasiFs { Ok(__wasi_prestat_t { pr_type: __WASI_PREOPENTYPE_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(), }) diff --git a/lib/wasi/src/syscalls/mod.rs b/lib/wasi/src/syscalls/mod.rs index 45b626346..2416b3a7a 100644 --- a/lib/wasi/src/syscalls/mod.rs +++ b/lib/wasi/src/syscalls/mod.rs @@ -324,15 +324,18 @@ pub fn fd_datasync(ctx: &mut Ctx, fd: __wasi_fd_t) -> __wasi_errno_t { pub fn fd_fdstat_get( ctx: &mut Ctx, fd: __wasi_fd_t, - buf: WasmPtr<__wasi_fdstat_t>, + buf_ptr: WasmPtr<__wasi_fdstat_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 memory = ctx.memory(0); - 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); __WASI_ESUCCESS @@ -543,9 +546,19 @@ pub fn fd_prestat_dir_name( if let Kind::Dir { .. } = inode_val.kind { // TODO: verify this: null termination, etc 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); + i += 1 } + path_chars[i].set(0); + + debug!( + "=> result: \"{}\"", + ::std::str::from_utf8(unsafe { &*(&path_chars[..] as *const [_] as *const [u8]) }) + .unwrap() + ); + __WASI_ESUCCESS } else { __WASI_EOVERFLOW @@ -669,13 +682,10 @@ pub fn fd_read( for iov in iovs_arr_cell { 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] = unsafe { &mut *(bytes as *const [_] as *mut [_] as *mut [u8]) }; - bytes_read += dbg!(reader.read(raw_bytes).map_err(|e| { - dbg!(e); - __WASI_EIO - })? as u32); + bytes_read += reader.read(raw_bytes).map_err(|e| __WASI_EIO)? as u32; } Ok(bytes_read) } @@ -722,7 +732,7 @@ pub fn fd_read( } }; - nread_cell.set(dbg!(bytes_read)); + nread_cell.set(bytes_read); __WASI_ESUCCESS } @@ -819,7 +829,7 @@ pub fn fd_seek( // TODO: handle case if fd is a dir? 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_SET => fd_entry.offset = offset as u64, _ => return __WASI_EINVAL, @@ -838,7 +848,7 @@ pub fn fd_seek( /// Errors: /// TODO: figure out which errors this should return /// - `__WASI_EPERM` -/// - `__WAIS_ENOTCAPABLE` +/// - `__WASI_ENOTCAPABLE` pub fn fd_sync(ctx: &mut Ctx, fd: __wasi_fd_t) -> __wasi_errno_t { debug!("wasi::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 } @@ -1042,7 +1052,9 @@ pub fn path_filestat_get( return __WASI_ELOOP; } } - _ => return __WASI_ENOTDIR, + _ => { + return __WASI_ENOTDIR; + } } } } diff --git a/src/bin/wasmer.rs b/src/bin/wasmer.rs index 32692a59e..54f588405 100644 --- a/src/bin/wasmer.rs +++ b/src/bin/wasmer.rs @@ -123,7 +123,6 @@ impl FromStr for Backend { _ => Err(format!("The backend {} doesn't exist", s)), } } ->>>>>>> origin/master } #[derive(Debug, StructOpt)]