Commit 5f960dfc authored by Deepti Gandluri's avatar Deepti Gandluri Committed by Commit Bot

[wasm] Fix Memory.grow when shared with asm.js modules

If the buffer associated with WebAssembly.Memory is used as memory
for asm.js modules, throw a range error on Memory.Grow.

Bug: chromium:776677
Change-Id: Iebcd7797fa7724002dd8073d1dbaeb98f080d316
Reviewed-on: https://chromium-review.googlesource.com/731844
Commit-Queue: Deepti Gandluri <gdeepti@chromium.org>
Reviewed-by: 's avatarBrad Nelson <bradnelson@chromium.org>
Reviewed-by: 's avatarBen Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48837}
parent 5814125c
......@@ -374,6 +374,7 @@ MaybeHandle<Object> AsmJs::InstantiateAsmWasm(Isolate* isolate,
ReportInstantiationFailure(script, position, "Requires heap buffer");
return MaybeHandle<Object>();
}
memory->set_is_growable(false);
size_t size = NumberToSize(memory->byte_length());
// TODO(mstarzinger): We currently only limit byte length of the buffer to
// be a multiple of 8, we should enforce the stricter spec limits here.
......
......@@ -984,7 +984,7 @@ void JSArrayBuffer::JSArrayBufferPrint(std::ostream& os) { // NOLINT
if (was_neutered()) os << "\n - neutered";
if (is_shared()) os << "\n - shared";
if (has_guard_region()) os << "\n - has_guard_region";
if (is_wasm_buffer()) os << "\n - wasm_buffer";
if (is_growable()) os << "\n - growable";
JSObjectPrintBody(os, this, !was_neutered());
}
......
......@@ -151,12 +151,10 @@ void JSArrayBuffer::set_has_guard_region(bool value) {
set_bit_field(HasGuardRegion::update(bit_field(), value));
}
bool JSArrayBuffer::is_wasm_buffer() {
return IsWasmBuffer::decode(bit_field());
}
bool JSArrayBuffer::is_growable() { return IsGrowable::decode(bit_field()); }
void JSArrayBuffer::set_is_wasm_buffer(bool value) {
set_bit_field(IsWasmBuffer::update(bit_field(), value));
void JSArrayBuffer::set_is_growable(bool value) {
set_bit_field(IsGrowable::update(bit_field(), value));
}
Object* JSArrayBufferView::byte_offset() const {
......
......@@ -170,10 +170,8 @@ class JSArrayBuffer : public JSObject {
inline bool has_guard_region() const;
inline void set_has_guard_region(bool value);
// TODO(gdeepti): This flag is introduced to disable asm.js optimizations in
// js-typer-lowering.cc, remove when the asm.js case is fixed.
inline bool is_wasm_buffer();
inline void set_is_wasm_buffer(bool value);
inline bool is_growable();
inline void set_is_growable(bool value);
DECL_CAST(JSArrayBuffer)
......@@ -233,7 +231,7 @@ class JSArrayBuffer : public JSObject {
class WasNeutered : public BitField<bool, 3, 1> {};
class IsShared : public BitField<bool, 4, 1> {};
class HasGuardRegion : public BitField<bool, 5, 1> {};
class IsWasmBuffer : public BitField<bool, 6, 1> {};
class IsGrowable : public BitField<bool, 6, 1> {};
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayBuffer);
......
......@@ -1793,7 +1793,6 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() {
Handle<JSArrayBuffer> memory = memory_.ToHandleChecked();
// Set externally passed ArrayBuffer non neuterable.
memory->set_is_neuterable(false);
memory->set_is_wasm_buffer(true);
DCHECK_IMPLIES(trap_handler::UseTrapHandler(),
module_->is_asm_js() || memory->has_guard_region());
......
......@@ -753,6 +753,10 @@ void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
max_size64 = i::FLAG_wasm_max_mem_pages;
}
i::Handle<i::JSArrayBuffer> old_buffer(receiver->array_buffer());
if (!old_buffer->is_growable()) {
thrower.RangeError("This memory cannot be grown");
return;
}
uint32_t old_size =
old_buffer->byte_length()->Number() / i::wasm::kSpecMaxWasmMemoryPages;
int64_t new_size64 = old_size + delta_size;
......
......@@ -67,7 +67,7 @@ Handle<JSArrayBuffer> SetupArrayBuffer(Isolate* isolate, void* allocation_base,
allocation_length, backing_store, static_cast<int>(size),
shared);
buffer->set_is_neuterable(false);
buffer->set_is_wasm_buffer(true);
buffer->set_is_growable(true);
buffer->set_has_guard_region(enable_guard_regions);
return buffer;
}
......
......@@ -322,6 +322,7 @@ namespace {
Handle<JSArrayBuffer> GrowMemoryBuffer(Isolate* isolate,
Handle<JSArrayBuffer> old_buffer,
uint32_t pages, uint32_t maximum_pages) {
if (!old_buffer->is_growable()) return Handle<JSArrayBuffer>::null();
Address old_mem_start = nullptr;
uint32_t old_size = 0;
if (!old_buffer.is_null()) {
......@@ -466,6 +467,7 @@ int32_t WasmMemoryObject::Grow(Isolate* isolate,
Handle<WasmMemoryObject> memory_object,
uint32_t pages) {
Handle<JSArrayBuffer> old_buffer(memory_object->array_buffer());
if (!old_buffer->is_growable()) return -1;
uint32_t old_size = 0;
CHECK(old_buffer->byte_length()->ToUint32(&old_size));
DCHECK_EQ(0, old_size % WasmModule::kPageSize);
......
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function module(stdlib,foreign,buffer) {
"use asm";
var fl = new stdlib.Uint32Array(buffer);
function f1(x) {
x = x | 0;
fl[0] = x;
fl[0x10000] = x;
fl[0x100000] = x;
}
return f1;
}
var global = {Uint32Array:Uint32Array};
var env = {};
memory = new WebAssembly.Memory({initial:200});
var buffer = memory.buffer;
evil_f = module(global,env,buffer);
zz = {};
zz.toString = function() {
Array.prototype.slice.call([]);
return 0xffffffff;
}
evil_f(3);
assertThrows(() => memory.grow(1), RangeError);
evil_f(zz);
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