mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-28 16:11:32 +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);
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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(),
|
||||||
})
|
})
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)]
|
||||||
|
Reference in New Issue
Block a user