QuipNetwork / QuipNetwork/quip-validator
pallet-xqvm execute: unbounded sample alloc + step_limit 0 is unlimited (validator OOM / hang)
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 5.6k
- Forks
- 32
- PR merge metrics
- No merged PRs in 30d
Description
Title: pallet-xqvm execute: unbounded sample alloc + step_limit 0 is unlimited (validator OOM / hang)
Summary
pallet-xqvm::execute is a signed, permissionless extrinsic. Weight is pre-charged from the caller-supplied step_limit, then the interpreter runs.
Two independent metering holes:
-
Memory is not metered.
BSMX/SSMX/XSMXtake a stack i64, convert to usize, and allocate a denseVec<i64>of that length in one instruction (xquad/xqvm/src/vm.rs).WeightPerStepis 1000 ref_time. A 3-instruction program (PUSH huge; BSMX; HALT) pays for a handful of steps and can request gigabytes. -
Zero step limit is treated as infinity. The pallet only checks
step_limit <= MaxStepLimit.0passes.Vm::set_step_limitmaps0tou64::MAX. Weight charged isexecute_base + WeightPerStep * 0. The node then runs until halt, OOM, or process kill. Substrate will not stop the extrinsic mid-loop because announced weight was tiny.
The crate has xqvm::verifier::verify. The pallet only Program::decodes (magic/CRC). It never calls the verifier.
Impact
Any account can stall or OOM every authoring/importing validator. Liveness of any runtime that includes this pallet.
Toy: PUSH 268435456; BSMX; HALT. Three steps. ~2GB per validator. Or step_limit=0: fee for zero steps, loop forever if the program does not halt.
Suggested fix
- Reject
step_limit == 0on the consensus path; never map 0 tou64::MAXthere. - Cap every dense allocation (
BSMX/SSMX/XSMX, vec growth, ITER copies); charge proof-size/memory weight. - Run
verifier::verifybeforeVm::run. - Prefer
DispatchResultWithPostInfoand fail closed if an opcode would allocate above remaining weight.
Files
xquad/xqvm/src/vm.rs(BSMX/SSMX/XSMX alloc;set_step_limit(0)->u64::MAX)quip-validator/pallets/xqvm/src/lib.rs(execute, weight =WeightPerStep * step_limit)quip-validator/runtime/src/configs/mod.rs(WeightPerStep)
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the cited allocation and step-limit paths in xquad/xqvm/src/vm.rs, then trace execute and its weight calculation in quip-validator/pallets/xqvm/src/lib.rs and WeightPerStep in quip-validator/runtime/src/configs/mod.rs. Reproduce the two toy cases described in the issue and inspect verifier::verify. Done means consensus execution rejects zero limits, bounds memory-consuming operations, and prevents the reported OOM or nonterminating behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- blockchain, security
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100