[wasm][fuzzer] Fix check for max_steps (again)

After the latest fix (https://crrev.com/c/4118547), it could happen that
we stop execution even though the stored "max steps" counter did not
reach zero. This was previously not possible because we did always
subtract 1, and only terminated once we reached zero. Not we sometimes
subtract bigger numbers, and terminate if the counter is smaller than
the number we want to subtract.

This CL fixes this by first subtracting, and then checking if the
counter ran negative.

R=thibaudm@chromium.org

Bug: chromium:1405322
Change-Id: I19d7be263b000eb0a6319aaeb8838d11b8c5a3b2
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4165602
Reviewed-by: Thibaud Michaud <thibaudm@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/main@{#85317}
This commit is contained in:
Clemens Backes 2023-01-13 18:19:39 +01:00 committed by V8 LUCI CQ
parent e62810f71a
commit 63bff6b94b
3 changed files with 10 additions and 6 deletions

View File

@ -1120,16 +1120,20 @@ class LiftoffCompiler {
max_steps_addr, max_steps_addr,
WasmValue::ForUintPtr(reinterpret_cast<uintptr_t>(max_steps_))); WasmValue::ForUintPtr(reinterpret_cast<uintptr_t>(max_steps_)));
__ Load(max_steps, max_steps_addr.gp(), no_reg, 0, LoadType::kI32Load); __ Load(max_steps, max_steps_addr.gp(), no_reg, 0, LoadType::kI32Load);
// Subtract first (and store the result), so the caller sees that
// max_steps ran negative. Since we never subtract too much at once, we
// cannot underflow.
DCHECK_GE(kMaxInt / 16, steps_done); // An arbitrary limit.
__ emit_i32_subi(max_steps.gp(), max_steps.gp(), steps_done);
__ Store(max_steps_addr.gp(), no_reg, 0, max_steps, StoreType::kI32Store,
pinned);
Label cont; Label cont;
__ emit_i32_cond_jumpi(kSignedGreaterEqual, &cont, max_steps.gp(), __ emit_i32_cond_jumpi(kSignedGreaterEqual, &cont, max_steps.gp(), 0,
steps_done, frozen); frozen);
// Abort. // Abort.
Trap(decoder, kTrapUnreachable); Trap(decoder, kTrapUnreachable);
__ bind(&cont); __ bind(&cont);
} }
__ emit_i32_subi(max_steps.gp(), max_steps.gp(), steps_done);
__ Store(max_steps_addr.gp(), no_reg, 0, max_steps, StoreType::kI32Store,
pinned);
} }
V8_NOINLINE void EmitDebuggingInfo(FullDecoder* decoder, WasmOpcode opcode) { V8_NOINLINE void EmitDebuggingInfo(FullDecoder* decoder, WasmOpcode opcode) {

View File

@ -125,7 +125,7 @@ void ExecuteAgainstReference(Isolate* isolate,
compiled_args.begin(), &exception_ref); compiled_args.begin(), &exception_ref);
// Reached max steps, do not try to execute the test module as it might // Reached max steps, do not try to execute the test module as it might
// never terminate. // never terminate.
if (max_steps == 0) return; if (max_steps < 0) return;
// If there is nondeterminism, we cannot guarantee the behavior of the test // If there is nondeterminism, we cannot guarantee the behavior of the test
// module, and in particular it may not terminate. // module, and in particular it may not terminate.
if (nondeterminism != 0) return; if (nondeterminism != 0) return;

Binary file not shown.