Improve the wasmtime crate's README (#4174)

* Improve the `wasmtime` crate's README

This commit is me finally getting back to #2688 and improving the README
of the `wasmtime` crate. Currently we have a [pretty drab README][drab]
that doesn't really convey what we want about Wasmtime.

While I was doing this I opted to update the feature list of Wasmtime as
well in the main README (which is mirrored into the crate readme),
namely adding a bullet point for "secure" which I felt was missing
relative to how we think about Wasmtime.

Naturally there's a lot of ways to paint this shed, so feedback is of
course welcome on this! (I'm not the best writer myself)

[drab]: https://crates.io/crates/wasmtime/0.37.0

* Expand the "Fast" bullet a bit more

* Reference the book from the wasmtime crate

* Update more security docs

Also merge the sandboxing security page with the main security page to
avoid the empty security page.
This commit is contained in:
Alex Crichton
2022-05-20 15:33:00 -05:00
committed by GitHub
parent 0824abbae4
commit a75f383f96
6 changed files with 285 additions and 100 deletions

View File

@@ -62,29 +62,48 @@ Hello, world!
## Features
* **Lightweight**. Wasmtime is a standalone runtime for WebAssembly that scales
with your needs. It fits on tiny chips as well as makes use of huge servers.
Wasmtime can be [embedded] into almost any application too.
* **Fast**. Wasmtime is built on the optimizing [Cranelift] code generator to
quickly generate high-quality machine code at runtime.
quickly generate high-quality machine code either at runtime or
ahead-of-time. Wasmtime's runtime is also optimized for cases such as
efficient instantiation, low-overhead transitions between the embedder and
wasm, and scalability of concurrent instances.
* **Configurable**. Whether you need to precompile your wasm ahead of time,
or interpret it at runtime, Wasmtime has you covered for all your
wasm-executing needs.
* **[Secure]**. Wasmtime's development is strongly focused on the correctness of
its implementation with 24/7 fuzzing donated by [Google's OSS Fuzz],
leveraging Rust's API and runtime safety guarantees, careful design of
features and APIs through an [RFC process], a [security policy] in place
for when things go wrong, and a [release policy] for patching older versions
as well. We follow best practices for defense-in-depth and known
protections and mitigations for issues like Spectre. Finally, we're working
to push the state-of-the-art by collaborating with academic
researchers to formally verify critical parts of Wasmtime and Cranelift.
* **WASI**. Wasmtime supports a rich set of APIs for interacting with the host
* **[Configurable]**. Wastime supports a rich set of APIs and build time
configuration to provide many options such as further means of restricting
WebAssembly beyond its basic guarantees such as its CPU and Memory
consumption. Wasmtime also runs in tiny environments all the way up to massive
servers with many concurrent instances.
* **[WASI]**. Wasmtime supports a rich set of APIs for interacting with the host
environment through the [WASI standard](https://wasi.dev).
* **Standards Compliant**. Wasmtime passes the [official WebAssembly test
* **[Standards Compliant]**. Wasmtime passes the [official WebAssembly test
suite](https://github.com/WebAssembly/testsuite), implements the [official C
API of wasm](https://github.com/WebAssembly/wasm-c-api), and implements
[future proposals to WebAssembly](https://github.com/WebAssembly/proposals) as
well. Wasmtime developers are intimately engaged with the WebAssembly
standards process all along the way too.
[Wasmtime]: https://github.com/bytecodealliance/wasmtime
[Cranelift]: https://github.com/bytecodealliance/wasmtime/blob/main/cranelift/README.md
[embedded]: https://bytecodealliance.github.io/wasmtime/lang.html
[Google's OSS Fuzz]: https://google.github.io/oss-fuzz/
[security policy]: https://bytecodealliance.org/security
[RFC process]: https://github.com/bytecodealliance/rfcs
[release policy]: https://docs.wasmtime.dev/stability-release.html
[Secure]: https://docs.wasmtime.dev/security.html
[Configurable]: https://docs.rs/wasmtime/latest/wasmtime/struct.Config.html
[WASI]: https://docs.rs/wasmtime-wasi/latest/wasmtime_wasi/
[Standards Compliant]: https://docs.wasmtime.dev/stability-wasm-proposals-support.html
## Language Support

View File

@@ -1,8 +1,119 @@
## Wasmtime Embedding API
<div align="center">
<h1><code>wasmtime</code></h1>
The `wasmtime` crate is an embedding API of the `wasmtime` WebAssembly runtime.
This is intended to be used in Rust projects and provides a high-level API of
working with WebAssembly modules.
<p>
<strong>A standalone runtime for
<a href="https://webassembly.org/">WebAssembly</a></strong>
</p>
If you're interested in embedding `wasmtime` in other languages, you may wish to
take a look a the [C embedding API](../c-api) instead!
<strong>A <a href="https://bytecodealliance.org/">Bytecode Alliance</a> project</strong>
</div>
## About
This crate is the Rust embedding API for the [Wasmtime] project: a
cross-platform engine for running WebAssembly programs. Notable features of
Wasmtime are:
* **Fast**. Wasmtime is built on the optimizing [Cranelift] code generator to
quickly generate high-quality machine code either at runtime or
ahead-of-time. Wasmtime's runtime is also optimized for cases such as
efficient instantiation, low-overhead transitions between the embedder and
wasm, and scalability of concurrent instances.
* **[Secure]**. Wasmtime's development is strongly focused on the correctness of
its implementation with 24/7 fuzzing donated by [Google's OSS Fuzz],
leveraging Rust's API and runtime safety guarantees, careful design of
features and APIs through an [RFC process], a [security policy] in place
for when things go wrong, and a [release policy] for patching older versions
as well. We follow best practices for defense-in-depth and known
protections and mitigations for issues like Spectre. Finally, we're working
to push the state-of-the-art by collaborating with academic
researchers to formally verify critical parts of Wasmtime and Cranelift.
* **[Configurable]**. Wastime supports a rich set of APIs and build time
configuration to provide many options such as further means of restricting
WebAssembly beyond its basic guarantees such as its CPU and Memory
consumption. Wasmtime also runs in tiny environments all the way up to massive
servers with many concurrent instances.
* **[WASI]**. Wasmtime supports a rich set of APIs for interacting with the host
environment through the [WASI standard](https://wasi.dev).
* **[Standards Compliant]**. Wasmtime passes the [official WebAssembly test
suite](https://github.com/WebAssembly/testsuite), implements the [official C
API of wasm](https://github.com/WebAssembly/wasm-c-api), and implements
[future proposals to WebAssembly](https://github.com/WebAssembly/proposals) as
well. Wasmtime developers are intimately engaged with the WebAssembly
standards process all along the way too.
[Wasmtime]: https://github.com/bytecodealliance/wasmtime
[Cranelift]: https://github.com/bytecodealliance/wasmtime/blob/main/cranelift/README.md
[Google's OSS Fuzz]: https://google.github.io/oss-fuzz/
[security policy]: https://bytecodealliance.org/security
[RFC process]: https://github.com/bytecodealliance/rfcs
[release policy]: https://docs.wasmtime.dev/stability-release.html
[Secure]: https://docs.wasmtime.dev/security.html
[Configurable]: https://docs.rs/wasmtime/latest/wasmtime/struct.Config.html
[WASI]: https://docs.rs/wasmtime-wasi/latest/wasmtime_wasi/
[Standards Compliant]: https://docs.wasmtime.dev/stability-wasm-proposals-support.html
## Example
An example of using the Wasmtime embedding API for running a small WebAssembly
module might look like:
```rust
use anyhow::Result;
use wasmtime::*;
fn main() -> Result<()> {
// Modules can be compiled through either the text or binary format
let engine = Engine::default();
let wat = r#"
(module
(import "host" "hello" (func $host_hello (param i32)))
(func (export "hello")
i32.const 3
call $host_hello)
)
"#;
let module = Module::new(&engine, wat)?;
// Create a `Linker` which will be later used to instantiate this module.
// Host functionality is defined by name within the `Linker`.
let mut linker = Linker::new(&engine);
linker.func_wrap("host", "hello", |caller: Caller<'_, u32>, param: i32| {
println!("Got {} from WebAssembly", param);
println!("my host state is: {}", caller.data());
})?;
// All wasm objects operate within the context of a "store". Each
// `Store` has a type parameter to store host-specific data, which in
// this case we're using `4` for.
let mut store = Store::new(&engine, 4);
let instance = linker.instantiate(&mut store, &module)?;
let hello = instance.get_typed_func::<(), (), _>(&mut store, "hello")?;
// And finally we can call the wasm!
hello.call(&mut store, ())?;
Ok(())
}
```
More examples and information can be found in the `wasmtime` crate's [online
documentation](https://docs.rs/wasmtime) as well.
## Documentation
[📚 Read the Wasmtime guide here! 📚][guide]
The [wasmtime guide][guide] is the best starting point to learn about what
Wasmtime can do for you or help answer your questions about Wasmtime. If you're
curious in contributing to Wasmtime, [it can also help you do
that][contributing]!
[contributing]: https://bytecodealliance.github.io/wasmtime/contributing.html
[guide]: https://bytecodealliance.github.io/wasmtime

View File

@@ -1,5 +1,11 @@
//! Wasmtime's embedding API
//!
//! Wasmtime is a WebAssembly engine for JIT-complied or ahead-of-time compiled
//! WebAssembly modules. More information about the Wasmtime project as a whole
//! can be found [in the documentation book](https://docs.wasmtime.dev) whereas
//! this documentation mostly focuses on the API reference of the `wasmtime`
//! crate itself.
//!
//! This crate contains an API used to interact with WebAssembly modules. For
//! example you can compile modules, instantiate them, call them, etc. As an
//! embedder of WebAssembly you can also provide WebAssembly modules

View File

@@ -48,7 +48,6 @@
- [Wasm Proposals Support](./stability-wasm-proposals-support.md)
- [Security](security.md)
- [Disclosure Policy](./security-disclosure.md)
- [Sandboxing](./security-sandboxing.md)
- [Contributing](contributing.md)
- [Architecture](./contributing-architecture.md)
- [Building](./contributing-building.md)

View File

@@ -1,81 +0,0 @@
# Sandboxing
One of WebAssembly (and Wasmtime's) main goals is to execute untrusted code in
a safe manner inside of a sandbox. WebAssembly is inherently sandboxed by design
(must import all functionality, etc). This document is intended to cover the
various sandboxing implementation strategies that Wasmtime has as they are
developed.
At this time Wasmtime implements what's necessary for the WebAssembly
specification, for example memory isolation between instances. Additionally the
safe Rust API is intended to mitigate accidental bugs in hosts.
Different sandboxing implementation techniques will also come with different
tradeoffs in terms of performance and feature limitations, and Wasmtime plans to
offer users choices of which tradeoffs they want to make.
More will be added here over time!
## WebAssembly Core
The core WebAssembly spec has several features which create a unique sandboxed
environment:
- The callstack is inaccessible. Unlike most native execution environments,
return addresses from calls and spilled registers are not stored in memory
accessible to applications. They are stored in memory that only the
implementation has access to, which makes traditional stack-smashing attacks
targeting return addresses impossible.
- Pointers, in source languages which have them, are compiled to offsets
into linear memory, so implementations details such as virtual addresses
are hidden from applications. And all accesses within linear memory are
checked to ensure they stay in bounds.
- All control transfers—direct and indirect branches, as well as direct and
indirect calls—are to known and type-checked destinations, so it's not
possible to accidentally call into the middle of a function or branch
outside of a function.
- All interaction with the outside world is done through imports and exports.
There is no raw access to system calls or other forms of I/O; the only
thing a WebAssembly instance can do is what is available through interfaces
it has been explicitly linked with.
- There is no undefined behavior. Even where the WebAssembly spec permits
multiple possible behaviors, it doesn't permit arbitrary behavior.
## Filesystem Access
Wasmtime implements the WASI APIs for filesystem access, which follow a
capability-based security model, which ensures that applications can only
access files and directories they've been given access to. WASI's security
model keeps users safe today, and also helps us prepare for shared-nothing
linking and nanoprocesses in the future.
Wasmtime developers are intimately engaged with the WASI standards process,
libraries, and tooling development, all along the way too.
## Terminal Output
If untrusted code is allowed to print text which is displayed to a terminal, it may
emit ANSI-style escape sequences and other control sequences which, depending on
the terminal the user is using and how it is configured, can have side effects
including writing to files, executing commands, injecting text into the stream
as if the user had typed it, or reading the output of previous commands. ANSI-style
escape sequences can also confuse or mislead users, making other vulnerabilities
easier to exploit.
Our first priority is to protect users, so Wasmtime now filters writes to output
streams when they are connected to a terminal to translate escape sequences into
inert replacement sequences.
Some applications need ANSI-style escape sequences, such as terminal-based
editors and programs that use colors, so we are also developing a proposal for
the WASI Subgroup for safe and portable ANSI-style escape sequence support, which
we hope to post more about soon.
## Spectre
Wasmtime does not yet implement Spectre mitigations, however this is a subject
of ongoing research.

View File

@@ -1,3 +1,134 @@
# Security
Please refer to the [Bytecode Alliance security policy](https://bytecodealliance.org/security) for details on how to report security issues in Wasmtime, our disclosure policy, and how to receive notifications about security issues.
One of WebAssembly (and Wasmtime's) main goals is to execute untrusted code in
a safe manner inside of a sandbox. WebAssembly is inherently sandboxed by design
(must import all functionality, etc). This document is intended to cover the
various sandboxing implementation strategies that Wasmtime has as they are
developed.
At this time Wasmtime implements what's necessary for the WebAssembly
specification, for example memory isolation between instances. Additionally the
safe Rust API is intended to mitigate accidental bugs in hosts.
Different sandboxing implementation techniques will also come with different
tradeoffs in terms of performance and feature limitations, and Wasmtime plans to
offer users choices of which tradeoffs they want to make.
## WebAssembly Core
The core WebAssembly spec has several features which create a unique sandboxed
environment:
- The callstack is inaccessible. Unlike most native execution environments,
return addresses from calls and spilled registers are not stored in memory
accessible to applications. They are stored in memory that only the
implementation has access to, which makes traditional stack-smashing attacks
targeting return addresses impossible.
- Pointers, in source languages which have them, are compiled to offsets
into linear memory, so implementations details such as virtual addresses
are hidden from applications. And all accesses within linear memory are
checked to ensure they stay in bounds.
- All control transfers—direct and indirect branches, as well as direct and
indirect calls—are to known and type-checked destinations, so it's not
possible to accidentally call into the middle of a function or branch
outside of a function.
- All interaction with the outside world is done through imports and exports.
There is no raw access to system calls or other forms of I/O; the only
thing a WebAssembly instance can do is what is available through interfaces
it has been explicitly linked with.
- There is no undefined behavior. Even where the WebAssembly spec permits
multiple possible behaviors, it doesn't permit arbitrary behavior.
## Defense-in-depth
While WebAssembly is designed to be sandboxed bugs or issues inevitably arise so
Wasmtime also implements a number of mitigations which are not required for
correct execution of WebAssembly but can help mitigate issues if bugs are found:
* Linear memories by default are preceded with a 2GB guard region. WebAssembly
has no means of ever accessing this memory but this can protect against
accidental sign-extension bugs in Cranelift where if an offset is accidentally
interpreted as a signed 32-bit offset instead of an unsigned offset it could
access memory before the addressable memory for WebAssembly.
* Wasmtime uses explicit checks to determine if a WebAssembly function should be
considered to stack overflow, but it still uses guard pages on all native
thread stacks. These guard pages are never intended to be hit and will abort
the program if they're hit. Hitting a guard page within WebAssembly indicates
a bug in host configuration or a bug in Cranelift itself.
* Where it can Wasmtime will zero memory used by a WebAssembly instance after
it's finished. This is not necessary unless the memory is actually reused for
instantiation elsewhere but this is done to prevent accidental leakage of
information between instances in the face of other bugs. This applies to
linear memories, tables, and the memory used to store instance information
itself.
* The choice of implementation language, Rust, for Wasmtime is also a
defense in protecting the authors for Wasmtime from themselves in addition to
protecting embedders from themselves. Rust helps catch mistakes when writing
Wasmtime itself at compile time. Rust additionally enables Wasmtime developers
to create an API that means that embedders can't get it wrong. For example
it's guaranteed that Wasmtime won't segfault when using its public API,
empowering embedders with confidence that even if the embedding has bugs all
of the security guarantees of WebAssembly are still upheld.
* Wasmtime is in the [process of implementing control-flow-integrity
mechanisms][cfi-rfc] to leverage hardware state for futher guaranteeing that
WebAssembly stays within its sandbox. In the event of a bug in Cranelift this
can help mitigate the impact of where control flow can go to.
[cfi-rfc]: https://github.com/bytecodealliance/rfcs/blob/main/accepted/cfi-improvements-with-pauth-and-bti.md
## Filesystem Access
Wasmtime implements the WASI APIs for filesystem access, which follow a
capability-based security model, which ensures that applications can only
access files and directories they've been given access to. WASI's security
model keeps users safe today, and also helps us prepare for shared-nothing
linking and nanoprocesses in the future.
Wasmtime developers are intimately engaged with the WASI standards process,
libraries, and tooling development, all along the way too.
## Terminal Output
If untrusted code is allowed to print text which is displayed to a terminal, it may
emit ANSI-style escape sequences and other control sequences which, depending on
the terminal the user is using and how it is configured, can have side effects
including writing to files, executing commands, injecting text into the stream
as if the user had typed it, or reading the output of previous commands. ANSI-style
escape sequences can also confuse or mislead users, making other vulnerabilities
easier to exploit.
Our first priority is to protect users, so Wasmtime now filters writes to output
streams when they are connected to a terminal to translate escape sequences into
inert replacement sequences.
Some applications need ANSI-style escape sequences, such as terminal-based
editors and programs that use colors, so we are also developing a proposal for
the WASI Subgroup for safe and portable ANSI-style escape sequence support, which
we hope to post more about soon.
## Spectre
Wasmtime implements a few forms of basic spectre mitigations at this time:
* Bounds checks when accessing entries in a function table (e.g. the
`call_indirect` instruction) are mitigated.
* The `br_table` instruction is mitigated to ensure that speculation goes to a
deterministic location.
* Wasmtime's default configuration for linear memory means that bounds checks
will not be present for memory accesses due to the reliance on page faults to
instead detect out-of-bounds accesses. When Wasmtime is configured with
"dynamic" memories, however, Cranelift will insert spectre mitigation for the
bounds checks performed for all memory accesses.
Mitigating Spectre continues to be a subject of ongoing research, and Wasmtime
will likely grow more mitigations in the future as well.