Skip to main content

Module runtime

Module runtime 

Source
Expand description

The WASM capability sandbox (#156, slice 4).

A plugin module is loaded into extism (embedding wasmtime) with no ambient authority: WASI is disabled, so the module gets no filesystem, clock, randomness, or network. Its entire outside-world surface is the host functions the host registers — and the host registers a function only if the matching capability was granted. A module that imports a host function whose capability wasn’t granted fails to load (a wasmtime link error): the runtime half of the capability model, paired with the manifest-level imports↔grant check in validate_manifest.

Execution is bounded three ways — a memory cap, a wasmtime fuel cap, and a wall-clock timeout — so a runaway module is trapped, never hangs the host.

The host-function bodies here are stubs: this slice establishes the sandbox, the capability→host-function ABI, and the enforcement/metering contract. The detector and export slices replace the stubs with real, scope-checked implementations (read the foreground window, POST to the granted origin, …).

Structs§

SandboxContext
Per-install context the host functions need beyond the capability scopes themselves, plus the verdict channel.

Constants§

DEFAULT_FUEL
wasmtime fuel ceiling per instance — belt to the timeout’s braces, so a tight CPU loop traps on fuel even if the timer thread is starved. Roughly one unit per wasm instruction; 5e8 is far above any real probe.
DEFAULT_MEMORY_MAX_PAGES
Memory ceiling for a plugin instance, in 64 KiB wasm pages. 64 pages = 4 MiB — generous for a detector/export module, tight enough that a runaway allocation traps quickly.
DEFAULT_TIMEOUT
Wall-clock ceiling for a single plugin call. Detectors run on a throttled interval off the scheduler tick, so 250 ms is ample for a real probe while bounding an accidental infinite loop.
HOST_SUPPRESS 🔒
The host-function name a detector calls to vote “suppress the next break”. Ungated (every detector may report a verdict) and always registered, so a detector module always links against it.

Functions§

build_sandboxed_plugin
Build a sandboxed plugin from module bytes, registering host functions only for the granted capabilities. WASI is off and memory / fuel / timeout are bounded (see the DEFAULT_* consts). Returns a user-facing error if the module fails to compile, link, or instantiate — including the case where it imports a host function whose capability wasn’t granted.
evaluate_detector
Build a detector from its module + granted capabilities, run its detect() export once, and return whether it voted to suppress (by calling host_suppress). A module that fails to build, has no detect export, or traps is treated as no suppression — a broken detector never blocks a break. Pure aside from the probes the granted host functions perform.
host_function_name
The host-function name a capability unlocks in the extism:host/user namespace, i.e. the symbol a module imports to use that capability. The sandbox registers exactly these for the granted capabilities.
host_stub 🔒
Placeholder body for host functions whose real implementation lands in a later slice (foreground-window and the export sinks). Returns 0. Its mere presence is still gated by the capability, so registering it doesn’t widen the module’s reach.
register_capability 🔒
Register the host function a single capability unlocks. All host functions are () -> i64 booleans in this ABI; the data each one reads (the process pattern, the granted file path) is captured from the grant + context, so a module cannot influence what’s probed.
register_probe 🔒
Register a () -> i64 boolean host function whose answer is probe(data). data is captured host-side from the grant/context — never supplied by the module — so the probe is scope-checked by construction.
set_bool 🔒
Set the single i64 output of a host function to a boolean (1/0).