Multi-variant Execution with RISC-V #1993
salaheldinsoliman
started this conversation in
Stellar Ecosystem Proposals
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Multi-variant execution
Introduction
DMON — "Distributed Heterogeneous N-Variant Execution" (Voulimeneas et al., DIMVA 2020) describes a way of enhancing software security by executing the same program on two different ISAs. They compile the same program twice, for two different ISAs — they used x86-64 and ARMv8 — run both variants in lockstep on identical inputs, and watch them at the system-call boundary. If the two ever disagree, then something has gone wrong: a compiler bug, a VM bug, or a memory-corruption exploit that works on one architecture and not the other.
I suggest that an implementation of an MVX verification system could benefit the security of Soroban contracts. First, I will list some questions and my best answers to them, then propose a solution.
Open questions
Cost/Benefit
The main benefit is the discovery of attacks targeting the runtime. For example, @tomerweller pointed out that wasmi was chosen because it is ~13k lines of auditable code, versus Wasmer's 180K.
Contract deployers who want to protect a public contract function from being exploited should indicate that to the Stellar node. The node, while dry-running the tx before execution, sends the tx bytes to the MVX service.
This means an extra tx execution; however, the tx execution time virtually stays the same: (a round-trip to the service + execution) - dry-run tx time. Dry-run tx time is subtracted since the two happen at the same time (at submission, before execution).
Companion ISA
A Soroban contract already runs on x86/arm when testing, which makes it a good candidate. However, the
soroban sdkgenerates different host calls for x86/arm. Also, a Soroban guest contract runs in a sandboxed environment, not directly on the server. Therefore, an MVX system would have to emulate an x86/arm machine to run the guest and host in.Another option is RISC-V, a ~47-instruction ISA with deterministic interpreters already there (CKB-VM, shown later in an experiment; PolkaVM). It also shares almost nothing with Wasm — different instructions, different codegen, different interpreter, etc.
This makes RISC-V a better candidate: sandboxed execution and a totally different runtime.
Where will the system exist
This depends on how the Stellar node is designed: it supports output data streams rather than node plugins, which makes an independent service a better fit.
Does it require a protocol change?
A contract deployer can protect a function iff they enforce that every tx is executed by the MVX service.
One way to do it is that a protected function must contain
require_auth(mvx_address). The tx then has to be signed by the MVX service. If a user submits a tx to a node that cannot get the signature of the MVX service, the tx fails.Given that, nodes are incentivized to include this feature to be able to execute protected txs, however they are not required to do so. Therefore, no protocol upgrade is needed for this service to exist.
Experiment: compiling and running a RISC-V ELF
soroban-ckb
This is a brief experiment of running a RISC-V program on CKB-VM. A small
contract is compiled to a RISC-V ELF and run inside CKB-VM; when it needs the
host, it issues an
ecall, and a native runner dispatches that call tosoroban-env-hostand returns the result. It shows that a RISC-V guest can drivethe same host a Wasm guest does, without the host running inside the VM.
Future work
The experiment hand-writes two host calls and a runner that exposes
soroban-env-hostto them. Two more changes are needed to reach an MVX service:RISC-V guest backend for
soroban-sdkThe SDK picks a backend by
cfg(target_family = "wasm"):wasmtargets get theWasm import bindings (
soroban-env-guest),everything else links the full host. Both are generated from
env.jsonby an x-macro. Add a third arm that lowers each host call to anecallfor the RISC-V target, gated by acfg. The function list is already generated, so thisreduces to one new macro arm plus routing in
rs-soroban-sdk.A contract then compiles to both targets from one source.
Guest-memory abstraction in
soroban-env-hostLinear-memory access is already directed through a few call sites in
mem_helper.rs, and every host function is callable withVmCaller::none()(no wasmi context). Abstracting those sites lets the host read and write CKB-VM memory alongside wasmi's, without duplicating host logic.All reactions