mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-28 08:01:33 +00:00
fix memory access in WasmPtr
This commit is contained in:
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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(),
|
||||
})
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -123,7 +123,6 @@ impl FromStr for Backend {
|
||||
_ => Err(format!("The backend {} doesn't exist", s)),
|
||||
}
|
||||
}
|
||||
>>>>>>> origin/master
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
|
Reference in New Issue
Block a user