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);
}
unsafe {
let cell_ptr = memory
.view::<T>()
.get_unchecked((self.offset() as usize) / mem::size_of::<T>())
as *const _;
let aligner = |ptr: usize, align: usize| ptr & !(align - 1);
let cell_ptr = aligner(
memory.view::<u8>().as_ptr().add(self.offset as usize) as usize,
mem::align_of::<T>(),
) as *const Cell<T>;
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;
#[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(),
})

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(
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;
}
}
}
}

View File

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