Context: crates/lean_vm/src/isa/instruction.rs
Description
The Jump execution enforces the boolean constraint with assert! rather than returning a recoverable error. If untrusted bytecode/memory sets condition to any field element other than 0 or 1, the process panics and aborts, allowing a denial-of-service(DoS) against any service that executes attacker-influenced programs.
let condition_value = condition.read_value(ctx.memory, *ctx.fp)?;
assert!([F::ZERO, F::ONE].contains(&condition_value),);
if condition_value == F::ZERO {
*ctx.pc += 1;
} else {
*ctx.pc = dest.read_value(ctx.memory, *ctx.fp)?.to_usize();
*ctx.fp = updated_fp.read_value(ctx.memory, *ctx.fp)?.to_usize();
}
Recommendation
-
Replace the assert! with a checked branch that returns a RunnerError (e.g., InvalidJumpCondition) when the value is not 0/1.
-
Consider validating jump conditions during bytecode loading as well.
Context:
crates/lean_vm/src/isa/instruction.rsDescription
The
Jumpexecution enforces the boolean constraint withassert!rather than returning a recoverable error. If untrusted bytecode/memory setsconditionto any field element other than 0 or 1, the process panics and aborts, allowing a denial-of-service(DoS) against any service that executes attacker-influenced programs.Recommendation
Replace the
assert!with a checked branch that returns aRunnerError(e.g.,InvalidJumpCondition) when the value is not 0/1.Consider validating jump conditions during bytecode loading as well.