* Reimplement `wasmtime-wasi` on top of `wasmtime`
This commit reimplements the `wasmtime-wasi` crate on top of the
`wasmtime` API crate, instead of being placed on top of the `wasmtime-*`
family of internal crates. The purpose here is to continue to exercise
the API as well as avoid usage of internals wherever possible and
instead use the safe API as much as possible.
The `wasmtime-wasi` crate's API has been updated as part of this PR as
well. The general outline of it is now:
* Each module snapshot has a `WasiCtxBuilder`, `WasiCtx`, and `Wasi`
type.
* The `WasiCtx*` types are reexported from `wasi-common`.
* The `Wasi` type is synthesized by the `wig` crate's procedural macro
* The `Wasi` type exposes one constructor which takes a `Store` and a
`WasiCtx`, and produces a `Wasi`
* Each `Wasi` struct fields for all the exported functions in that wasi
module. They're all public an they all have type `wasmtime::Func`
* The `Wasi` type has a `get_export` method to fetch an struct field by
name.
The intention here is that we can continue to make progress on #727 by
integrating WASI construction into the `Instance::new` experience, but
it requires everything to be part of the same system!
The main oddity required by the `wasmtime-wasi` crate is that it needs
access to the caller's `memory` export, if any. This is currently done
with a bit of a hack and is expected to go away once interface types are
more fully baked in.
* Remove now no-longer-necessary APIs from `wasmtime`
* rustfmt
* Rename to from_abi
* Reel in unsafety around `InstanceHandle`
This commit is an attempt, or at least is targeted at being a start, at
reeling in the unsafety around the `InstanceHandle` type. Currently this
type represents a sort of moral `Rc<Instance>` but is a bit more
specialized since the underlying memory is allocated through mmap.
Additionally, though, `InstanceHandle` exposes a fundamental flaw in its
safety by safetly allowing mutable access so long as you have `&mut
InstanceHandle`. This type, however, is trivially created by simply
cloning a `InstanceHandle` to get an owned reference. This means that
`&mut InstanceHandle` does not actually provide any guarantees about
uniqueness, so there's no more safety than `&InstanceHandle` itself.
This commit removes all `&mut self` APIs from `InstanceHandle`,
additionally removing some where `&self` was `unsafe` and `&mut self`
was safe (since it was trivial to subvert this "safety"). In doing so
interior mutability patterns are now used much more extensively through
structures such as `Table` and `Memory`. Additionally a number of
methods were refactored to be a bit clearer and use helper functions
where possible.
This is a relatively large commit unfortunately, but it snowballed very
quickly into touching quite a few places. My hope though is that this
will prevent developers working on wasmtime internals as well as
developers still yet to migrate to the `wasmtime` crate from falling
into trivial unsafe traps by accidentally using `&mut` when they can't.
All existing users relying on `&mut` will need to migrate to some form
of interior mutability, such as using `RefCell` or `Cell`.
This commit also additionally marks `InstanceHandle::new` as an `unsafe`
function. The rationale for this is that the `&mut`-safety is only the
beginning for the safety of `InstanceHandle`. In general the wasmtime
internals are extremely unsafe and haven't been audited for appropriate
usage of `unsafe`. Until that's done it's hoped that we can warn users
with this `unsafe` constructor and otherwise push users to the
`wasmtime` crate which we know is safe.
* Fix windows build
* Wrap up mutable memory state in one structure
Rather than having separate fields
* Use `Cell::set`, not `Cell::replace`, where possible
* Add a helper function for offsets from VMContext
* Fix a typo from merging
* rustfmt
* Use try_from, not as
* Tweak style of some setters
* Auto-generate shims for old `wasi_unstable` module
This commit is effectively just doing what #707 already did, but
applying it to the `snapshot_0` module as well. The end result is the
same, where we cut down on all the boilerplate in `snapshot_0` and bring
it in line with the main `wasi_snapshot_preview1` implementation. The
goal here is to make it easier to change the two in tandem since they're
both doing the same thing.
* Migrate `wasi_common::hostcalls` to a macro
This commit migrates the `hostcalls` module to being auto-generated by a
macro rather than duplicating a handwritten signature for each wasi
syscall.
* Auto-generate snapshot_0's `hostcalls` module
Similar to the previous commit, but for `snapshot_0`
* Delete the `wasi-common-cbindgen` crate
This is no longer needed with the hostcalls macro now, we can easily
fold the definition of the cbindgen macro into the same crate.
* Rustfmt
* Fix windows build errors
* Rustfmt
* Remove now no-longer-necessary code
* rustfmt
* Replace the global-exports mechanism with a caller-vmctx mechanism.
This eliminates the global exports mechanism, and instead adds a
caller-vmctx argument to wasm functions so that WASI can obtain the
memory and other things from the caller rather than looking them up in a
global registry.
This replaces #390.
* Fixup some merge conflicts
* Rustfmt
* Ensure VMContext is aligned to 16 bytes
With the removal of `global_exports` it "just so happens" that this
isn't happening naturally any more.
* Fixup some bugs with double vmctx in wasmtime crate
* Trampoline stub needed adjusting
* Use pointer type instead of always using I64 for caller vmctx
* Don't store `ir::Signature` in `Func` since we don't know the pointer
size at creation time.
* Skip the first 2 arguments in IR signatures since that's the two vmctx
parameters.
* Update cranelift to 0.56.0
* Handle more merge conflicts
* Rustfmt
Co-authored-by: Alex Crichton <alex@alexcrichton.com>
This commit introduces two small changes:
* it adds `gen_errno_strerror` to `wig` crate which generates a
`strerror` function for `__wasi_errno_t` directly from `*.witx`,
similarly to how it's done in the `wasi` crate
* it tweaks `WasiError` type to include the error message generated
with `strerror` when displaying the error
* Log str repr of WASI errno at trace level
This commit refactors `Error` enum, and adds logging of the WASI
errno string representation at the trace level. Now, when tracing
WASI syscalls, we will be greeted with a nicely formatted errno
value after each syscall:
```
path_open(...)
| *fd=5
| errno=ESUCCESS
```
This commit gets rid of `errno_from_nix`, `errno_from_win` and
`errno_from_host` helper fns in favour of direct `From` implementations
for the relevant types such as `yanix::Errno` and `winx::winerror::WinError`.
`errno_from_host` is replaced by a trait `FromRawOsError`.
* Back port changes to snapshot0
* Fix indentation in logs
* Update to the latest spec_testsuite and dependencies.
Update to target-lexicon 0.10, cranelift 0.54, wast 0.6, faerie 0.14,
and the latest spec_testsuite.
For wast and cranelift-wasm, update the code for API changes.
* Factor out the code for matching f32, f64, and v128.
This takes the idea from #802 to split out `f32_matches`, `f64_matches`,
and `v128_matches` functions, which better factor out the matching
functionality between scalar and vector.
This commit implements `fd_fdstat_set_flags` for Windows.
Additionally, it fixes a problem where `O_APPEND` was not working correctly
because `GENERIC_WRITE` was always being set; as a result, `FILE_WRITE_DATA`
could not be removed from the permission set to properly enable append-only
mode.
It also treats `O_TRUNC` with `O_APPEND` as an invalid argument error. This is
because Windows cannot support these two flags together. To support `O_TRUNC`,
the `GENERIC_WRITE` bit must be set for the file access flags. Setting this
bit will cause `FILE_WRITE_DATA` to be set, which will not properly treat the
file as append-only (it requires `FILE_APPEND_DATA` without `FILE_WRITE_DATA`).
* Fix path_open granting more rights than requested
* Add missing rights checks in: fd_fdstat_set_flags, fd_filestat_get, poll_oneoff
* Fix `open_scratch_directory` not requesting any rights.
* Properly request needed rights in various tests
* Add some extra trace-level logging
* Remove a no-op restriction of rights to the ones returned by
`determine_type_rights`. It was redundant, because `FdEntry:from`
internally also called `determine_type_rights` and only dropped some of them.
* Clean up fd_filestat_get implementation
This commit does 4 things:
* Adds `yanix::file::fstat`, a wrapper around `libc::fstat`.
* It essentially reverts 89fbde2 for Unix hosts -- in other words,
it brings back the use of `fstat` to obtain `libc::stat` from a
file descriptor, rather than relying on `std::fs::Metadata`. This
way, we reuse `host_impl::filestat_from_nix` in
`hostcalls_impl::fd_filestat_get` implementation rather than
unnecessarily duplicate code for converting filestats into
`__wasi_filestat_t`.
* Moves `crate::helpers::systemtime_to_timestamp` to Windows `host_impl`
module. It does the same thing with helpers which assist in converting
`std::fs::Metadata` into `__wasi_filestat_t`. This should retain symmetry
between *nix and Windows impls.
* Makes timestamp conversions in `host_impl::filestat_from_nix` fallible.
* Backport changes to snapshot0
* Signal no overflow with `from` rather than `as` cast
* Use thiserror proc macros for auto From impls
This commit refactors `wasi_common::error::Error` by using `#[from]`
proc macro to autoderive `From` for wrapped errors.
* Back port changes to snapshot0
* Auto impl Display for WasiError
* Fix stack overflow when auto generating Display for WasiError
* Initial support for securing tty I/O.
* Update the tests.
* Fix warnings
* Update crates/wasi-common/src/fdentry.rs
Co-Authored-By: Jakub Konka <jakub.konka@golem.network>
* Properly sandbox stderr.
* Document why the scratch buffer is 4 elements long.
* Update crates/wasi-common/src/sandboxed_tty_writer.rs
Co-Authored-By: Jakub Konka <jakub.konka@golem.network>
* Update crates/wasi-common/src/sandboxed_tty_writer.rs
Co-Authored-By: Jakub Konka <jakub.konka@golem.network>
* Add comments explaining how we report the number of bytes written.
* Always sanitize stderr.
* Port the changes to the snapshot_0 directory.
* Fix snapshot_0 compilation error.
* Replace the scratch buffer with a temporary buffer.
* Update crates/wasi-common/src/sandboxed_tty_writer.rs
Co-Authored-By: bjorn3 <bjorn3@users.noreply.github.com>
* Format with latest stable rustfmt.
Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
Co-authored-by: bjorn3 <bjorn3@users.noreply.github.com>
This commit uses the `*.witx` files describing the current wasi API to
reduce the boilerplate used to define implementations in the
`wasmtime-wasi` crate. Eventually I'd like to remove lots of boilerplate
in the `wasi-common` crate too, but this should at least be a good start!
The boilerplate removed here is:
* No need to list each function to add it to the
`wasmtime_runtime::Module` being created
* No need to list the signature of the function in a separate
`syscalls.rs` file.
Instead the `*.witx` file is processed in a single-use macro inside the
`wasmtime-wasi` crate. This macro uses the signatures known from
`*.witx` to automatically register with the right type in the wasm
module as well as define a wrapper that the wasm module will call into.
Functionally this is all the same as before, it's just defined in a
different way now!
The shim generated by this macro which wasmtime calls into only uses
`i32`/`i64`/etc wasm types, and it internally uses `as` casts to convert
to the right wasi types when delegating into the `wasi-common` crate.
One change was necessary to get this implemented, however. The functions
in `wasi-common` sometimes took `WasiCtx` and sometimes took a slice of
memory. After this PR they uniformly all require both `WasiCtx` and
memory so the wrappers can be auto-generated. The arguments are ignored
if they weren't previously required.