Skip to content

Always use fallible accesses of the GC heap#13320

Open
alexcrichton wants to merge 1 commit intobytecodealliance:mainfrom
alexcrichton:fallible-gc
Open

Always use fallible accesses of the GC heap#13320
alexcrichton wants to merge 1 commit intobytecodealliance:mainfrom
alexcrichton:fallible-gc

Conversation

@alexcrichton
Copy link
Copy Markdown
Member

This commit is an attempt to harden Wasmtime in the face of GC heap corruption to downgrade panics to an error being returned instead. Normal operation should never hit any of these paths and in theory this is all dead code. The intention, however, is to further downgrade the severity of GC heaps from a DoS to, in theory, maybe not even a CVE at all.

This commit is inspired by the transition done for component-model-async recently too where many assert!'d conditions and panics were translated into bail_bug! within Wasmtime. This returns a special kind of error in release mode and panics in debug mode. The rationale behind this is that, like component-model-async, the GC implementation is the intersection of:

  • Easy for guests to control.
  • Difficult to guarantee 100% correctness of the host.
  • Low consequences if corruption is detected.
  • Easy to generate a trap via ? to propagate upwards.

In this situation the goal here is to more aggressively return errors, in release mode, rather than panic which risks a quick DoS of embedders. The ideal goal is for GC heap corruption to not be a DoS at all, but we're not quite ready to make that commitment just yet.

Many methods in this commit were refactored to return Result, and many implementations internally within the GC implementation have been updated to use bail_bug! or similar to downgrade panics to errors. Note that in debug mode (or cfg(debug_assertions)) all of these are still panics.

cc #13216

This commit is an attempt to harden Wasmtime in the face of GC heap
corruption to downgrade panics to an error being returned instead.
Normal operation should never hit any of these paths and in theory this
is all dead code. The intention, however, is to further downgrade the
severity of GC heaps from a DoS to, in theory, maybe not even a CVE at
all.

This commit is inspired by the transition done for component-model-async
recently too where many `assert!`'d conditions and panics were
translated into `bail_bug!` within Wasmtime. This returns a special kind
of error in release mode and panics in debug mode. The rationale behind
this is that, like component-model-async, the GC implementation is the
intersection of:

* Easy for guests to control.
* Difficult to guarantee 100% correctness of the host.
* Low consequences if corruption is detected.
* Easy to generate a trap via `?` to propagate upwards.

In this situation the goal here is to more aggressively return errors,
in release mode, rather than panic which risks a quick DoS of
embedders. The ideal goal is for GC heap corruption to not be a DoS at
all, but we're not quite ready to make that commitment just yet.

Many methods in this commit were refactored to return `Result`, and many
implementations internally within the GC implementation have been
updated to use `bail_bug!` or similar to downgrade panics to errors.
Note that in debug mode (or `cfg(debug_assertions)`) all of these are
still panics.

cc bytecodealliance#13216
alexcrichton added a commit to alexcrichton/wasmtime that referenced this pull request May 7, 2026
In the spirit of bytecodealliance#13320 this commit goes through the compiled code for
the GC proposal to ensure that, in the face of GC corruption, Wasmtime
by default can recover and return a "bug" to the embedder. This was also
discussed a bit in bytecodealliance#13112 as well, and the changes made here are:

* Plumbing traps from translation into the runtime now uses a new
  `CompiledTrap` enum instead of just the normal `Trap`. This new enum
  has branches for `InternalAssert` (not previously present) and
  additionally `GcHeapCorrupted` (now added).
* Whether or not `CompiledTrap::{InternalAssert,GcHeapCorrupted}` is
  encoded into the final `*.cwasm` is now a `Tunables` configuration
  option. Internal asserts are not encoded by default but GC heap
  corruption is.
* Traps caught as `CompiledTrap::{InternalAssert,GcHeapCorrupted}` are
  turned into `WasmtimeBug` and propagated upwards. Traps stay as normal
  traps.
* All memory accesses to the GC heap now use
  `CompiledTrap::GcHeapCorrupted` as their trap code. Additionally
  they're also no longer marked as `readonly` in a few places.
* A few locations in GC translation using `InternalAssert` now use
  `GcHeapCorrupted`, such as the checked arithmetic around array
  lengths. Other assertions which are about control flow are left
  untouched.

The end state is that faults in the GC heap in compiled code itself
should show up as a `bug!` on the other end by default. This requires
extra metadata in `*.cwasm`s mapping traps, but this is similar to
linear-memory-using-wasms which have lots of trap metadata for
loads/stores. Being able to catch `InternalAssert` as a first-class
error (as opposed to a signal) is a debugging nicety I've added here but
remains off-by-default to avoid bloating `*.cwasm`s for internal debugging.

Closes bytecodealliance#13112
@github-actions github-actions Bot added wasmtime:api Related to the API of the `wasmtime` crate itself wasmtime:ref-types Issues related to reference types and GC in Wasmtime labels May 8, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 8, 2026

Subscribe to Label Action

cc @fitzgen

Details This issue or pull request has been labeled: "wasmtime:api", "wasmtime:ref-types"

Thus the following users have been cc'd because of the following labels:

  • fitzgen: wasmtime:ref-types

To subscribe or unsubscribe from this label, edit the .github/subscribe-to-label.json configuration file.

Learn more.

@bjorn3
Copy link
Copy Markdown
Contributor

bjorn3 commented May 8, 2026

If you are worried about DoS due to bugs as an embedder, why wouldn't you be using catch_unwind already? catch_unwind in part exists to reduce the blast radius of bugs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

wasmtime:api Related to the API of the `wasmtime` crate itself wasmtime:ref-types Issues related to reference types and GC in Wasmtime

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants