Commit 9f747be5 authored by ahaas's avatar ahaas Committed by Commit bot

[wasm] Check the input of grow-memory before calling the runtime.

If the input of grow-memory was not representable as a SMI, then the
input was not passed correctly to the runtime, which caused a crash.
With this CL the input of grow-memory is checked before the runtime is
called.

R=titzer@chromium.org, gdeepti@chromium.org
TEST=mjsunit/wasm/grow-memory.js:testGrowMemoryTrapsWithNonSmiInput()

Review-Url: https://codereview.chromium.org/2288773002
Cr-Commit-Position: refs/heads/master@{#39022}
parent f2931d7d
......@@ -1668,13 +1668,18 @@ Node* WasmGraphBuilder::BuildFloatToIntConversionInstruction(
}
Node* WasmGraphBuilder::BuildGrowMemory(Node* input) {
Diamond check_input_range(
graph(), jsgraph()->common(),
graph()->NewNode(
jsgraph()->machine()->Uint32LessThanOrEqual(), input,
jsgraph()->Uint32Constant(wasm::WasmModule::kMaxMemPages)),
BranchHint::kTrue);
Runtime::FunctionId function_id = Runtime::kWasmGrowMemory;
const Runtime::Function* function = Runtime::FunctionForId(function_id);
CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
jsgraph()->zone(), function_id, function->nargs, Operator::kNoThrow,
CallDescriptor::kNoFlags);
Node** control_ptr = control_;
Node** effect_ptr = effect_;
wasm::ModuleEnv* module = module_;
input = BuildChangeUint32ToSmi(input);
Node* inputs[] = {
......@@ -1683,13 +1688,19 @@ Node* WasmGraphBuilder::BuildGrowMemory(Node* input) {
ExternalReference(function_id, jsgraph()->isolate())), // ref
jsgraph()->Int32Constant(function->nargs), // arity
jsgraph()->HeapConstant(module->instance->context), // context
*effect_ptr,
*control_ptr};
Node* node = graph()->NewNode(jsgraph()->common()->Call(desc),
*effect_,
check_input_range.if_true};
Node* call = graph()->NewNode(jsgraph()->common()->Call(desc),
static_cast<int>(arraysize(inputs)), inputs);
*effect_ptr = node;
node = BuildChangeSmiToInt32(node);
return node;
Node* result = BuildChangeSmiToInt32(call);
result = check_input_range.Phi(MachineRepresentation::kWord32, result,
jsgraph()->Int32Constant(-1));
*effect_ = graph()->NewNode(jsgraph()->common()->EffectPhi(2), call, *effect_,
check_input_range.merge);
*control_ = check_input_range.merge;
return result;
}
Node* WasmGraphBuilder::BuildI32DivS(Node* left, Node* right,
......
......@@ -58,9 +58,8 @@ RUNTIME_FUNCTION(Runtime_WasmGrowMemory) {
old_size = 0;
// TODO(gdeepti): Fix bounds check to take into account size of memtype.
new_size = delta_pages * wasm::WasmModule::kPageSize;
if (delta_pages > wasm::WasmModule::kMaxMemPages) {
return *isolate->factory()->NewNumberFromInt(-1);
}
// The code generated in the wasm compiler guarantees this precondition.
DCHECK(delta_pages <= wasm::WasmModule::kMaxMemPages);
new_mem_start =
static_cast<Address>(isolate->array_buffer_allocator()->Allocate(
static_cast<uint32_t>(new_size)));
......
......@@ -117,3 +117,14 @@ function testGrowMemoryTrapMaxPages() {
}
testGrowMemoryTrapMaxPages();
function testGrowMemoryTrapsWithNonSmiInput() {
var builder = genGrowMemoryBuilder();
var module = builder.instantiate();
function growMem(pages) { return module.exports.grow_memory(pages); }
// The parameter of grow_memory is unsigned. Therefore -1 stands for
// UINT32_MIN, which cannot be represented as SMI.
assertEquals(-1, growMem(-1));
};
testGrowMemoryTrapsWithNonSmiInput();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment