From 751a1a1f7bc8ac0b732a5eae1eec5f1d55b0e923 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 10 May 2019 20:13:50 +0200 Subject: [PATCH 1/2] Add experimental struct with views memory and ctxs This struct is heavily taking from Lucet's Vmctx struct. --- src/ctx.rs | 10 +++ src/hostcalls.rs | 172 +++++++++++++++++++++++++---------------------- src/lib.rs | 1 + src/memory.rs | 63 +++++++++++------ src/vmctx.rs | 59 ++++++++++++++++ 5 files changed, 202 insertions(+), 103 deletions(-) create mode 100644 src/vmctx.rs diff --git a/src/ctx.rs b/src/ctx.rs index 4771d9552b..88d8f73265 100644 --- a/src/ctx.rs +++ b/src/ctx.rs @@ -198,6 +198,16 @@ pub struct WasiCtx { pub env: Vec, } +impl Default for WasiCtx { + fn default() -> Self { + Self { + fds: HashMap::new(), + args: Vec::new(), + env: Vec::new(), + } + } +} + impl WasiCtx { /// Make a new `WasiCtx` with some default settings. /// diff --git a/src/hostcalls.rs b/src/hostcalls.rs index ea10f976f2..1c65201201 100644 --- a/src/hostcalls.rs +++ b/src/hostcalls.rs @@ -11,9 +11,9 @@ #![allow(non_camel_case_types)] #![allow(unused_unsafe)] #![allow(unused)] -use crate::ctx::VmContext; use crate::fdentry::{determine_type_rights, FdEntry}; use crate::memory::*; +use crate::vmctx::VmContextView; use crate::{host, wasm32}; use cast::From as _0; @@ -25,21 +25,21 @@ use std::os::unix::prelude::{FromRawFd, OsStrExt, OsStringExt, RawFd}; use std::time::SystemTime; use std::{cmp, slice}; -pub unsafe fn proc_exit(_vmctx: &mut VmContext, rval: wasm32::__wasi_exitcode_t) -> () { +pub unsafe fn proc_exit(_vmctx: &mut VmContextView, rval: wasm32::__wasi_exitcode_t) -> () { std::process::exit(dec_exitcode(rval) as i32); } pub unsafe fn args_get( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, argv_ptr: wasm32::uintptr_t, argv_buf: wasm32::uintptr_t, ) -> wasm32::__wasi_errno_t { - let ctx = (*vmctx).as_wasi_ctx(); + let ctx = vmctx.get_wasi_ctx(); let mut argv_buf_offset = 0; let mut argv = vec![]; - for arg in (*ctx).args.iter() { + for arg in ctx.args.iter() { let arg_bytes = arg.as_bytes_with_nul(); let arg_ptr = argv_buf + argv_buf_offset; @@ -67,13 +67,13 @@ pub unsafe fn args_get( } pub unsafe fn args_sizes_get( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, argc_ptr: wasm32::uintptr_t, argv_buf_size_ptr: wasm32::uintptr_t, ) -> wasm32::__wasi_errno_t { - let ctx = (*vmctx).as_wasi_ctx(); + let ctx = vmctx.get_wasi_ctx(); - let argc = (*ctx).args.len(); + let argc = ctx.args.len(); let argv_size = (*ctx) .args .iter() @@ -92,7 +92,7 @@ pub unsafe fn args_sizes_get( } pub unsafe fn clock_res_get( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, clock_id: wasm32::__wasi_clockid_t, resolution_ptr: wasm32::uintptr_t, ) -> wasm32::__wasi_errno_t { @@ -134,7 +134,7 @@ pub unsafe fn clock_res_get( } pub unsafe fn clock_time_get( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, clock_id: wasm32::__wasi_clockid_t, // ignored for now, but will be useful once we put optional limits on precision to reduce side // channels @@ -171,16 +171,16 @@ pub unsafe fn clock_time_get( } pub unsafe fn environ_get( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, environ_ptr: wasm32::uintptr_t, environ_buf: wasm32::uintptr_t, ) -> wasm32::__wasi_errno_t { - let ctx = (*vmctx).as_wasi_ctx(); + let ctx = vmctx.get_wasi_ctx(); let mut environ_buf_offset = 0; let mut environ = vec![]; - for pair in (*ctx).env.iter() { + for pair in ctx.env.iter() { let env_bytes = pair.as_bytes_with_nul(); let env_ptr = environ_buf + environ_buf_offset; @@ -208,14 +208,14 @@ pub unsafe fn environ_get( } pub unsafe fn environ_sizes_get( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, environ_count_ptr: wasm32::uintptr_t, environ_size_ptr: wasm32::uintptr_t, ) -> wasm32::__wasi_errno_t { - let ctx = (*vmctx).as_wasi_ctx(); + let ctx = vmctx.get_wasi_ctx(); - let environ_count = (*ctx).env.len(); - if let Some(environ_size) = (*ctx).env.iter().try_fold(0, |acc: u32, pair| { + let environ_count = ctx.env.len(); + if let Some(environ_size) = ctx.env.iter().try_fold(0, |acc: u32, pair| { acc.checked_add(pair.as_bytes_with_nul().len() as u32) }) { unsafe { @@ -232,16 +232,19 @@ pub unsafe fn environ_sizes_get( } } -pub unsafe fn fd_close(vmctx: *mut VmContext, fd: wasm32::__wasi_fd_t) -> wasm32::__wasi_errno_t { - let ctx = (*vmctx).as_wasi_ctx_mut(); +pub unsafe fn fd_close( + vmctx: &mut VmContextView, + fd: wasm32::__wasi_fd_t, +) -> wasm32::__wasi_errno_t { + let mut ctx = vmctx.get_wasi_ctx_mut(); let fd = dec_fd(fd); - if let Some(fdent) = (*ctx).fds.get(&fd) { + if let Some(fdent) = ctx.fds.get(&fd) { // can't close preopened files if fdent.preopen_path.is_some() { return wasm32::__WASI_ENOTSUP; } } - if let Some(mut fdent) = (*ctx).fds.remove(&fd) { + if let Some(mut fdent) = ctx.fds.remove(&fd) { fdent.fd_object.needs_close = false; match nix::unistd::close(fdent.fd_object.rawfd) { Ok(_) => wasm32::__WASI_ESUCCESS, @@ -253,7 +256,7 @@ pub unsafe fn fd_close(vmctx: *mut VmContext, fd: wasm32::__wasi_fd_t) -> wasm32 } pub unsafe fn fd_fdstat_get( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, fd: wasm32::__wasi_fd_t, fdstat_ptr: wasm32::uintptr_t, // *mut wasm32::__wasi_fdstat_t ) -> wasm32::__wasi_errno_t { @@ -263,8 +266,8 @@ pub unsafe fn fd_fdstat_get( Err(e) => return enc_errno(e), }; - let ctx = (*vmctx).as_wasi_ctx_mut(); - let errno = if let Some(fe) = (*ctx).fds.get(&host_fd) { + let ctx = vmctx.get_wasi_ctx(); + let errno = if let Some(fe) = ctx.fds.get(&host_fd) { host_fdstat.fs_filetype = fe.fd_object.ty; host_fdstat.fs_rights_base = fe.rights_base; host_fdstat.fs_rights_inheriting = fe.rights_inheriting; @@ -289,7 +292,7 @@ pub unsafe fn fd_fdstat_get( } pub unsafe fn fd_fdstat_set_flags( - vmctx: &mut VmContext, + vmctx: &mut VmContextView, fd: wasm32::__wasi_fd_t, fdflags: wasm32::__wasi_fdflags_t, ) -> wasm32::__wasi_errno_t { @@ -297,9 +300,9 @@ pub unsafe fn fd_fdstat_set_flags( let host_fdflags = dec_fdflags(fdflags); let nix_flags = host::nix_from_fdflags(host_fdflags); - let ctx = (*vmctx).as_wasi_ctx_mut(); + let ctx = vmctx.get_wasi_ctx(); - if let Some(fe) = (*ctx).fds.get(&host_fd) { + if let Some(fe) = ctx.fds.get(&host_fd) { match nix::fcntl::fcntl(fe.fd_object.rawfd, nix::fcntl::F_SETFL(nix_flags)) { Ok(_) => wasm32::__WASI_ESUCCESS, Err(e) => wasm32::errno_from_nix(e.as_errno().unwrap()), @@ -310,13 +313,13 @@ pub unsafe fn fd_fdstat_set_flags( } pub unsafe fn fd_seek( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, fd: wasm32::__wasi_fd_t, offset: wasm32::__wasi_filedelta_t, whence: wasm32::__wasi_whence_t, newoffset: wasm32::uintptr_t, ) -> wasm32::__wasi_errno_t { - let ctx = (*vmctx).as_wasi_ctx_mut(); + let ctx = vmctx.get_wasi_ctx(); let fd = dec_fd(fd); let offset = dec_filedelta(offset); let whence = dec_whence(whence); @@ -335,7 +338,7 @@ pub unsafe fn fd_seek( } else { host::__WASI_RIGHT_FD_SEEK | host::__WASI_RIGHT_FD_TELL }; - match (*ctx).get_fd_entry(fd, rights.into(), 0) { + match ctx.get_fd_entry(fd, rights.into(), 0) { Ok(fe) => match lseek(fe.fd_object.rawfd, offset, nwhence) { Ok(newoffset) => newoffset, Err(e) => return wasm32::errno_from_nix(e.as_errno().unwrap()), @@ -352,14 +355,14 @@ pub unsafe fn fd_seek( } pub unsafe fn fd_prestat_get( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, fd: wasm32::__wasi_fd_t, prestat_ptr: wasm32::uintptr_t, ) -> wasm32::__wasi_errno_t { - let ctx = (*vmctx).as_wasi_ctx(); + let ctx = vmctx.get_wasi_ctx(); let fd = dec_fd(fd); // TODO: is this the correct right for this? - match (*ctx).get_fd_entry(fd, host::__WASI_RIGHT_PATH_OPEN.into(), 0) { + match ctx.get_fd_entry(fd, host::__WASI_RIGHT_PATH_OPEN.into(), 0) { Ok(fe) => { if let Some(po_path) = &fe.preopen_path { if fe.fd_object.ty != host::__WASI_FILETYPE_DIRECTORY { @@ -391,14 +394,17 @@ pub unsafe fn fd_prestat_get( } pub unsafe fn fd_prestat_dir_name( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, fd: wasm32::__wasi_fd_t, path_ptr: wasm32::uintptr_t, path_len: wasm32::size_t, ) -> wasm32::__wasi_errno_t { let fd = dec_fd(fd); - match (*(*vmctx).as_wasi_ctx()).get_fd_entry(fd, host::__WASI_RIGHT_PATH_OPEN.into(), 0) { + match vmctx + .get_wasi_ctx() + .get_fd_entry(fd, host::__WASI_RIGHT_PATH_OPEN.into(), 0) + { Ok(fe) => { if let Some(po_path) = &fe.preopen_path { if fe.fd_object.ty != host::__WASI_FILETYPE_DIRECTORY { @@ -422,7 +428,7 @@ pub unsafe fn fd_prestat_dir_name( } pub unsafe fn fd_read( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, fd: wasm32::__wasi_fd_t, iovs_ptr: wasm32::uintptr_t, iovs_len: wasm32::size_t, @@ -436,8 +442,8 @@ pub unsafe fn fd_read( Err(e) => return enc_errno(e), }; - let ctx = (*vmctx).as_wasi_ctx_mut(); - let fe = match (*ctx).get_fd_entry(fd, host::__WASI_RIGHT_FD_READ.into(), 0) { + let mut ctx = vmctx.get_wasi_ctx_mut(); + let fe = match ctx.get_fd_entry(fd, host::__WASI_RIGHT_FD_READ.into(), 0) { Ok(fe) => fe, Err(e) => return enc_errno(e), }; @@ -454,7 +460,7 @@ pub unsafe fn fd_read( if host_nread == 0 { // we hit eof, so remove the fdentry from the context - let mut fe = (*ctx).fds.remove(&fd).expect("file entry is still there"); + let mut fe = ctx.fds.remove(&fd).expect("file entry is still there"); fe.fd_object.needs_close = false; } @@ -466,7 +472,7 @@ pub unsafe fn fd_read( } pub unsafe fn fd_write( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, fd: wasm32::__wasi_fd_t, iovs_ptr: wasm32::uintptr_t, iovs_len: wasm32::size_t, @@ -480,8 +486,8 @@ pub unsafe fn fd_write( Err(e) => return enc_errno(e), }; - let ctx = (*vmctx).as_wasi_ctx(); - let fe = match (*ctx).get_fd_entry(fd, host::__WASI_RIGHT_FD_WRITE.into(), 0) { + let ctx = vmctx.get_wasi_ctx(); + let fe = match ctx.get_fd_entry(fd, host::__WASI_RIGHT_FD_WRITE.into(), 0) { Ok(fe) => fe, Err(e) => return enc_errno(e), }; @@ -504,7 +510,7 @@ pub unsafe fn fd_write( } pub unsafe fn path_open( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, dirfd: wasm32::__wasi_fd_t, dirflags: wasm32::__wasi_lookupflags_t, path_ptr: wasm32::uintptr_t, @@ -627,7 +633,7 @@ pub unsafe fn path_open( let mut fe = unsafe { FdEntry::from_raw_fd(new_fd) }; fe.rights_base &= max_base; fe.rights_inheriting &= max_inheriting; - match (*(*vmctx).as_wasi_ctx_mut()).insert_fd_entry(fe) { + match vmctx.get_wasi_ctx_mut().insert_fd_entry(fe) { Ok(fd) => fd, Err(e) => return enc_errno(e), } @@ -642,14 +648,14 @@ pub unsafe fn path_open( } pub unsafe fn random_get( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, buf_ptr: wasm32::uintptr_t, buf_len: wasm32::size_t, ) -> wasm32::__wasi_errno_t { use rand::{thread_rng, RngCore}; let buf_len = dec_usize(buf_len); - let buf_ptr = match unsafe { (*vmctx).dec_ptr(buf_ptr, buf_len) } { + let buf_ptr = match unsafe { dec_ptr(vmctx, buf_ptr, buf_len) } { Ok(ptr) => ptr, Err(e) => return enc_errno(e), }; @@ -662,7 +668,7 @@ pub unsafe fn random_get( } pub unsafe fn poll_oneoff( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, input: wasm32::uintptr_t, output: wasm32::uintptr_t, nsubscriptions: wasm32::size_t, @@ -751,16 +757,16 @@ pub unsafe fn poll_oneoff( } pub unsafe fn fd_filestat_get( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, fd: wasm32::__wasi_fd_t, filestat_ptr: wasm32::uintptr_t, ) -> wasm32::__wasi_errno_t { use nix::sys::stat::fstat; let host_fd = dec_fd(fd); - let ctx = (*vmctx).as_wasi_ctx_mut(); + let ctx = vmctx.get_wasi_ctx_mut(); - let errno = if let Some(fe) = (*ctx).fds.get(&host_fd) { + let errno = if let Some(fe) = ctx.fds.get(&host_fd) { match fstat(fe.fd_object.rawfd) { Err(e) => wasm32::errno_from_nix(e.as_errno().unwrap()), Ok(filestat) => { @@ -779,7 +785,7 @@ pub unsafe fn fd_filestat_get( } pub unsafe fn path_filestat_get( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, dirfd: wasm32::__wasi_fd_t, dirflags: wasm32::__wasi_lookupflags_t, path_ptr: wasm32::uintptr_t, @@ -825,7 +831,7 @@ pub unsafe fn path_filestat_get( } pub unsafe fn path_create_directory( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, dirfd: wasm32::__wasi_fd_t, path_ptr: wasm32::uintptr_t, path_len: wasm32::size_t, @@ -862,7 +868,7 @@ pub unsafe fn path_create_directory( } pub unsafe fn path_unlink_file( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, dirfd: wasm32::__wasi_fd_t, path_ptr: wasm32::uintptr_t, path_len: wasm32::size_t, @@ -899,14 +905,14 @@ pub unsafe fn path_unlink_file( } pub unsafe fn fd_datasync( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, fd: wasm32::__wasi_fd_t, ) -> wasm32::__wasi_errno_t { unimplemented!("fd_datasync") } pub unsafe fn fd_pread( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, fd: wasm32::__wasi_fd_t, iovs: wasm32::uintptr_t, iovs_len: wasm32::size_t, @@ -917,7 +923,7 @@ pub unsafe fn fd_pread( } pub unsafe fn fd_pwrite( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, fd: wasm32::__wasi_fd_t, iovs: wasm32::uintptr_t, iovs_len: wasm32::size_t, @@ -928,7 +934,7 @@ pub unsafe fn fd_pwrite( } pub unsafe fn fd_renumber( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, from: wasm32::__wasi_fd_t, to: wasm32::__wasi_fd_t, ) -> wasm32::__wasi_errno_t { @@ -936,7 +942,7 @@ pub unsafe fn fd_renumber( } pub unsafe fn fd_tell( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, fd: wasm32::__wasi_fd_t, newoffset: wasm32::uintptr_t, ) -> wasm32::__wasi_errno_t { @@ -944,7 +950,7 @@ pub unsafe fn fd_tell( } pub unsafe fn fd_fdstat_set_rights( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, fd: wasm32::__wasi_fd_t, fs_rights_base: wasm32::__wasi_rights_t, fs_rights_inheriting: wasm32::__wasi_rights_t, @@ -952,12 +958,15 @@ pub unsafe fn fd_fdstat_set_rights( unimplemented!("fd_fdstat_set_rights") } -pub unsafe fn fd_sync(vmctx: *mut VmContext, fd: wasm32::__wasi_fd_t) -> wasm32::__wasi_errno_t { +pub unsafe fn fd_sync( + vmctx: &mut VmContextView, + fd: wasm32::__wasi_fd_t, +) -> wasm32::__wasi_errno_t { unimplemented!("fd_sync") } pub unsafe fn fd_advise( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, fd: wasm32::__wasi_fd_t, offset: wasm32::__wasi_filesize_t, len: wasm32::__wasi_filesize_t, @@ -967,7 +976,7 @@ pub unsafe fn fd_advise( } pub unsafe fn fd_allocate( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, fd: wasm32::__wasi_fd_t, offset: wasm32::__wasi_filesize_t, len: wasm32::__wasi_filesize_t, @@ -976,7 +985,7 @@ pub unsafe fn fd_allocate( } pub unsafe fn path_link( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, fd0: wasm32::__wasi_fd_t, flags0: wasm32::__wasi_lookupflags_t, path0: wasm32::uintptr_t, @@ -989,7 +998,7 @@ pub unsafe fn path_link( } pub unsafe fn fd_readdir( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, fd: wasm32::__wasi_fd_t, buf: wasm32::uintptr_t, buf_len: wasm32::size_t, @@ -1000,7 +1009,7 @@ pub unsafe fn fd_readdir( } pub unsafe fn path_readlink( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, fd: wasm32::__wasi_fd_t, path: wasm32::uintptr_t, path_len: wasm32::size_t, @@ -1012,7 +1021,7 @@ pub unsafe fn path_readlink( } pub unsafe fn path_rename( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, fd0: wasm32::__wasi_fd_t, path0: wasm32::uintptr_t, path_len0: wasm32::size_t, @@ -1024,7 +1033,7 @@ pub unsafe fn path_rename( } pub unsafe fn fd_filestat_set_times( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, fd: wasm32::__wasi_fd_t, st_atim: wasm32::__wasi_timestamp_t, st_mtim: wasm32::__wasi_timestamp_t, @@ -1034,7 +1043,7 @@ pub unsafe fn fd_filestat_set_times( } pub unsafe fn fd_filestat_set_size( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, fd: wasm32::__wasi_fd_t, size: wasm32::__wasi_filesize_t, ) -> wasm32::__wasi_errno_t { @@ -1042,7 +1051,7 @@ pub unsafe fn fd_filestat_set_size( } pub unsafe fn path_filestat_set_times( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, fd: wasm32::__wasi_fd_t, flags: wasm32::__wasi_lookupflags_t, path: wasm32::uintptr_t, @@ -1055,7 +1064,7 @@ pub unsafe fn path_filestat_set_times( } pub unsafe fn path_symlink( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, path0: wasm32::uintptr_t, path_len0: wasm32::size_t, fd: wasm32::__wasi_fd_t, @@ -1066,7 +1075,7 @@ pub unsafe fn path_symlink( } pub unsafe fn path_remove_directory( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, fd: wasm32::__wasi_fd_t, path: wasm32::uintptr_t, path_len: wasm32::size_t, @@ -1075,18 +1084,18 @@ pub unsafe fn path_remove_directory( } pub unsafe fn proc_raise( - _vmctx: *mut VmContext, + _vmctx: &mut VmContextView, _sig: wasm32::__wasi_signal_t, ) -> wasm32::__wasi_errno_t { unimplemented!("proc_raise") } -pub unsafe fn sched_yield(_vmctx: *mut VmContext) -> wasm32::__wasi_errno_t { +pub unsafe fn sched_yield(_vmctx: &mut VmContextView) -> wasm32::__wasi_errno_t { unimplemented!("sched_yield") } pub unsafe fn sock_recv( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, sock: wasm32::__wasi_fd_t, ri_data: wasm32::uintptr_t, ri_data_len: wasm32::size_t, @@ -1098,7 +1107,7 @@ pub unsafe fn sock_recv( } pub unsafe fn sock_send( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, sock: wasm32::__wasi_fd_t, si_data: wasm32::uintptr_t, si_data_len: wasm32::size_t, @@ -1109,7 +1118,7 @@ pub unsafe fn sock_send( } pub unsafe fn sock_shutdown( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, sock: wasm32::__wasi_fd_t, how: wasm32::__wasi_sdflags_t, ) -> wasm32::__wasi_errno_t { @@ -1146,7 +1155,7 @@ struct FdEventData { } fn poll_oneoff_handle_timeout_event( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, output_slice: &mut [wasm32::__wasi_event_t], nevents: wasm32::uintptr_t, timeout: Option, @@ -1177,7 +1186,7 @@ fn poll_oneoff_handle_timeout_event( } fn poll_oneoff_handle_fd_event<'t>( - vmctx: *mut VmContext, + vmctx: &mut VmContextView, output_slice: &mut [wasm32::__wasi_event_t], nevents: wasm32::uintptr_t, events: impl Iterator, @@ -1263,7 +1272,7 @@ fn poll_oneoff_handle_fd_event<'t>( /// /// This is a workaround for not having Capsicum support in the OS. pub fn path_get>( - vmctx: &VmContext, + vmctx: &VmContextView, dirfd: host::__wasi_fd_t, dirflags: host::__wasi_lookupflags_t, path: P, @@ -1307,9 +1316,8 @@ pub fn path_get>( Err(errno) } - let ctx = (*vmctx).as_wasi_ctx(); - - let dirfe = unsafe { (*ctx).get_fd_entry(dirfd, needed_base, needed_inheriting)? }; + let ctx = vmctx.get_wasi_ctx(); + let dirfe = ctx.get_fd_entry(dirfd, needed_base, needed_inheriting)?; // Stack of directory file descriptors. Index 0 always corresponds with the directory provided // to this function. Entering a directory causes a file descriptor to be pushed, while handling diff --git a/src/lib.rs b/src/lib.rs index d98ff3a343..94ca4c5379 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,6 +25,7 @@ pub mod fdentry; pub mod host; pub mod hostcalls; pub mod memory; +pub mod vmctx; pub mod wasm32; pub use ctx::{WasiCtx, WasiCtxBuilder}; diff --git a/src/memory.rs b/src/memory.rs index 2de9b5c568..24b924e45b 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -9,7 +9,7 @@ //! //! This sort of manual encoding will hopefully be obsolete once the IDL is developed. -use crate::ctx::VmContext; +use crate::vmctx::VmContextView; use crate::{host, wasm32}; use cast; @@ -23,26 +23,47 @@ macro_rules! bail_errno { }; } +pub unsafe fn dec_ptr( + vmctx: &VmContextView, + ptr: wasm32::uintptr_t, + len: usize, +) -> Result<*mut u8, host::__wasi_errno_t> { + let mut heap = vmctx.memory_mut(); + + // check that `len` fits in the wasm32 address space + if len > wasm32::UINTPTR_MAX as usize { + bail_errno!(__WASI_EOVERFLOW); + } + + // check that `ptr` and `ptr + len` are both within the guest heap + if ptr as usize > heap.len() || ptr as usize + len > heap.len() { + bail_errno!(__WASI_EFAULT); + } + + // translate the pointer + Ok(heap.as_mut_ptr().offset(ptr as isize)) +} + pub unsafe fn dec_ptr_to( - vmctx: *mut VmContext, + vmctx: &VmContextView, ptr: wasm32::uintptr_t, ) -> Result<*mut T, host::__wasi_errno_t> { // check that the ptr is aligned if ptr as usize % align_of::() != 0 { bail_errno!(__WASI_EINVAL); } - (*vmctx).dec_ptr(ptr, size_of::()).map(|p| p as *mut T) + dec_ptr(vmctx, ptr, size_of::()).map(|p| p as *mut T) } pub unsafe fn dec_pointee( - vmctx: *mut VmContext, + vmctx: &VmContextView, ptr: wasm32::uintptr_t, ) -> Result { dec_ptr_to::(vmctx, ptr).map(|p| p.read()) } pub unsafe fn enc_pointee( - vmctx: *mut VmContext, + vmctx: &VmContextView, ptr: wasm32::uintptr_t, t: T, ) -> Result<(), host::__wasi_errno_t> { @@ -50,7 +71,7 @@ pub unsafe fn enc_pointee( } pub unsafe fn dec_slice_of( - vmctx: *mut VmContext, + vmctx: &VmContextView, ptr: wasm32::uintptr_t, len: wasm32::size_t, ) -> Result<(*mut T, usize), host::__wasi_errno_t> { @@ -65,13 +86,13 @@ pub unsafe fn dec_slice_of( return Err(host::__WASI_EOVERFLOW); }; - let ptr = (*vmctx).dec_ptr(ptr, len_bytes)? as *mut T; + let ptr = dec_ptr(vmctx, ptr, len_bytes)? as *mut T; Ok((ptr, len)) } pub unsafe fn enc_slice_of( - vmctx: *mut VmContext, + vmctx: &VmContextView, slice: &[T], ptr: wasm32::uintptr_t, ) -> Result<(), host::__wasi_errno_t> { @@ -87,7 +108,7 @@ pub unsafe fn enc_slice_of( }; // get the pointer into guest memory, and copy the bytes - let ptr = (*vmctx).dec_ptr(ptr, len_bytes)? as *mut libc::c_void; + let ptr = dec_ptr(vmctx, ptr, len_bytes)? as *mut libc::c_void; libc::memcpy(ptr, slice.as_ptr() as *const libc::c_void, len_bytes); Ok(()) @@ -100,7 +121,7 @@ macro_rules! dec_enc_scalar { } pub unsafe fn $dec_byref( - vmctx: *mut VmContext, + vmctx: &VmContextView, ptr: wasm32::uintptr_t, ) -> Result { dec_pointee::(vmctx, ptr).map($dec) @@ -111,7 +132,7 @@ macro_rules! dec_enc_scalar { } pub unsafe fn $enc_byref( - vmctx: *mut VmContext, + vmctx: &VmContextView, ptr: wasm32::uintptr_t, x: host::$ty, ) -> Result<(), host::__wasi_errno_t> { @@ -121,18 +142,18 @@ macro_rules! dec_enc_scalar { } pub unsafe fn dec_ciovec( - vmctx: *mut VmContext, + vmctx: &VmContextView, ciovec: &wasm32::__wasi_ciovec_t, ) -> Result { let len = dec_usize(ciovec.buf_len); Ok(host::__wasi_ciovec_t { - buf: (*vmctx).dec_ptr(ciovec.buf, len)? as *const host::void, + buf: dec_ptr(vmctx, ciovec.buf, len)? as *const host::void, buf_len: len, }) } pub unsafe fn dec_ciovec_slice( - vmctx: *mut VmContext, + vmctx: &VmContextView, ptr: wasm32::uintptr_t, len: wasm32::size_t, ) -> Result, host::__wasi_errno_t> { @@ -206,7 +227,7 @@ pub fn dec_filestat(filestat: wasm32::__wasi_filestat_t) -> host::__wasi_filesta } pub unsafe fn dec_filestat_byref( - vmctx: *mut VmContext, + vmctx: &VmContextView, filestat_ptr: wasm32::uintptr_t, ) -> Result { dec_pointee::(vmctx, filestat_ptr).map(dec_filestat) @@ -226,7 +247,7 @@ pub fn enc_filestat(filestat: host::__wasi_filestat_t) -> wasm32::__wasi_filesta } pub unsafe fn enc_filestat_byref( - vmctx: *mut VmContext, + vmctx: &VmContextView, filestat_ptr: wasm32::uintptr_t, host_filestat: host::__wasi_filestat_t, ) -> Result<(), host::__wasi_errno_t> { @@ -244,7 +265,7 @@ pub fn dec_fdstat(fdstat: wasm32::__wasi_fdstat_t) -> host::__wasi_fdstat_t { } pub unsafe fn dec_fdstat_byref( - vmctx: *mut VmContext, + vmctx: &VmContextView, fdstat_ptr: wasm32::uintptr_t, ) -> Result { dec_pointee::(vmctx, fdstat_ptr).map(dec_fdstat) @@ -261,7 +282,7 @@ pub fn enc_fdstat(fdstat: host::__wasi_fdstat_t) -> wasm32::__wasi_fdstat_t { } pub unsafe fn enc_fdstat_byref( - vmctx: *mut VmContext, + vmctx: &VmContextView, fdstat_ptr: wasm32::uintptr_t, host_fdstat: host::__wasi_fdstat_t, ) -> Result<(), host::__wasi_errno_t> { @@ -328,7 +349,7 @@ pub fn dec_prestat( } pub unsafe fn dec_prestat_byref( - vmctx: *mut VmContext, + vmctx: &VmContextView, prestat_ptr: wasm32::uintptr_t, ) -> Result { dec_pointee::(vmctx, prestat_ptr).and_then(dec_prestat) @@ -354,7 +375,7 @@ pub fn enc_prestat( } pub unsafe fn enc_prestat_byref( - vmctx: *mut VmContext, + vmctx: &VmContextView, prestat_ptr: wasm32::uintptr_t, host_prestat: host::__wasi_prestat_t, ) -> Result<(), host::__wasi_errno_t> { @@ -386,7 +407,7 @@ pub fn enc_usize(size: usize) -> wasm32::size_t { } pub unsafe fn enc_usize_byref( - vmctx: *mut VmContext, + vmctx: &VmContextView, usize_ptr: wasm32::uintptr_t, host_usize: usize, ) -> Result<(), host::__wasi_errno_t> { diff --git a/src/vmctx.rs b/src/vmctx.rs new file mode 100644 index 0000000000..a3a8ae6af9 --- /dev/null +++ b/src/vmctx.rs @@ -0,0 +1,59 @@ +//! This code borrows heavily from Lucet's Vmctx implementation +//! https://github.com/fastly/lucet/blob/master/lucet-runtime/lucet-runtime-internals/src/vmctx.rs + +use crate::ctx::WasiCtx; +use std::borrow::{Borrow, BorrowMut}; +use std::cell::{Ref, RefCell, RefMut}; + +pub trait AsVmContextView { + unsafe fn as_vm_context_view(&mut self) -> VmContextView; +} + +#[derive(Debug)] +pub struct VmContextView { + pub memory_view: RefCell>, + pub wasi_ctx_view: RefCell>, +} + +impl Drop for VmContextView { + fn drop(&mut self) { + let memory_view = self.memory_view.replace(Box::new([])); + let wasi_ctx_view = self.wasi_ctx_view.replace(Box::new(WasiCtx::default())); + Box::leak(memory_view); + Box::leak(wasi_ctx_view); + } +} + +impl VmContextView { + pub fn memory(&self) -> Ref<[u8]> { + let r = self + .memory_view + .try_borrow() + .expect("memory not already borrowed mutably"); + Ref::map(r, |b| b.borrow()) + } + + pub fn memory_mut(&self) -> RefMut<[u8]> { + let r = self + .memory_view + .try_borrow_mut() + .expect("memory not already borrowed"); + RefMut::map(r, |b| b.borrow_mut()) + } + + pub fn get_wasi_ctx(&self) -> Ref { + let r = self + .wasi_ctx_view + .try_borrow() + .expect("WASI context not already borrowed mutably"); + Ref::map(r, |b| b.borrow()) + } + + pub fn get_wasi_ctx_mut(&self) -> RefMut { + let r = self + .wasi_ctx_view + .try_borrow_mut() + .expect("WASI context not already borrowed"); + RefMut::map(r, |b| b.borrow_mut()) + } +} From 75ad92b0f3f0fbe668967918e377dc0c855e6747 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sat, 11 May 2019 10:44:54 +0200 Subject: [PATCH 2/2] Insulate API from intricacies of memory mgmt of calling runtimes --- src/ctx.rs | 22 --- src/hostcalls.rs | 366 +++++++++++++++++++++++++---------------------- src/lib.rs | 1 - src/memory.rs | 75 +++++----- src/vmctx.rs | 59 -------- 5 files changed, 228 insertions(+), 295 deletions(-) delete mode 100644 src/vmctx.rs diff --git a/src/ctx.rs b/src/ctx.rs index 88d8f73265..6b8d5d0e94 100644 --- a/src/ctx.rs +++ b/src/ctx.rs @@ -1,6 +1,5 @@ use crate::fdentry::FdEntry; use crate::host; -use crate::wasm32; use failure::{bail, format_err, Error}; use nix::unistd::dup; @@ -11,17 +10,6 @@ use std::io::{stderr, stdin, stdout}; use std::os::unix::prelude::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; use std::path::{Path, PathBuf}; -pub trait VmContext { - fn as_wasi_ctx(&self) -> *const WasiCtx; - fn as_wasi_ctx_mut(&mut self) -> *mut WasiCtx; - - unsafe fn dec_ptr( - &mut self, - ptr: wasm32::uintptr_t, - len: usize, - ) -> Result<*mut u8, host::__wasi_errno_t>; -} - pub struct WasiCtxBuilder { fds: HashMap, preopens: HashMap, @@ -198,16 +186,6 @@ pub struct WasiCtx { pub env: Vec, } -impl Default for WasiCtx { - fn default() -> Self { - Self { - fds: HashMap::new(), - args: Vec::new(), - env: Vec::new(), - } - } -} - impl WasiCtx { /// Make a new `WasiCtx` with some default settings. /// diff --git a/src/hostcalls.rs b/src/hostcalls.rs index 1c65201201..3be889e244 100644 --- a/src/hostcalls.rs +++ b/src/hostcalls.rs @@ -11,9 +11,9 @@ #![allow(non_camel_case_types)] #![allow(unused_unsafe)] #![allow(unused)] +use crate::ctx::WasiCtx; use crate::fdentry::{determine_type_rights, FdEntry}; use crate::memory::*; -use crate::vmctx::VmContextView; use crate::{host, wasm32}; use cast::From as _0; @@ -25,25 +25,24 @@ use std::os::unix::prelude::{FromRawFd, OsStrExt, OsStringExt, RawFd}; use std::time::SystemTime; use std::{cmp, slice}; -pub unsafe fn proc_exit(_vmctx: &mut VmContextView, rval: wasm32::__wasi_exitcode_t) -> () { +pub fn proc_exit(rval: wasm32::__wasi_exitcode_t) -> () { std::process::exit(dec_exitcode(rval) as i32); } -pub unsafe fn args_get( - vmctx: &mut VmContextView, +pub fn args_get( + wasi_ctx: &WasiCtx, + memory: &mut [u8], argv_ptr: wasm32::uintptr_t, argv_buf: wasm32::uintptr_t, ) -> wasm32::__wasi_errno_t { - let ctx = vmctx.get_wasi_ctx(); - let mut argv_buf_offset = 0; let mut argv = vec![]; - for arg in ctx.args.iter() { + for arg in wasi_ctx.args.iter() { let arg_bytes = arg.as_bytes_with_nul(); let arg_ptr = argv_buf + argv_buf_offset; - if let Err(e) = unsafe { enc_slice_of(vmctx, arg_bytes, arg_ptr) } { + if let Err(e) = unsafe { enc_slice_of(memory, arg_bytes, arg_ptr) } { return enc_errno(e); } @@ -60,39 +59,38 @@ pub unsafe fn args_get( } unsafe { - enc_slice_of(vmctx, argv.as_slice(), argv_ptr) + enc_slice_of(memory, argv.as_slice(), argv_ptr) .map(|_| wasm32::__WASI_ESUCCESS) .unwrap_or_else(|e| e) } } -pub unsafe fn args_sizes_get( - vmctx: &mut VmContextView, +pub fn args_sizes_get( + wasi_ctx: &WasiCtx, + memory: &mut [u8], argc_ptr: wasm32::uintptr_t, argv_buf_size_ptr: wasm32::uintptr_t, ) -> wasm32::__wasi_errno_t { - let ctx = vmctx.get_wasi_ctx(); - - let argc = ctx.args.len(); - let argv_size = (*ctx) + let argc = wasi_ctx.args.len(); + let argv_size = wasi_ctx .args .iter() .map(|arg| arg.as_bytes_with_nul().len()) .sum(); unsafe { - if let Err(e) = enc_usize_byref(vmctx, argc_ptr, argc) { + if let Err(e) = enc_usize_byref(memory, argc_ptr, argc) { return enc_errno(e); } - if let Err(e) = enc_usize_byref(vmctx, argv_buf_size_ptr, argv_size) { + if let Err(e) = enc_usize_byref(memory, argv_buf_size_ptr, argv_size) { return enc_errno(e); } } wasm32::__WASI_ESUCCESS } -pub unsafe fn clock_res_get( - vmctx: &mut VmContextView, +pub fn clock_res_get( + memory: &mut [u8], clock_id: wasm32::__wasi_clockid_t, resolution_ptr: wasm32::uintptr_t, ) -> wasm32::__wasi_errno_t { @@ -124,7 +122,7 @@ pub unsafe fn clock_res_get( wasm32::__WASI_EINVAL } else { unsafe { - enc_timestamp_byref(vmctx, resolution_ptr, resolution) + enc_timestamp_byref(memory, resolution_ptr, resolution) .map(|_| wasm32::__WASI_ESUCCESS) .unwrap_or_else(|e| e) } @@ -133,8 +131,8 @@ pub unsafe fn clock_res_get( .unwrap_or(wasm32::__WASI_EOVERFLOW) } -pub unsafe fn clock_time_get( - vmctx: &mut VmContextView, +pub fn clock_time_get( + memory: &mut [u8], clock_id: wasm32::__wasi_clockid_t, // ignored for now, but will be useful once we put optional limits on precision to reduce side // channels @@ -163,28 +161,27 @@ pub unsafe fn clock_time_get( .checked_mul(1_000_000_000) .and_then(|sec_ns| sec_ns.checked_add(timespec.tv_nsec as host::__wasi_timestamp_t)) .map(|time| unsafe { - enc_timestamp_byref(vmctx, time_ptr, time) + enc_timestamp_byref(memory, time_ptr, time) .map(|_| wasm32::__WASI_ESUCCESS) .unwrap_or_else(|e| e) }) .unwrap_or(wasm32::__WASI_EOVERFLOW) } -pub unsafe fn environ_get( - vmctx: &mut VmContextView, +pub fn environ_get( + wasi_ctx: &WasiCtx, + memory: &mut [u8], environ_ptr: wasm32::uintptr_t, environ_buf: wasm32::uintptr_t, ) -> wasm32::__wasi_errno_t { - let ctx = vmctx.get_wasi_ctx(); - let mut environ_buf_offset = 0; let mut environ = vec![]; - for pair in ctx.env.iter() { + for pair in wasi_ctx.env.iter() { let env_bytes = pair.as_bytes_with_nul(); let env_ptr = environ_buf + environ_buf_offset; - if let Err(e) = unsafe { enc_slice_of(vmctx, env_bytes, env_ptr) } { + if let Err(e) = unsafe { enc_slice_of(memory, env_bytes, env_ptr) } { return enc_errno(e); } @@ -201,28 +198,27 @@ pub unsafe fn environ_get( } unsafe { - enc_slice_of(vmctx, environ.as_slice(), environ_ptr) + enc_slice_of(memory, environ.as_slice(), environ_ptr) .map(|_| wasm32::__WASI_ESUCCESS) .unwrap_or_else(|e| e) } } -pub unsafe fn environ_sizes_get( - vmctx: &mut VmContextView, +pub fn environ_sizes_get( + wasi_ctx: &WasiCtx, + memory: &mut [u8], environ_count_ptr: wasm32::uintptr_t, environ_size_ptr: wasm32::uintptr_t, ) -> wasm32::__wasi_errno_t { - let ctx = vmctx.get_wasi_ctx(); - - let environ_count = ctx.env.len(); - if let Some(environ_size) = ctx.env.iter().try_fold(0, |acc: u32, pair| { + let environ_count = wasi_ctx.env.len(); + if let Some(environ_size) = wasi_ctx.env.iter().try_fold(0, |acc: u32, pair| { acc.checked_add(pair.as_bytes_with_nul().len() as u32) }) { unsafe { - if let Err(e) = enc_usize_byref(vmctx, environ_count_ptr, environ_count) { + if let Err(e) = enc_usize_byref(memory, environ_count_ptr, environ_count) { return enc_errno(e); } - if let Err(e) = enc_usize_byref(vmctx, environ_size_ptr, environ_size as usize) { + if let Err(e) = enc_usize_byref(memory, environ_size_ptr, environ_size as usize) { return enc_errno(e); } } @@ -232,19 +228,15 @@ pub unsafe fn environ_sizes_get( } } -pub unsafe fn fd_close( - vmctx: &mut VmContextView, - fd: wasm32::__wasi_fd_t, -) -> wasm32::__wasi_errno_t { - let mut ctx = vmctx.get_wasi_ctx_mut(); +pub fn fd_close(wasi_ctx: &mut WasiCtx, fd: wasm32::__wasi_fd_t) -> wasm32::__wasi_errno_t { let fd = dec_fd(fd); - if let Some(fdent) = ctx.fds.get(&fd) { + if let Some(fdent) = wasi_ctx.fds.get(&fd) { // can't close preopened files if fdent.preopen_path.is_some() { return wasm32::__WASI_ENOTSUP; } } - if let Some(mut fdent) = ctx.fds.remove(&fd) { + if let Some(mut fdent) = wasi_ctx.fds.remove(&fd) { fdent.fd_object.needs_close = false; match nix::unistd::close(fdent.fd_object.rawfd) { Ok(_) => wasm32::__WASI_ESUCCESS, @@ -255,19 +247,19 @@ pub unsafe fn fd_close( } } -pub unsafe fn fd_fdstat_get( - vmctx: &mut VmContextView, +pub fn fd_fdstat_get( + wasi_ctx: &WasiCtx, + memory: &mut [u8], fd: wasm32::__wasi_fd_t, fdstat_ptr: wasm32::uintptr_t, // *mut wasm32::__wasi_fdstat_t ) -> wasm32::__wasi_errno_t { let host_fd = dec_fd(fd); - let mut host_fdstat = match unsafe { dec_fdstat_byref(vmctx, fdstat_ptr) } { + let mut host_fdstat = match unsafe { dec_fdstat_byref(memory, fdstat_ptr) } { Ok(host_fdstat) => host_fdstat, Err(e) => return enc_errno(e), }; - let ctx = vmctx.get_wasi_ctx(); - let errno = if let Some(fe) = ctx.fds.get(&host_fd) { + let errno = if let Some(fe) = wasi_ctx.fds.get(&host_fd) { host_fdstat.fs_filetype = fe.fd_object.ty; host_fdstat.fs_rights_base = fe.rights_base; host_fdstat.fs_rights_inheriting = fe.rights_inheriting; @@ -284,15 +276,15 @@ pub unsafe fn fd_fdstat_get( }; unsafe { - enc_fdstat_byref(vmctx, fdstat_ptr, host_fdstat) + enc_fdstat_byref(memory, fdstat_ptr, host_fdstat) .expect("can write back into the pointer we read from"); } errno } -pub unsafe fn fd_fdstat_set_flags( - vmctx: &mut VmContextView, +pub fn fd_fdstat_set_flags( + wasi_ctx: &WasiCtx, fd: wasm32::__wasi_fd_t, fdflags: wasm32::__wasi_fdflags_t, ) -> wasm32::__wasi_errno_t { @@ -300,9 +292,7 @@ pub unsafe fn fd_fdstat_set_flags( let host_fdflags = dec_fdflags(fdflags); let nix_flags = host::nix_from_fdflags(host_fdflags); - let ctx = vmctx.get_wasi_ctx(); - - if let Some(fe) = ctx.fds.get(&host_fd) { + if let Some(fe) = wasi_ctx.fds.get(&host_fd) { match nix::fcntl::fcntl(fe.fd_object.rawfd, nix::fcntl::F_SETFL(nix_flags)) { Ok(_) => wasm32::__WASI_ESUCCESS, Err(e) => wasm32::errno_from_nix(e.as_errno().unwrap()), @@ -312,14 +302,14 @@ pub unsafe fn fd_fdstat_set_flags( } } -pub unsafe fn fd_seek( - vmctx: &mut VmContextView, +pub fn fd_seek( + wasi_ctx: &WasiCtx, + memory: &mut [u8], fd: wasm32::__wasi_fd_t, offset: wasm32::__wasi_filedelta_t, whence: wasm32::__wasi_whence_t, newoffset: wasm32::uintptr_t, ) -> wasm32::__wasi_errno_t { - let ctx = vmctx.get_wasi_ctx(); let fd = dec_fd(fd); let offset = dec_filedelta(offset); let whence = dec_whence(whence); @@ -338,7 +328,7 @@ pub unsafe fn fd_seek( } else { host::__WASI_RIGHT_FD_SEEK | host::__WASI_RIGHT_FD_TELL }; - match ctx.get_fd_entry(fd, rights.into(), 0) { + match wasi_ctx.get_fd_entry(fd, rights.into(), 0) { Ok(fe) => match lseek(fe.fd_object.rawfd, offset, nwhence) { Ok(newoffset) => newoffset, Err(e) => return wasm32::errno_from_nix(e.as_errno().unwrap()), @@ -348,21 +338,21 @@ pub unsafe fn fd_seek( }; unsafe { - enc_filesize_byref(vmctx, newoffset, host_newoffset as u64) + enc_filesize_byref(memory, newoffset, host_newoffset as u64) .map(|_| wasm32::__WASI_ESUCCESS) .unwrap_or_else(|e| e) } } -pub unsafe fn fd_prestat_get( - vmctx: &mut VmContextView, +pub fn fd_prestat_get( + wasi_ctx: &WasiCtx, + memory: &mut [u8], fd: wasm32::__wasi_fd_t, prestat_ptr: wasm32::uintptr_t, ) -> wasm32::__wasi_errno_t { - let ctx = vmctx.get_wasi_ctx(); let fd = dec_fd(fd); // TODO: is this the correct right for this? - match ctx.get_fd_entry(fd, host::__WASI_RIGHT_PATH_OPEN.into(), 0) { + match wasi_ctx.get_fd_entry(fd, host::__WASI_RIGHT_PATH_OPEN.into(), 0) { Ok(fe) => { if let Some(po_path) = &fe.preopen_path { if fe.fd_object.ty != host::__WASI_FILETYPE_DIRECTORY { @@ -370,7 +360,7 @@ pub unsafe fn fd_prestat_get( } unsafe { enc_prestat_byref( - vmctx, + memory, prestat_ptr, host::__wasi_prestat_t { pr_type: host::__WASI_PREOPENTYPE_DIR, @@ -393,18 +383,16 @@ pub unsafe fn fd_prestat_get( } } -pub unsafe fn fd_prestat_dir_name( - vmctx: &mut VmContextView, +pub fn fd_prestat_dir_name( + wasi_ctx: &WasiCtx, + memory: &mut [u8], fd: wasm32::__wasi_fd_t, path_ptr: wasm32::uintptr_t, path_len: wasm32::size_t, ) -> wasm32::__wasi_errno_t { let fd = dec_fd(fd); - match vmctx - .get_wasi_ctx() - .get_fd_entry(fd, host::__WASI_RIGHT_PATH_OPEN.into(), 0) - { + match wasi_ctx.get_fd_entry(fd, host::__WASI_RIGHT_PATH_OPEN.into(), 0) { Ok(fe) => { if let Some(po_path) = &fe.preopen_path { if fe.fd_object.ty != host::__WASI_FILETYPE_DIRECTORY { @@ -415,7 +403,7 @@ pub unsafe fn fd_prestat_dir_name( return wasm32::__WASI_ENAMETOOLONG; } unsafe { - enc_slice_of(vmctx, path_bytes, path_ptr) + enc_slice_of(memory, path_bytes, path_ptr) .map(|_| wasm32::__WASI_ESUCCESS) .unwrap_or_else(|e| e) } @@ -427,8 +415,9 @@ pub unsafe fn fd_prestat_dir_name( } } -pub unsafe fn fd_read( - vmctx: &mut VmContextView, +pub fn fd_read( + wasi_ctx: &mut WasiCtx, + memory: &mut [u8], fd: wasm32::__wasi_fd_t, iovs_ptr: wasm32::uintptr_t, iovs_len: wasm32::size_t, @@ -437,13 +426,12 @@ pub unsafe fn fd_read( use nix::sys::uio::{readv, IoVec}; let fd = dec_fd(fd); - let mut iovs = match unsafe { dec_ciovec_slice(vmctx, iovs_ptr, iovs_len) } { + let mut iovs = match unsafe { dec_ciovec_slice(memory, iovs_ptr, iovs_len) } { Ok(iovs) => iovs, Err(e) => return enc_errno(e), }; - let mut ctx = vmctx.get_wasi_ctx_mut(); - let fe = match ctx.get_fd_entry(fd, host::__WASI_RIGHT_FD_READ.into(), 0) { + let fe = match wasi_ctx.get_fd_entry(fd, host::__WASI_RIGHT_FD_READ.into(), 0) { Ok(fe) => fe, Err(e) => return enc_errno(e), }; @@ -460,19 +448,20 @@ pub unsafe fn fd_read( if host_nread == 0 { // we hit eof, so remove the fdentry from the context - let mut fe = ctx.fds.remove(&fd).expect("file entry is still there"); + let mut fe = wasi_ctx.fds.remove(&fd).expect("file entry is still there"); fe.fd_object.needs_close = false; } unsafe { - enc_usize_byref(vmctx, nread, host_nread) + enc_usize_byref(memory, nread, host_nread) .map(|_| wasm32::__WASI_ESUCCESS) .unwrap_or_else(|e| e) } } -pub unsafe fn fd_write( - vmctx: &mut VmContextView, +pub fn fd_write( + wasi_ctx: &WasiCtx, + memory: &mut [u8], fd: wasm32::__wasi_fd_t, iovs_ptr: wasm32::uintptr_t, iovs_len: wasm32::size_t, @@ -481,13 +470,12 @@ pub unsafe fn fd_write( use nix::sys::uio::{writev, IoVec}; let fd = dec_fd(fd); - let iovs = match unsafe { dec_ciovec_slice(vmctx, iovs_ptr, iovs_len) } { + let iovs = match unsafe { dec_ciovec_slice(memory, iovs_ptr, iovs_len) } { Ok(iovs) => iovs, Err(e) => return enc_errno(e), }; - let ctx = vmctx.get_wasi_ctx(); - let fe = match ctx.get_fd_entry(fd, host::__WASI_RIGHT_FD_WRITE.into(), 0) { + let fe = match wasi_ctx.get_fd_entry(fd, host::__WASI_RIGHT_FD_WRITE.into(), 0) { Ok(fe) => fe, Err(e) => return enc_errno(e), }; @@ -503,14 +491,15 @@ pub unsafe fn fd_write( }; unsafe { - enc_usize_byref(vmctx, nwritten, host_nwritten) + enc_usize_byref(memory, nwritten, host_nwritten) .map(|_| wasm32::__WASI_ESUCCESS) .unwrap_or_else(|e| e) } } -pub unsafe fn path_open( - vmctx: &mut VmContextView, +pub fn path_open( + wasi_ctx: &mut WasiCtx, + memory: &mut [u8], dirfd: wasm32::__wasi_fd_t, dirflags: wasm32::__wasi_lookupflags_t, path_ptr: wasm32::uintptr_t, @@ -575,13 +564,14 @@ pub unsafe fn path_open( needed_inheriting |= host::__WASI_RIGHT_FD_SYNC; } - let path = match unsafe { dec_slice_of::(vmctx, path_ptr, path_len) } { + let path = match unsafe { dec_slice_of::(memory, path_ptr, path_len) } { Ok((ptr, len)) => OsStr::from_bytes(unsafe { std::slice::from_raw_parts(ptr, len) }), Err(e) => return enc_errno(e), }; let (dir, path) = match path_get( - &*vmctx, + wasi_ctx, + memory, dirfd, dirflags, path, @@ -633,7 +623,7 @@ pub unsafe fn path_open( let mut fe = unsafe { FdEntry::from_raw_fd(new_fd) }; fe.rights_base &= max_base; fe.rights_inheriting &= max_inheriting; - match vmctx.get_wasi_ctx_mut().insert_fd_entry(fe) { + match wasi_ctx.insert_fd_entry(fe) { Ok(fd) => fd, Err(e) => return enc_errno(e), } @@ -641,21 +631,21 @@ pub unsafe fn path_open( }; unsafe { - enc_fd_byref(vmctx, fd_out_ptr, guest_fd) + enc_fd_byref(memory, fd_out_ptr, guest_fd) .map(|_| wasm32::__WASI_ESUCCESS) .unwrap_or_else(|e| e) } } -pub unsafe fn random_get( - vmctx: &mut VmContextView, +pub fn random_get( + memory: &mut [u8], buf_ptr: wasm32::uintptr_t, buf_len: wasm32::size_t, ) -> wasm32::__wasi_errno_t { use rand::{thread_rng, RngCore}; let buf_len = dec_usize(buf_len); - let buf_ptr = match unsafe { dec_ptr(vmctx, buf_ptr, buf_len) } { + let buf_ptr = match unsafe { dec_ptr(memory, buf_ptr, buf_len) } { Ok(ptr) => ptr, Err(e) => return enc_errno(e), }; @@ -667,8 +657,8 @@ pub unsafe fn random_get( return wasm32::__WASI_ESUCCESS; } -pub unsafe fn poll_oneoff( - vmctx: &mut VmContextView, +pub fn poll_oneoff( + memory: &mut [u8], input: wasm32::uintptr_t, output: wasm32::uintptr_t, nsubscriptions: wasm32::size_t, @@ -677,14 +667,14 @@ pub unsafe fn poll_oneoff( if nsubscriptions as u64 > wasm32::__wasi_filesize_t::max_value() { return wasm32::__WASI_EINVAL; } - unsafe { enc_pointee(vmctx, nevents, 0) }.unwrap(); + unsafe { enc_pointee(memory, nevents, 0) }.unwrap(); let input_slice_ = - unsafe { dec_slice_of::(vmctx, input, nsubscriptions) } + unsafe { dec_slice_of::(memory, input, nsubscriptions) } .unwrap(); let input_slice = unsafe { slice::from_raw_parts(input_slice_.0, input_slice_.1) }; let output_slice_ = - unsafe { dec_slice_of::(vmctx, output, nsubscriptions) }.unwrap(); + unsafe { dec_slice_of::(memory, output, nsubscriptions) }.unwrap(); let output_slice = unsafe { slice::from_raw_parts_mut(output_slice_.0, output_slice_.1) }; let input: Vec<_> = input_slice.iter().map(|x| dec_subscription(x)).collect(); @@ -750,29 +740,29 @@ pub unsafe fn poll_oneoff( } }; if ready == 0 { - return poll_oneoff_handle_timeout_event(&mut *vmctx, output_slice, nevents, timeout); + return poll_oneoff_handle_timeout_event(memory, output_slice, nevents, timeout); } let events = fd_events.iter().zip(poll_fds.iter()).take(ready); - poll_oneoff_handle_fd_event(&mut *vmctx, output_slice, nevents, events) + poll_oneoff_handle_fd_event(memory, output_slice, nevents, events) } -pub unsafe fn fd_filestat_get( - vmctx: &mut VmContextView, +pub fn fd_filestat_get( + wasi_ctx: &WasiCtx, + memory: &mut [u8], fd: wasm32::__wasi_fd_t, filestat_ptr: wasm32::uintptr_t, ) -> wasm32::__wasi_errno_t { use nix::sys::stat::fstat; let host_fd = dec_fd(fd); - let ctx = vmctx.get_wasi_ctx_mut(); - let errno = if let Some(fe) = ctx.fds.get(&host_fd) { + let errno = if let Some(fe) = wasi_ctx.fds.get(&host_fd) { match fstat(fe.fd_object.rawfd) { Err(e) => wasm32::errno_from_nix(e.as_errno().unwrap()), Ok(filestat) => { let host_filestat = host::filestat_from_nix(filestat); unsafe { - enc_filestat_byref(vmctx, filestat_ptr, host_filestat) + enc_filestat_byref(memory, filestat_ptr, host_filestat) .expect("can write into the pointer"); } wasm32::__WASI_ESUCCESS @@ -784,8 +774,9 @@ pub unsafe fn fd_filestat_get( errno } -pub unsafe fn path_filestat_get( - vmctx: &mut VmContextView, +pub fn path_filestat_get( + wasi_ctx: &WasiCtx, + memory: &mut [u8], dirfd: wasm32::__wasi_fd_t, dirflags: wasm32::__wasi_lookupflags_t, path_ptr: wasm32::uintptr_t, @@ -797,12 +788,13 @@ pub unsafe fn path_filestat_get( let dirfd = dec_fd(dirfd); let dirflags = dec_lookupflags(dirflags); - let path = match unsafe { dec_slice_of::(vmctx, path_ptr, path_len) } { + let path = match unsafe { dec_slice_of::(memory, path_ptr, path_len) } { Ok((ptr, len)) => OsStr::from_bytes(unsafe { std::slice::from_raw_parts(ptr, len) }), Err(e) => return enc_errno(e), }; let (dir, path) = match path_get( - &*vmctx, + wasi_ctx, + memory, dirfd, dirflags, path, @@ -822,7 +814,7 @@ pub unsafe fn path_filestat_get( Ok(filestat) => { let host_filestat = host::filestat_from_nix(filestat); unsafe { - enc_filestat_byref(vmctx, filestat_ptr, host_filestat) + enc_filestat_byref(memory, filestat_ptr, host_filestat) .expect("can write into the pointer"); } wasm32::__WASI_ESUCCESS @@ -830,8 +822,9 @@ pub unsafe fn path_filestat_get( } } -pub unsafe fn path_create_directory( - vmctx: &mut VmContextView, +pub fn path_create_directory( + wasi_ctx: &WasiCtx, + memory: &mut [u8], dirfd: wasm32::__wasi_fd_t, path_ptr: wasm32::uintptr_t, path_len: wasm32::size_t, @@ -840,12 +833,13 @@ pub unsafe fn path_create_directory( use nix::libc::mkdirat; let dirfd = dec_fd(dirfd); - let path = match unsafe { dec_slice_of::(vmctx, path_ptr, path_len) } { + let path = match unsafe { dec_slice_of::(memory, path_ptr, path_len) } { Ok((ptr, len)) => OsStr::from_bytes(unsafe { std::slice::from_raw_parts(ptr, len) }), Err(e) => return enc_errno(e), }; let (dir, path) = match path_get( - &*vmctx, + wasi_ctx, + memory, dirfd, 0, path, @@ -867,8 +861,9 @@ pub unsafe fn path_create_directory( } } -pub unsafe fn path_unlink_file( - vmctx: &mut VmContextView, +pub fn path_unlink_file( + wasi_ctx: &WasiCtx, + memory: &mut [u8], dirfd: wasm32::__wasi_fd_t, path_ptr: wasm32::uintptr_t, path_len: wasm32::size_t, @@ -877,12 +872,13 @@ pub unsafe fn path_unlink_file( use nix::libc::unlinkat; let dirfd = dec_fd(dirfd); - let path = match unsafe { dec_slice_of::(vmctx, path_ptr, path_len) } { + let path = match unsafe { dec_slice_of::(memory, path_ptr, path_len) } { Ok((ptr, len)) => OsStr::from_bytes(unsafe { std::slice::from_raw_parts(ptr, len) }), Err(e) => return enc_errno(e), }; let (dir, path) = match path_get( - &*vmctx, + wasi_ctx, + memory, dirfd, 0, path, @@ -904,15 +900,17 @@ pub unsafe fn path_unlink_file( } } -pub unsafe fn fd_datasync( - vmctx: &mut VmContextView, +pub fn fd_datasync( + wasi_ctx: &WasiCtx, + memory: &mut [u8], fd: wasm32::__wasi_fd_t, ) -> wasm32::__wasi_errno_t { unimplemented!("fd_datasync") } -pub unsafe fn fd_pread( - vmctx: &mut VmContextView, +pub fn fd_pread( + wasi_ctx: &WasiCtx, + memory: &mut [u8], fd: wasm32::__wasi_fd_t, iovs: wasm32::uintptr_t, iovs_len: wasm32::size_t, @@ -922,8 +920,9 @@ pub unsafe fn fd_pread( unimplemented!("fd_pread") } -pub unsafe fn fd_pwrite( - vmctx: &mut VmContextView, +pub fn fd_pwrite( + wasi_ctx: &WasiCtx, + memory: &mut [u8], fd: wasm32::__wasi_fd_t, iovs: wasm32::uintptr_t, iovs_len: wasm32::size_t, @@ -933,24 +932,27 @@ pub unsafe fn fd_pwrite( unimplemented!("fd_pwrite") } -pub unsafe fn fd_renumber( - vmctx: &mut VmContextView, +pub fn fd_renumber( + wasi_ctx: &WasiCtx, + memory: &mut [u8], from: wasm32::__wasi_fd_t, to: wasm32::__wasi_fd_t, ) -> wasm32::__wasi_errno_t { unimplemented!("fd_renumber") } -pub unsafe fn fd_tell( - vmctx: &mut VmContextView, +pub fn fd_tell( + wasi_ctx: &WasiCtx, + memory: &mut [u8], fd: wasm32::__wasi_fd_t, newoffset: wasm32::uintptr_t, ) -> wasm32::__wasi_errno_t { unimplemented!("fd_tell") } -pub unsafe fn fd_fdstat_set_rights( - vmctx: &mut VmContextView, +pub fn fd_fdstat_set_rights( + wasi_ctx: &WasiCtx, + memory: &mut [u8], fd: wasm32::__wasi_fd_t, fs_rights_base: wasm32::__wasi_rights_t, fs_rights_inheriting: wasm32::__wasi_rights_t, @@ -958,15 +960,17 @@ pub unsafe fn fd_fdstat_set_rights( unimplemented!("fd_fdstat_set_rights") } -pub unsafe fn fd_sync( - vmctx: &mut VmContextView, +pub fn fd_sync( + wasi_ctx: &WasiCtx, + memory: &mut [u8], fd: wasm32::__wasi_fd_t, ) -> wasm32::__wasi_errno_t { unimplemented!("fd_sync") } -pub unsafe fn fd_advise( - vmctx: &mut VmContextView, +pub fn fd_advise( + wasi_ctx: &WasiCtx, + memory: &mut [u8], fd: wasm32::__wasi_fd_t, offset: wasm32::__wasi_filesize_t, len: wasm32::__wasi_filesize_t, @@ -975,8 +979,9 @@ pub unsafe fn fd_advise( unimplemented!("fd_advise") } -pub unsafe fn fd_allocate( - vmctx: &mut VmContextView, +pub fn fd_allocate( + wasi_ctx: &WasiCtx, + memory: &mut [u8], fd: wasm32::__wasi_fd_t, offset: wasm32::__wasi_filesize_t, len: wasm32::__wasi_filesize_t, @@ -984,8 +989,9 @@ pub unsafe fn fd_allocate( unimplemented!("fd_allocate") } -pub unsafe fn path_link( - vmctx: &mut VmContextView, +pub fn path_link( + wasi_ctx: &WasiCtx, + memory: &mut [u8], fd0: wasm32::__wasi_fd_t, flags0: wasm32::__wasi_lookupflags_t, path0: wasm32::uintptr_t, @@ -997,8 +1003,9 @@ pub unsafe fn path_link( unimplemented!("path_link") } -pub unsafe fn fd_readdir( - vmctx: &mut VmContextView, +pub fn fd_readdir( + wasi_ctx: &WasiCtx, + memory: &mut [u8], fd: wasm32::__wasi_fd_t, buf: wasm32::uintptr_t, buf_len: wasm32::size_t, @@ -1008,8 +1015,9 @@ pub unsafe fn fd_readdir( unimplemented!("fd_readdir") } -pub unsafe fn path_readlink( - vmctx: &mut VmContextView, +pub fn path_readlink( + wasi_ctx: &WasiCtx, + memory: &mut [u8], fd: wasm32::__wasi_fd_t, path: wasm32::uintptr_t, path_len: wasm32::size_t, @@ -1020,8 +1028,9 @@ pub unsafe fn path_readlink( unimplemented!("path_readlink") } -pub unsafe fn path_rename( - vmctx: &mut VmContextView, +pub fn path_rename( + wasi_ctx: &WasiCtx, + memory: &mut [u8], fd0: wasm32::__wasi_fd_t, path0: wasm32::uintptr_t, path_len0: wasm32::size_t, @@ -1032,8 +1041,9 @@ pub unsafe fn path_rename( unimplemented!("path_rename") } -pub unsafe fn fd_filestat_set_times( - vmctx: &mut VmContextView, +pub fn fd_filestat_set_times( + wasi_ctx: &WasiCtx, + memory: &mut [u8], fd: wasm32::__wasi_fd_t, st_atim: wasm32::__wasi_timestamp_t, st_mtim: wasm32::__wasi_timestamp_t, @@ -1042,16 +1052,18 @@ pub unsafe fn fd_filestat_set_times( unimplemented!("fd_filestat_set_times") } -pub unsafe fn fd_filestat_set_size( - vmctx: &mut VmContextView, +pub fn fd_filestat_set_size( + wasi_ctx: &WasiCtx, + memory: &mut [u8], fd: wasm32::__wasi_fd_t, size: wasm32::__wasi_filesize_t, ) -> wasm32::__wasi_errno_t { unimplemented!("fd_filestat_set_size") } -pub unsafe fn path_filestat_set_times( - vmctx: &mut VmContextView, +pub fn path_filestat_set_times( + wasi_ctx: &WasiCtx, + memory: &mut [u8], fd: wasm32::__wasi_fd_t, flags: wasm32::__wasi_lookupflags_t, path: wasm32::uintptr_t, @@ -1063,8 +1075,9 @@ pub unsafe fn path_filestat_set_times( unimplemented!("path_filestat_set_times") } -pub unsafe fn path_symlink( - vmctx: &mut VmContextView, +pub fn path_symlink( + wasi_ctx: &WasiCtx, + memory: &mut [u8], path0: wasm32::uintptr_t, path_len0: wasm32::size_t, fd: wasm32::__wasi_fd_t, @@ -1074,8 +1087,9 @@ pub unsafe fn path_symlink( unimplemented!("path_symlink") } -pub unsafe fn path_remove_directory( - vmctx: &mut VmContextView, +pub fn path_remove_directory( + wasi_ctx: &WasiCtx, + memory: &mut [u8], fd: wasm32::__wasi_fd_t, path: wasm32::uintptr_t, path_len: wasm32::size_t, @@ -1083,19 +1097,21 @@ pub unsafe fn path_remove_directory( unimplemented!("path_remove_directory") } -pub unsafe fn proc_raise( - _vmctx: &mut VmContextView, - _sig: wasm32::__wasi_signal_t, +pub fn proc_raise( + wasi_ctx: &WasiCtx, + memory: &mut [u8], + sig: wasm32::__wasi_signal_t, ) -> wasm32::__wasi_errno_t { unimplemented!("proc_raise") } -pub unsafe fn sched_yield(_vmctx: &mut VmContextView) -> wasm32::__wasi_errno_t { +pub fn sched_yield() -> wasm32::__wasi_errno_t { unimplemented!("sched_yield") } -pub unsafe fn sock_recv( - vmctx: &mut VmContextView, +pub fn sock_recv( + wasi_ctx: &WasiCtx, + memory: &mut [u8], sock: wasm32::__wasi_fd_t, ri_data: wasm32::uintptr_t, ri_data_len: wasm32::size_t, @@ -1106,8 +1122,9 @@ pub unsafe fn sock_recv( unimplemented!("sock_recv") } -pub unsafe fn sock_send( - vmctx: &mut VmContextView, +pub fn sock_send( + wasi_ctx: &WasiCtx, + memory: &mut [u8], sock: wasm32::__wasi_fd_t, si_data: wasm32::uintptr_t, si_data_len: wasm32::size_t, @@ -1117,8 +1134,9 @@ pub unsafe fn sock_send( unimplemented!("sock_send") } -pub unsafe fn sock_shutdown( - vmctx: &mut VmContextView, +pub fn sock_shutdown( + wasi_ctx: &WasiCtx, + memory: &mut [u8], sock: wasm32::__wasi_fd_t, how: wasm32::__wasi_sdflags_t, ) -> wasm32::__wasi_errno_t { @@ -1155,7 +1173,7 @@ struct FdEventData { } fn poll_oneoff_handle_timeout_event( - vmctx: &mut VmContextView, + memory: &mut [u8], output_slice: &mut [wasm32::__wasi_event_t], nevents: wasm32::uintptr_t, timeout: Option, @@ -1173,12 +1191,12 @@ fn poll_oneoff_handle_timeout_event( }, }; output_slice[0] = enc_event(output_event); - if let Err(e) = unsafe { enc_pointee(vmctx, nevents, 1) } { + if let Err(e) = unsafe { enc_pointee(memory, nevents, 1) } { return enc_errno(e); } } else { // shouldn't happen - if let Err(e) = unsafe { enc_pointee(vmctx, nevents, 0) } { + if let Err(e) = unsafe { enc_pointee(memory, nevents, 0) } { return enc_errno(e); } } @@ -1186,7 +1204,7 @@ fn poll_oneoff_handle_timeout_event( } fn poll_oneoff_handle_fd_event<'t>( - vmctx: &mut VmContextView, + memory: &mut [u8], output_slice: &mut [wasm32::__wasi_event_t], nevents: wasm32::uintptr_t, events: impl Iterator, @@ -1262,7 +1280,7 @@ fn poll_oneoff_handle_fd_event<'t>( *output_slice_cur.next().unwrap() = enc_event(output_event); revents_count += 1; } - if let Err(e) = unsafe { enc_pointee(vmctx, nevents, revents_count) } { + if let Err(e) = unsafe { enc_pointee(memory, nevents, revents_count) } { return enc_errno(e); } wasm32::__WASI_ESUCCESS @@ -1272,7 +1290,8 @@ fn poll_oneoff_handle_fd_event<'t>( /// /// This is a workaround for not having Capsicum support in the OS. pub fn path_get>( - vmctx: &VmContextView, + wasi_ctx: &WasiCtx, + memory: &mut [u8], dirfd: host::__wasi_fd_t, dirflags: host::__wasi_lookupflags_t, path: P, @@ -1316,8 +1335,7 @@ pub fn path_get>( Err(errno) } - let ctx = vmctx.get_wasi_ctx(); - let dirfe = ctx.get_fd_entry(dirfd, needed_base, needed_inheriting)?; + let dirfe = wasi_ctx.get_fd_entry(dirfd, needed_base, needed_inheriting)?; // Stack of directory file descriptors. Index 0 always corresponds with the directory provided // to this function. Entering a directory causes a file descriptor to be pushed, while handling diff --git a/src/lib.rs b/src/lib.rs index 94ca4c5379..d98ff3a343 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,7 +25,6 @@ pub mod fdentry; pub mod host; pub mod hostcalls; pub mod memory; -pub mod vmctx; pub mod wasm32; pub use ctx::{WasiCtx, WasiCtxBuilder}; diff --git a/src/memory.rs b/src/memory.rs index 24b924e45b..2c283fd0aa 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -9,7 +9,6 @@ //! //! This sort of manual encoding will hopefully be obsolete once the IDL is developed. -use crate::vmctx::VmContextView; use crate::{host, wasm32}; use cast; @@ -24,54 +23,52 @@ macro_rules! bail_errno { } pub unsafe fn dec_ptr( - vmctx: &VmContextView, + memory: &mut [u8], ptr: wasm32::uintptr_t, len: usize, ) -> Result<*mut u8, host::__wasi_errno_t> { - let mut heap = vmctx.memory_mut(); - // check that `len` fits in the wasm32 address space if len > wasm32::UINTPTR_MAX as usize { bail_errno!(__WASI_EOVERFLOW); } // check that `ptr` and `ptr + len` are both within the guest heap - if ptr as usize > heap.len() || ptr as usize + len > heap.len() { + if ptr as usize > memory.len() || ptr as usize + len > memory.len() { bail_errno!(__WASI_EFAULT); } // translate the pointer - Ok(heap.as_mut_ptr().offset(ptr as isize)) + Ok(memory.as_mut_ptr().offset(ptr as isize)) } pub unsafe fn dec_ptr_to( - vmctx: &VmContextView, + memory: &mut [u8], ptr: wasm32::uintptr_t, ) -> Result<*mut T, host::__wasi_errno_t> { // check that the ptr is aligned if ptr as usize % align_of::() != 0 { bail_errno!(__WASI_EINVAL); } - dec_ptr(vmctx, ptr, size_of::()).map(|p| p as *mut T) + dec_ptr(memory, ptr, size_of::()).map(|p| p as *mut T) } pub unsafe fn dec_pointee( - vmctx: &VmContextView, + memory: &mut [u8], ptr: wasm32::uintptr_t, ) -> Result { - dec_ptr_to::(vmctx, ptr).map(|p| p.read()) + dec_ptr_to::(memory, ptr).map(|p| p.read()) } pub unsafe fn enc_pointee( - vmctx: &VmContextView, + memory: &mut [u8], ptr: wasm32::uintptr_t, t: T, ) -> Result<(), host::__wasi_errno_t> { - dec_ptr_to::(vmctx, ptr).map(|p| p.write(t)) + dec_ptr_to::(memory, ptr).map(|p| p.write(t)) } pub unsafe fn dec_slice_of( - vmctx: &VmContextView, + memory: &mut [u8], ptr: wasm32::uintptr_t, len: wasm32::size_t, ) -> Result<(*mut T, usize), host::__wasi_errno_t> { @@ -86,13 +83,13 @@ pub unsafe fn dec_slice_of( return Err(host::__WASI_EOVERFLOW); }; - let ptr = dec_ptr(vmctx, ptr, len_bytes)? as *mut T; + let ptr = dec_ptr(memory, ptr, len_bytes)? as *mut T; Ok((ptr, len)) } pub unsafe fn enc_slice_of( - vmctx: &VmContextView, + memory: &mut [u8], slice: &[T], ptr: wasm32::uintptr_t, ) -> Result<(), host::__wasi_errno_t> { @@ -108,7 +105,7 @@ pub unsafe fn enc_slice_of( }; // get the pointer into guest memory, and copy the bytes - let ptr = dec_ptr(vmctx, ptr, len_bytes)? as *mut libc::c_void; + let ptr = dec_ptr(memory, ptr, len_bytes)? as *mut libc::c_void; libc::memcpy(ptr, slice.as_ptr() as *const libc::c_void, len_bytes); Ok(()) @@ -121,10 +118,10 @@ macro_rules! dec_enc_scalar { } pub unsafe fn $dec_byref( - vmctx: &VmContextView, + memory: &mut [u8], ptr: wasm32::uintptr_t, ) -> Result { - dec_pointee::(vmctx, ptr).map($dec) + dec_pointee::(memory, ptr).map($dec) } pub fn $enc(x: host::$ty) -> wasm32::$ty { @@ -132,34 +129,34 @@ macro_rules! dec_enc_scalar { } pub unsafe fn $enc_byref( - vmctx: &VmContextView, + memory: &mut [u8], ptr: wasm32::uintptr_t, x: host::$ty, ) -> Result<(), host::__wasi_errno_t> { - enc_pointee::(vmctx, ptr, $enc(x)) + enc_pointee::(memory, ptr, $enc(x)) } }; } pub unsafe fn dec_ciovec( - vmctx: &VmContextView, + memory: &mut [u8], ciovec: &wasm32::__wasi_ciovec_t, ) -> Result { let len = dec_usize(ciovec.buf_len); Ok(host::__wasi_ciovec_t { - buf: dec_ptr(vmctx, ciovec.buf, len)? as *const host::void, + buf: dec_ptr(memory, ciovec.buf, len)? as *const host::void, buf_len: len, }) } pub unsafe fn dec_ciovec_slice( - vmctx: &VmContextView, + memory: &mut [u8], ptr: wasm32::uintptr_t, len: wasm32::size_t, ) -> Result, host::__wasi_errno_t> { - let slice = dec_slice_of::(vmctx, ptr, len)?; + let slice = dec_slice_of::(memory, ptr, len)?; let slice = slice::from_raw_parts(slice.0, slice.1); - slice.iter().map(|iov| dec_ciovec(vmctx, iov)).collect() + slice.iter().map(|iov| dec_ciovec(memory, iov)).collect() } dec_enc_scalar!( @@ -227,10 +224,10 @@ pub fn dec_filestat(filestat: wasm32::__wasi_filestat_t) -> host::__wasi_filesta } pub unsafe fn dec_filestat_byref( - vmctx: &VmContextView, + memory: &mut [u8], filestat_ptr: wasm32::uintptr_t, ) -> Result { - dec_pointee::(vmctx, filestat_ptr).map(dec_filestat) + dec_pointee::(memory, filestat_ptr).map(dec_filestat) } pub fn enc_filestat(filestat: host::__wasi_filestat_t) -> wasm32::__wasi_filestat_t { @@ -247,12 +244,12 @@ pub fn enc_filestat(filestat: host::__wasi_filestat_t) -> wasm32::__wasi_filesta } pub unsafe fn enc_filestat_byref( - vmctx: &VmContextView, + memory: &mut [u8], filestat_ptr: wasm32::uintptr_t, host_filestat: host::__wasi_filestat_t, ) -> Result<(), host::__wasi_errno_t> { let filestat = enc_filestat(host_filestat); - enc_pointee::(vmctx, filestat_ptr, filestat) + enc_pointee::(memory, filestat_ptr, filestat) } pub fn dec_fdstat(fdstat: wasm32::__wasi_fdstat_t) -> host::__wasi_fdstat_t { @@ -265,10 +262,10 @@ pub fn dec_fdstat(fdstat: wasm32::__wasi_fdstat_t) -> host::__wasi_fdstat_t { } pub unsafe fn dec_fdstat_byref( - vmctx: &VmContextView, + memory: &mut [u8], fdstat_ptr: wasm32::uintptr_t, ) -> Result { - dec_pointee::(vmctx, fdstat_ptr).map(dec_fdstat) + dec_pointee::(memory, fdstat_ptr).map(dec_fdstat) } pub fn enc_fdstat(fdstat: host::__wasi_fdstat_t) -> wasm32::__wasi_fdstat_t { @@ -282,12 +279,12 @@ pub fn enc_fdstat(fdstat: host::__wasi_fdstat_t) -> wasm32::__wasi_fdstat_t { } pub unsafe fn enc_fdstat_byref( - vmctx: &VmContextView, + memory: &mut [u8], fdstat_ptr: wasm32::uintptr_t, host_fdstat: host::__wasi_fdstat_t, ) -> Result<(), host::__wasi_errno_t> { let fdstat = enc_fdstat(host_fdstat); - enc_pointee::(vmctx, fdstat_ptr, fdstat) + enc_pointee::(memory, fdstat_ptr, fdstat) } dec_enc_scalar!( @@ -349,10 +346,10 @@ pub fn dec_prestat( } pub unsafe fn dec_prestat_byref( - vmctx: &VmContextView, + memory: &mut [u8], prestat_ptr: wasm32::uintptr_t, ) -> Result { - dec_pointee::(vmctx, prestat_ptr).and_then(dec_prestat) + dec_pointee::(memory, prestat_ptr).and_then(dec_prestat) } pub fn enc_prestat( @@ -375,12 +372,12 @@ pub fn enc_prestat( } pub unsafe fn enc_prestat_byref( - vmctx: &VmContextView, + memory: &mut [u8], prestat_ptr: wasm32::uintptr_t, host_prestat: host::__wasi_prestat_t, ) -> Result<(), host::__wasi_errno_t> { let prestat = enc_prestat(host_prestat)?; - enc_pointee::(vmctx, prestat_ptr, prestat) + enc_pointee::(memory, prestat_ptr, prestat) } dec_enc_scalar!( @@ -407,11 +404,11 @@ pub fn enc_usize(size: usize) -> wasm32::size_t { } pub unsafe fn enc_usize_byref( - vmctx: &VmContextView, + memory: &mut [u8], usize_ptr: wasm32::uintptr_t, host_usize: usize, ) -> Result<(), host::__wasi_errno_t> { - enc_pointee::(vmctx, usize_ptr, enc_usize(host_usize)) + enc_pointee::(memory, usize_ptr, enc_usize(host_usize)) } dec_enc_scalar!( diff --git a/src/vmctx.rs b/src/vmctx.rs deleted file mode 100644 index a3a8ae6af9..0000000000 --- a/src/vmctx.rs +++ /dev/null @@ -1,59 +0,0 @@ -//! This code borrows heavily from Lucet's Vmctx implementation -//! https://github.com/fastly/lucet/blob/master/lucet-runtime/lucet-runtime-internals/src/vmctx.rs - -use crate::ctx::WasiCtx; -use std::borrow::{Borrow, BorrowMut}; -use std::cell::{Ref, RefCell, RefMut}; - -pub trait AsVmContextView { - unsafe fn as_vm_context_view(&mut self) -> VmContextView; -} - -#[derive(Debug)] -pub struct VmContextView { - pub memory_view: RefCell>, - pub wasi_ctx_view: RefCell>, -} - -impl Drop for VmContextView { - fn drop(&mut self) { - let memory_view = self.memory_view.replace(Box::new([])); - let wasi_ctx_view = self.wasi_ctx_view.replace(Box::new(WasiCtx::default())); - Box::leak(memory_view); - Box::leak(wasi_ctx_view); - } -} - -impl VmContextView { - pub fn memory(&self) -> Ref<[u8]> { - let r = self - .memory_view - .try_borrow() - .expect("memory not already borrowed mutably"); - Ref::map(r, |b| b.borrow()) - } - - pub fn memory_mut(&self) -> RefMut<[u8]> { - let r = self - .memory_view - .try_borrow_mut() - .expect("memory not already borrowed"); - RefMut::map(r, |b| b.borrow_mut()) - } - - pub fn get_wasi_ctx(&self) -> Ref { - let r = self - .wasi_ctx_view - .try_borrow() - .expect("WASI context not already borrowed mutably"); - Ref::map(r, |b| b.borrow()) - } - - pub fn get_wasi_ctx_mut(&self) -> RefMut { - let r = self - .wasi_ctx_view - .try_borrow_mut() - .expect("WASI context not already borrowed"); - RefMut::map(r, |b| b.borrow_mut()) - } -}