Open georgemitenkov opened 1 year ago
Thanks for reporting this @georgemitenkov!
I'm guessing there is some sort of conditional testing in the trap handler. For example when we trigger a trap, maybe we don't check metering is active and therefore we don't count those instructions. This is particularly relevant to Wasmer Edge and blockchains because it is a potential DOS vector.
Wanted to comment that we solved this in our fork here by charging for compute before executing the basic block.
These changes may be valuable to upstream since they make middlewares more powerful generally :)
Describe the bug
Metering instrumentation does not work in presence of trapping instructions. Right now the algorithm would place instrumentation at each branch source / target, e.g.
loop
,call
,br
, etc. - essentially at the end of a basic block. If the basic block contains an instruction that traps, the execution is not metered. This allows to create malicious programs with a single computationally-expensive basic block with an instruction that traps in the end, which is not metered.Steps to reproduce
Example of a program which would not be metered if
$x == 0
.To reproduce, you can add this code to tests in metering instrumentation folder.
Expected behavior
Actual behavior
The instrumentation with an accumulated cost of metering (4) is added after division instruction. Because division traps, it is never reached.
Additional context
To fix the issue, the metering has to be done before every trapping instruction, or a different algorithm should be used.