1986f9f79SAlex Crichton# Coding guidelines
2986f9f79SAlex Crichton
3986f9f79SAlex CrichtonFor the most part, Wasmtime and Cranelift follow common Rust conventions and
4986f9f79SAlex Crichton[pull request] (PR) workflows, though we do have a few additional things to
5986f9f79SAlex Crichtonbe aware of.
6986f9f79SAlex Crichton
7986f9f79SAlex Crichton[pull request]: https://help.github.com/articles/about-pull-requests/
8986f9f79SAlex Crichton
947d3c8deSNick Fitzgerald### `rustfmt`
10986f9f79SAlex Crichton
11986f9f79SAlex CrichtonAll PRs must be formatted according to rustfmt, and this is checked in the
12986f9f79SAlex Crichtoncontinuous integration tests. You can format code locally with:
13986f9f79SAlex Crichton
1492cfda1bSVictor Adossi```console
1592cfda1bSVictor Adossicargo fmt
16986f9f79SAlex Crichton```
17986f9f79SAlex Crichton
18986f9f79SAlex Crichtonat the root of the repository. You can find [more information about rustfmt
19986f9f79SAlex Crichtononline](https://github.com/rust-lang/rustfmt) too, such as how to configure
20986f9f79SAlex Crichtonyour editor.
21986f9f79SAlex Crichton
22c0c3e798SAlex Crichton### Compiler Warnings and Lints
23c0c3e798SAlex Crichton
24c0c3e798SAlex CrichtonWasmtime promotes all compiler warnings to errors in CI, meaning that the `main`
25c0c3e798SAlex Crichtonbranch will never have compiler warnings for the version of Rust that's being
26c0c3e798SAlex Crichtontested on CI. Compiler warnings change over time, however, so it's not always
27c0c3e798SAlex Crichtonguaranteed that Wasmtime will build with zero warnings given an arbitrary
28c0c3e798SAlex Crichtonversion of Rust. If you encounter compiler warnings on your version of Rust
29c0c3e798SAlex Crichtonplease feel free to send a PR fixing them.
30c0c3e798SAlex Crichton
31c0c3e798SAlex CrichtonDuring local development, however, compiler warnings are simply warnings and the
32c0c3e798SAlex Crichtonbuild and tests can still succeed despite the presence of warnings. This can be
33c0c3e798SAlex Crichtonuseful because warnings are often quite prevalent in the middle of a
34c0c3e798SAlex Crichtonrefactoring, for example. By the time you make a PR, though, we'll require that
35c0c3e798SAlex Crichtonall warnings are resolved or otherwise CI will fail and the PR cannot land.
36c0c3e798SAlex Crichton
37c0c3e798SAlex CrichtonCompiler lints are controlled through the `[workspace.lints.rust]` table in the
38c0c3e798SAlex Crichton`Cargo.toml` at the root of the Wasmtime repository. A few allow-by-default
39c0c3e798SAlex Crichtonlints are enabled such as `trivial_numeric_casts`, and you're welcome to enable
40c0c3e798SAlex Crichtonmore lints as applicable. Lints can additionally be enabled on a per-crate basis
41c0c3e798SAlex Crichtonsuch as placing this in a `src/lib.rs` file:
42c0c3e798SAlex Crichton
43c0c3e798SAlex Crichton```rust
44c0c3e798SAlex Crichton#![warn(trivial_numeric_casts)]
45c0c3e798SAlex Crichton```
46c0c3e798SAlex Crichton
47c0c3e798SAlex CrichtonUsing `warn` here will allow local development to continue while still causing
48c0c3e798SAlex CrichtonCI to promote this warning to an error.
49c0c3e798SAlex Crichton
50c0c3e798SAlex Crichton### Clippy
51c0c3e798SAlex Crichton
52c0c3e798SAlex CrichtonAll PRs are gated on `cargo clippy` passing for all workspace crates and
53c0c3e798SAlex Crichtontargets. All clippy lints, however, are allow-by-default and thus disabled. The
54c0c3e798SAlex CrichtonWasmtime project selectively enables Clippy lints on an opt-in basis. Lints can
55c0c3e798SAlex Crichtonbe controlled for the entire workspace via `[workspace.lints.clippy]`:
56c0c3e798SAlex Crichton
57c0c3e798SAlex Crichton```toml
58c0c3e798SAlex Crichton[workspace.lints.clippy]
59c0c3e798SAlex Crichton# ...
60c0c3e798SAlex Crichtonmanual_strip = 'warn'
61c0c3e798SAlex Crichton```
62c0c3e798SAlex Crichton
63c0c3e798SAlex Crichtonor on a per-crate or module basis by using attributes:
64c0c3e798SAlex Crichton
65c0c3e798SAlex Crichton```rust
66c0c3e798SAlex Crichton#![warn(clippy::manual_strip)]
67c0c3e798SAlex Crichton```
68c0c3e798SAlex Crichton
69c0c3e798SAlex CrichtonIn Wasmtime we've found that the default set of Clippy lints is too noisy to
70c0c3e798SAlex Crichtonproductively use other Clippy lints, hence the allow-by-default behavior.
71c0c3e798SAlex CrichtonDespite this though there are numerous useful Clippy lints which are desired for
72c0c3e798SAlex Crichtonall crates or in some cases for a single crate or module. Wasmtime encourages
73c0c3e798SAlex Crichtoncontributors to enable Clippy lints they find useful through workspace or
74c0c3e798SAlex Crichtonper-crate configuration.
75c0c3e798SAlex Crichton
76c0c3e798SAlex CrichtonLike compiler warnings in the above section all Clippy warnings are turned into
77c0c3e798SAlex Crichtonerrors in CI. This means that `cargo clippy` should always produce no warnings
78c0c3e798SAlex Crichtonon Wasmtime's `main` branch if you're using the same compiler version that CI
79c0c3e798SAlex Crichtondoes (typically current stable Rust). This means, however, that if you enable a
80c0c3e798SAlex Crichtonnew Clippy lint for the workspace you'll be required to fix the lint for all
81c0c3e798SAlex Crichtoncrates in the workspace to land the PR in CI.
82c0c3e798SAlex Crichton
83c0c3e798SAlex CrichtonClippy can be run locally with:
84c0c3e798SAlex Crichton
8592cfda1bSVictor Adossi```console
8692cfda1bSVictor Adossicargo clippy --workspace --all-targets
87c0c3e798SAlex Crichton```
88c0c3e798SAlex Crichton
89c0c3e798SAlex CrichtonContributors are welcome to enable new lints and send PRs for this. Feel free to
90c0c3e798SAlex Crichtonreach out if you're not sure about a lint as well.
91c0c3e798SAlex Crichton
92584f6686SAlex Crichton### Minimum Supported `rustc` Version (MSRV)
93986f9f79SAlex Crichton
94a04c4930SAlex CrichtonWasmtime and Cranelift support the latest three stable releases of Rust. This
95a04c4930SAlex Crichtonmeans that if the latest version of Rust is 1.72.0 then Wasmtime supports Rust
96a04c4930SAlex Crichton1.70.0, 1.71.0, and 1.72.0. CI will test by default with 1.72.0 and there will
97a04c4930SAlex Crichtonbe one job running the full test suite on Linux x86\_64 on 1.70.0.
98986f9f79SAlex Crichton
99a04c4930SAlex CrichtonSome of the CI jobs depend on nightly Rust, for example to run rustdoc with
100a04c4930SAlex Crichtonnightly features, however these use pinned versions in CI that are updated
101a04c4930SAlex Crichtonperiodically and the general repository does not depend on nightly features.
102986f9f79SAlex Crichton
103a04c4930SAlex CrichtonUpdating Wasmtime's MSRV is done by editing the `rust-version` field in the
104a04c4930SAlex Crichtonworkspace root's `Cargo.toml`
105986f9f79SAlex Crichton
106584f6686SAlex CrichtonNote that this policy is subject to change over time (notably it might be
107584f6686SAlex Crichtonextended to include more rustc versions). Current Wasmtime users don't require a
108584f6686SAlex Crichtonlarger MSRV window to justify the maintenance needed to have a larger window. If
109584f6686SAlex Crichtonyour use case requires a larger MSRV range though please feel free to contact
110584f6686SAlex Crichtonmaintainers to raise your use case (e.g. an issue, in a Wasmtime meeting, on
111584f6686SAlex CrichtonZulip, etc).
112584f6686SAlex Crichton
1135c8bce70SAlex Crichton### Dependencies of Wasmtime
1145c8bce70SAlex Crichton
1155c8bce70SAlex CrichtonWasmtime and Cranelift have a higher threshold than default for adding
1165c8bce70SAlex Crichtondependencies to the project. All dependencies are required to be "vetted"
1175c8bce70SAlex Crichtonthrough the [`cargo vet` tool](https://mozilla.github.io/cargo-vet/). This is
1185c8bce70SAlex Crichtonchecked on CI and will run on all modifications to `Cargo.lock`.
1195c8bce70SAlex Crichton
1205c8bce70SAlex CrichtonA "vet" for Wasmtime is not a meticulous code review of a dependency for
1215c8bce70SAlex Crichtoncorrectness but rather it is a statement that the crate does not contain
1225c8bce70SAlex Crichtonmalicious code and is safe for us to run during development and (optionally)
1235c8bce70SAlex Crichtonusers to run when they run Wasmtime themselves. Wasmtime's vet entries are used
1245c8bce70SAlex Crichtonby other organizations which means that this isn't simply for our own personal
1255c8bce70SAlex Crichtonuse. Wasmtime additionally uses vet entries from other organizations as well
1265c8bce70SAlex Crichtonwhich means we don't have to vet everything ourselves.
1275c8bce70SAlex Crichton
1285c8bce70SAlex CrichtonNew vet entries are required to be made by trusted contributors to Wasmtime.
1295c8bce70SAlex CrichtonThis is all configured in the `supply-chain` folder of Wasmtime. These files
1305c8bce70SAlex Crichtongenerally aren't hand-edited though and are instead managed through the `cargo
1315c8bce70SAlex Crichtonvet` tool itself. Note that our `supply-chain/audits.toml` additionally contains
1325c8bce70SAlex Crichtonentries which indicates that authors are trusted as opposed to vets of
1335c8bce70SAlex Crichtonindividual crates. This lowers the burden of updating version of a crate from a
1345c8bce70SAlex Crichtontrusted author.
1355c8bce70SAlex Crichton
1365c8bce70SAlex CrichtonWhen put together this means that contributions to Wasmtime and Cranelift which
1375c8bce70SAlex Crichtonupdate existing dependencies or add new dependencies will not be mergeable by
1385c8bce70SAlex Crichtondefault (CI will fail). This is expected from our project's configuration and
1395c8bce70SAlex Crichtonthis situation will be handled one of a few ways:
1405c8bce70SAlex Crichton
141a6a51b71SAlex CrichtonNote that this process is not in place to prevent new dependencies or prevent
142a6a51b71SAlex Crichtonupdates, but rather it ensures that development of Wasmtime is done with a
143a6a51b71SAlex Crichtontrusted set of code that has been reviewed by trusted parties. We welcome
144a6a51b71SAlex Crichtondependency updates and new functionality, so please don't be too alarmed when
145a6a51b71SAlex Crichtoncontributing and seeing a failure of `cargo vet` on CI!
146a6a51b71SAlex Crichton
147a6a51b71SAlex Crichton### `cargo vet` for Contributors
148a6a51b71SAlex Crichton
149a6a51b71SAlex CrichtonIf you're a contributor to Wasmtime and you've landed on this documentation,
150a6a51b71SAlex Crichtonhello and thanks for your contribution! Here's some guidelines for changing the
151a6a51b71SAlex Crichtonset of dependencies in Wasmtime:
152a6a51b71SAlex Crichton
1535c8bce70SAlex Crichton* If a new dependency is being added it might be worth trying to slim down
1545c8bce70SAlex Crichton  what's required or avoiding the dependency altogether. Avoiding new
1555c8bce70SAlex Crichton  dependencies is best when reasonable, but it is not always reasonable to do
1565c8bce70SAlex Crichton  so. This is left to the judgement of the author and reviewer.
1575c8bce70SAlex Crichton
1585c8bce70SAlex Crichton* When updating dependencies this should be done for a specific purpose relevant
1595c8bce70SAlex Crichton  to the PR-at-hand. For example if the PR implements a new feature then the
1605c8bce70SAlex Crichton  dependency update should be required for the new feature. Otherwise it's best
1615c8bce70SAlex Crichton  to leave dependency updates to their own PRs. It's ok to update dependencies
1625c8bce70SAlex Crichton  "just for the update" but we prefer to have that as separate PRs.
1635c8bce70SAlex Crichton
164a6a51b71SAlex CrichtonDependency additions or updates require action on behalf of project maintainers
165a6a51b71SAlex Crichtonso we ask that you don't run `cargo vet` yourself or update the `supply-chain`
166f900a884SAlex Crichtonfolder yourself. Instead a maintainer will review your PR and perform the `cargo
167f900a884SAlex Crichtonvet` entries themselves. Reviewers will typically make a separate pull request
168f900a884SAlex Crichtonto add `cargo vet` entries and once that lands yours will be added to the queue.
1695c8bce70SAlex Crichton
170a6a51b71SAlex Crichton### `cargo vet` for Maintainers
171a6a51b71SAlex Crichton
172a6a51b71SAlex CrichtonMaintainers of Wasmtime are required to explicitly vet and approve all
173a6a51b71SAlex Crichtondependency updates and modifications to Wasmtime. This means that when reviewing
174a6a51b71SAlex Crichtona PR you should ensure that contributors are not modifying the `supply-chain`
175a6a51b71SAlex Crichtondirectory themselves outside of commits authored by other maintainers. Otherwise
176a6a51b71SAlex Crichtonthough to add vet entries this is done through one of a few methods:
177a6a51b71SAlex Crichton
178a6a51b71SAlex Crichton* For a PR where maintainers themselves are modifying dependencies the `cargo
179a6a51b71SAlex Crichton  vet` entries can be included inline with the PR itself by the author. The
180a6a51b71SAlex Crichton  reviewer knows that the author of the PR is themself a maintainer.
181a6a51b71SAlex Crichton
182a6a51b71SAlex Crichton* PRs that "just update dependencies" are ok to have at any time. You can do
183a6a51b71SAlex Crichton  this in preparation for a future feature or for a future contributor. This
184a6a51b71SAlex Crichton  more-or-less is the same as the previous categories.
185a6a51b71SAlex Crichton
186a6a51b71SAlex Crichton* For contributors who should not add vet entries themselves maintainers should
187f900a884SAlex Crichton  review the PR and add vet entries either in a separate PR or as part of the
188f900a884SAlex Crichton  contributor's PR itself. As a separate PR you'll check out the branch, run
189f900a884SAlex Crichton  `cargo vet`, then rebase away the contributor's commits and push your `cargo
190f900a884SAlex Crichton  vet` commit alone to merge. For pushing directly to the contributor's own PR
191f900a884SAlex Crichton  be sure to read the notes below.
192a6a51b71SAlex Crichton
193f900a884SAlex CrichtonNote for the last case it's important to ensure that if you push directly to a
194f900a884SAlex Crichtoncontributor's PR any future updates pushed by the contributor either contain or
195f900a884SAlex Crichtondon't overwrite your vet entries. Also verify that if the PR branch is rebased
196f900a884SAlex Crichtonor force-pushed, the details of your previously pushed vetting remain the same:
197f900a884SAlex Crichtone.g., versions were not bumped and descriptive reasons remain the same. If
198f900a884SAlex Crichtonpushing a vetting commit to a contributor's PR and also asking for more changes,
199f900a884SAlex Crichtonrequest that the contributor make the requested fixes in an additional commit
200f900a884SAlex Crichtonrather than force-pushing a rewritten history, so your existing vetting commit
201f900a884SAlex Crichtonremains untouched. These guidelines make it easier to verify no tampering has
202f900a884SAlex Crichtonoccurred.
203a6a51b71SAlex Crichton
204a6a51b71SAlex Crichton### Policy for adding `cargo vet` entries
205a6a51b71SAlex Crichton
206a6a51b71SAlex CrichtonFor maintainers this is intended to document the project's policy on adding
207a6a51b71SAlex Crichton`cargo vet` entries. The goal of this policy is to not make dependency updates
208a6a51b71SAlex Crichtonso onerous that they never happen while still achieving much of the intended
209a6a51b71SAlex Crichtonbenefit of `cargo vet` in protection against supply-chain style attacks.
210a6a51b71SAlex Crichton
211a6a51b71SAlex Crichton* For dependencies **that receive at least 10,000 downloads a day** on crates.io
212a6a51b71SAlex Crichton  it's ok to add an entry to `exemptions` in `supply-chain/config.toml`. This
213a6a51b71SAlex Crichton  does not require careful review or review at all of these dependencies. The
214a6a51b71SAlex Crichton  assumption here is that a supply chain attack against a popular crate is
215a6a51b71SAlex Crichton  statistically likely to be discovered relatively quickly. Changes to `main` in
216a6a51b71SAlex Crichton  Wasmtime take at least 2 weeks to be released due to our release process, so
217a6a51b71SAlex Crichton  the assumption is that popular crates that are victim of a supply chain attack
218a6a51b71SAlex Crichton  would be discovered during this time. This policy additionally greatly helps
219a6a51b71SAlex Crichton  when updating dependencies on popular crates that are common to see without
220a6a51b71SAlex Crichton  increasing the burden too much on maintainers.
221a6a51b71SAlex Crichton
222a6a51b71SAlex Crichton* For other dependencies a manual vet is required. The `cargo vet` tool will
223a6a51b71SAlex Crichton  assist in adding a vet by pointing you towards the source code, as published
224a6a51b71SAlex Crichton  on crates.io, to be browsed online. Manual review should be done to ensure
225a6a51b71SAlex Crichton  that "nothing nefarious" is happening. For example `unsafe` should be
226a6a51b71SAlex Crichton  inspected as well as use of ambient system capabilities such as `std::fs`,
227a6a51b71SAlex Crichton  `std::net`, or `std::process`, and build scripts. Note that you're not
228a6a51b71SAlex Crichton  reviewing for correctness, instead only for whether a supply-chain attack
229a6a51b71SAlex Crichton  appears to be present.
230a6a51b71SAlex Crichton
231a6a51b71SAlex CrichtonThis policy intends to strike a rough balance between usability and security.
232a6a51b71SAlex CrichtonIt's always recommended to add vet entries where possible, but the first bullet
233a6a51b71SAlex Crichtonabove can be used to update an `exemptions` entry or add a new entry. Note that
234a6a51b71SAlex Crichtonwhen the "popular threshold" is used **do not add a vet entry** because the
235a6a51b71SAlex Crichtoncrate is, in fact, not vetted. This is required to go through an
236a6a51b71SAlex Crichton`[[exemptions]]` entry.
2374c8edb95SAlex Crichton
2384c8edb95SAlex Crichton### Crate Organization
2394c8edb95SAlex Crichton
2404c8edb95SAlex CrichtonThe Wasmtime repository is a bit of a monorepo with lots of crates internally
2414c8edb95SAlex Crichtonwithin it. The Wasmtime project and `wasmtime` crate also consists of a variety
2424c8edb95SAlex Crichtonof crates intended for various purposes. As such not all crates are treated
2434c8edb95SAlex Crichtonexactly the same and so there are some rough guidelines here about adding new
2444c8edb95SAlex Crichtoncrates to the repository and where to place/name them:
2454c8edb95SAlex Crichton
2464c8edb95SAlex Crichton* Wasmtime-related crates live in `crates/foo/Cargo.toml` where the crate name
2474c8edb95SAlex Crichton  is typically `wasmtime-foo` or `wasmtime-internal-foo`.
2484c8edb95SAlex Crichton
2494c8edb95SAlex Crichton* Cranelift-related crates live in `cranelift/foo/Cargo.toml` where the crate is
2504c8edb95SAlex Crichton  named `cranelift-foo`.
2514c8edb95SAlex Crichton
2524c8edb95SAlex Crichton* Some projects such as Winch, Pulley, and Wiggle are exceptions to the above
2534c8edb95SAlex Crichton  rules and live in `winch/*`, `pulley/*` and `crates/wiggle/*`.
2544c8edb95SAlex Crichton
2554c8edb95SAlex Crichton* Some crates are "internal" to Wasmtime. This means that they only exist for
2564c8edb95SAlex Crichton  crate organization purposes (such as optional dependencies, or code
2574c8edb95SAlex Crichton  organization). These crates are not intended for public consumption and are
2584c8edb95SAlex Crichton  intended for exclusively being used by the `wasmtime` crate, for example, or
2594c8edb95SAlex Crichton  other public crates. These crates should be named `wasmtime-internal-foo` and
2604c8edb95SAlex Crichton  live in `crates/foo`. The `[workspace.dependencies]` directive in `Cargo.toml`
2614c8edb95SAlex Crichton  at the root of the repository should rename it to `wasmtime-foo` in
2624c8edb95SAlex Crichton  workspace-local usage, meaning that the "internal" part is only relevant on
2634c8edb95SAlex Crichton  crates.io.
26495942cb5SAlex Crichton
265*ec76a6b2SAlex Crichton### Adding Crates
266*ec76a6b2SAlex Crichton
267*ec76a6b2SAlex CrichtonAdding a new crate to the Wasmtime workspace takes a bit of care. Wasmtime uses
268*ec76a6b2SAlex Crichtoncrates.io trusted publishing meaning that all crates are published from CI in a
269*ec76a6b2SAlex Crichtonspecific workflow. This means that crates must exist on crates.io prior to their
270*ec76a6b2SAlex Crichtonfirst publication from the Wasmtime workspace and be configured for trusted
271*ec76a6b2SAlex Crichtonpublishing.
272*ec76a6b2SAlex Crichton
273*ec76a6b2SAlex CrichtonThe process for adding a new crate to the workspace looks like:
274*ec76a6b2SAlex Crichton
275*ec76a6b2SAlex Crichton1. In a PR a new crate is added and this documentation probably isn't read to
276*ec76a6b2SAlex Crichton   start out with.
277*ec76a6b2SAlex Crichton2. CI will fail in the "verify-publish" job because this crate doesn't exist on
278*ec76a6b2SAlex Crichton   crates.io.
279*ec76a6b2SAlex Crichton3. The PR author should publish a placeholder crate to crates.io.
280*ec76a6b2SAlex Crichton4. The PR author should go to "Settings" on crates.io, click on "Add" under
281*ec76a6b2SAlex Crichton   "Trusted Publishing", and enter the following:
282*ec76a6b2SAlex Crichton   fields:
283*ec76a6b2SAlex Crichton   * Publisher: `GitHub`
284*ec76a6b2SAlex Crichton   * Repository Owner: `bytecodealliance`
285*ec76a6b2SAlex Crichton   * Repository name: `wasmtime`
286*ec76a6b2SAlex Crichton   * Workflow filename: `publish-to-cratesio.yml`
287*ec76a6b2SAlex Crichton   * Environment name: `publish`
288*ec76a6b2SAlex Crichton5. The PR author should then check the box for requiring all publishes to use
289*ec76a6b2SAlex Crichton   the trusted publishing workflow.
290*ec76a6b2SAlex Crichton6. The PR author should invite the `wasmtime-publish` user to this crate.
291*ec76a6b2SAlex Crichton7. A Wasmtime maintainer, with access to the BA 1password vault, will log in to
292*ec76a6b2SAlex Crichton   crates.io as the `wasmtime-publish` user to accept the invite. Wasmtime
293*ec76a6b2SAlex Crichton   maintainers should double-check all of the settings and remove the original
294*ec76a6b2SAlex Crichton   owner of the crate so just `wasmtime-publish` owns the crate.
295*ec76a6b2SAlex Crichton
296*ec76a6b2SAlex CrichtonThis ensures that when publication time rolls around the crate is already
297*ec76a6b2SAlex Crichtonreserved on GitHub and the publication workflow will succeed. After the initial
298*ec76a6b2SAlex Crichtonpublication the crate is managed by Wasmtime maintainers.
299*ec76a6b2SAlex Crichton
30095942cb5SAlex Crichton### Use of `unsafe`
30195942cb5SAlex Crichton
30295942cb5SAlex CrichtonWasmtime is a project that contains `unsafe` Rust code. Wasmtime is also used in
30395942cb5SAlex Crichtonsecurity-critical contexts which means that it's extra-important that this
30495942cb5SAlex Crichton`unsafe` code is correct. The purpose of this section is to outline guidelines
30595942cb5SAlex Crichtonand guidance for how to use `unsafe` in Wasmtime.
30695942cb5SAlex Crichton
30795942cb5SAlex CrichtonIdeally Wasmtime would have no `unsafe` code. For large components of Wasmtime
30895942cb5SAlex Crichtonthis is already true, for these components have little to no `unsafe` code:
30995942cb5SAlex Crichton
31095942cb5SAlex Crichton* Cranelift - compiling WebAssembly modules.
31195942cb5SAlex Crichton* Winch - compiling WebAssembly modules.
31295942cb5SAlex Crichton* Wasmparser - validating WebAssembly.
31395942cb5SAlex Crichton* `wasmtime-wasi` / `wasmtime-wasi-http` - implementation of WASI.
31495942cb5SAlex Crichton
31595942cb5SAlex CrichtonWithout `unsafe` the likelihood of a security bug is greatly reduced with the
31695942cb5SAlex Crichtonriskiest possibility being a DoS vector through a panic, generally considered a
31795942cb5SAlex Crichtonlow-severity issue. Inevitably though due to the nature of Wasmtime it's
31895942cb5SAlex Crichtoneffectively impossible to 100% remove `unsafe` code. The question then becomes
31995942cb5SAlex Crichtonwhat is the right balance and how to work with `unsafe`?
32095942cb5SAlex Crichton
32195942cb5SAlex CrichtonSome `unsafe` blocks are effectively impossible to remove. For example somewhere
32295942cb5SAlex Crichtonin Wasmtime we're going to take the output of Cranelift and turn it into a
32395942cb5SAlex Crichtonfunction pointer to calling it. In doing so the correctness of the `unsafe`
32495942cb5SAlex Crichtonblock relies on the correctness of Cranelift as well as the translation from
32595942cb5SAlex CrichtonWebAssembly to Cranelift. This is a fundamental property of the Wasmtime project
32695942cb5SAlex Crichtonand thus can't really be mitigated.
32795942cb5SAlex Crichton
32895942cb5SAlex CrichtonOther `unsafe` blocks, however, ideally will be self-contained and isolated to a
32995942cb5SAlex Crichtonsmall portion of Wasmtime. For this code Wasmtime tries to follow these
33095942cb5SAlex Crichtonguidelines:
33195942cb5SAlex Crichton
33295942cb5SAlex Crichton1. Users of the public API of the `wasmtime` crate should never need `unsafe`.
33395942cb5SAlex Crichton   The API of `wasmtime` should be sound and safe no matter how its combined
33495942cb5SAlex Crichton   with other safe Rust code. While `unsafe` additions are allowed they should
33595942cb5SAlex Crichton   be very clearly documented with a precise contract of what exactly is unsafe
33695942cb5SAlex Crichton   and what must be upheld by the caller. For example `Module::deserialize`
33795942cb5SAlex Crichton   clearly documents that it could allow arbitrary code execution and thus it's
33895942cb5SAlex Crichton   not safe to pass in arbitrary bytes, but previously serialized bytes are
33995942cb5SAlex Crichton   always safe to pass in.
34095942cb5SAlex Crichton
34195942cb5SAlex Crichton2. Declaring a function as `unsafe` should be accompanied with clear
34295942cb5SAlex Crichton   documentation on the function declaration indicating why the function is
34395942cb5SAlex Crichton   `unsafe`. This should clearly indicate all the contracts that need to be
34495942cb5SAlex Crichton   upheld by callers for the invocation to be safe. There is no way to verify
34595942cb5SAlex Crichton   that the documentation is correct but this is a useful flag to reviewers and
34695942cb5SAlex Crichton   readers alike to be more vigilant around such functions.
34795942cb5SAlex Crichton
34895942cb5SAlex Crichton3. An `unsafe` block within a function should be accompanied with a preceding
34995942cb5SAlex Crichton   comment explaining why it's safe to have this block. It should be possible to
35095942cb5SAlex Crichton   verify this comment with local reasoning, for example considering little code
35195942cb5SAlex Crichton   outside of the current function or module. This means that it should be
35295942cb5SAlex Crichton   almost trivial to connect the contracts required on the callee function (why
35395942cb5SAlex Crichton   the `unsafe` block is there in the first place) to the surrounding code. This
35495942cb5SAlex Crichton   can include the current function being `unsafe` (effectively "forwarding" the
35595942cb5SAlex Crichton   contract of the callee) or via local reasoning.
35695942cb5SAlex Crichton
35795942cb5SAlex Crichton4. Implementation of a feature within Wasmtime should not result in excessive
35895942cb5SAlex Crichton   amounts of `unsafe` functions or usage of `unsafe` functions. The goal here
35995942cb5SAlex Crichton   is that if two possible designs for a feature are being weighed it's not
36095942cb5SAlex Crichton   required to favor one with zero unsafe vs one with just a little unsafe, but
36195942cb5SAlex Crichton   one with a little unsafe should be favored over one that is entirely unsafe.
36295942cb5SAlex Crichton   An example of this is Wasmtime's implementation of the GC proposal with a
36395942cb5SAlex Crichton   sandboxed heap where the data on the heap is never trusted. This comes at a
36495942cb5SAlex Crichton   minor theoretical performance loss on the host but has the benefit of all
36595942cb5SAlex Crichton   functions within the implementation are all safe. These sorts of design
36695942cb5SAlex Crichton   tradeoffs are not really possible to codify in stone, but the general
36795942cb5SAlex Crichton   guideline is to try to favor safer implementations so long as the
36895942cb5SAlex Crichton   hypothetical sacrifice in performance isn't too great.
36995942cb5SAlex Crichton
37095942cb5SAlex CrichtonIt should be noted that Wasmtime is a relatively large and old codebase and thus
37195942cb5SAlex Crichtondoes not perfectly follow these guidelines for preexisting code. Code not
37295942cb5SAlex Crichtonfollowing these guidelines is considered technical debt that must be paid down
37395942cb5SAlex Crichtonat one point. Wasmtime tries to [keep track of known issues][unsafe-code-tag] to
37495942cb5SAlex Crichtonburn down this list over time. New features to Wasmtime are allowed to add to
37595942cb5SAlex Crichtonthis list, but it should be clear how to burn down the list in time for any new
37695942cb5SAlex Crichtonentries added.
37795942cb5SAlex Crichton
37895942cb5SAlex Crichton[unsafe-code-tag]: https://github.com/bytecodealliance/wasmtime/labels/wasmtime%3Aunsafe-code
379