Commit 15e48957 authored by Clemens Backes's avatar Clemens Backes Committed by V8 LUCI CQ

[wasm] Fix integer overflow on memory growing on 32-bit

When growing a memory without a maximum, we should still check against
the spec'ed limit, to avoid an overflow when computing the new number of
pages.

R=ahaas@chromium.org

Bug: chromium:1215808
Change-Id: I476b954268277e7dce1106a9b8c3c713b0d1a560
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2944433Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74980}
parent 2f5e7706
...@@ -935,14 +935,15 @@ int32_t WasmMemoryObject::Grow(Isolate* isolate, ...@@ -935,14 +935,15 @@ int32_t WasmMemoryObject::Grow(Isolate* isolate,
size_t old_pages = old_size / wasm::kWasmPageSize; size_t old_pages = old_size / wasm::kWasmPageSize;
uint32_t max_pages = wasm::kSpecMaxMemoryPages; uint32_t max_pages = wasm::kSpecMaxMemoryPages;
if (memory_object->has_maximum_pages()) { if (memory_object->has_maximum_pages()) {
DCHECK_GE(max_pages, memory_object->maximum_pages());
max_pages = static_cast<uint32_t>(memory_object->maximum_pages()); max_pages = static_cast<uint32_t>(memory_object->maximum_pages());
DCHECK_GE(max_pages, old_pages);
if (pages > max_pages - old_pages) return -1;
} }
DCHECK_GE(max_pages, old_pages);
if (pages > max_pages - old_pages) return -1;
base::Optional<size_t> result_inplace = base::Optional<size_t> result_inplace =
backing_store->GrowWasmMemoryInPlace(isolate, pages, max_pages); backing_store->GrowWasmMemoryInPlace(isolate, pages, max_pages);
// Try to handle shared memory first. // Handle shared memory first.
if (old_buffer->is_shared()) { if (old_buffer->is_shared()) {
// Shared memories can only be grown in place; no copying. // Shared memories can only be grown in place; no copying.
if (!result_inplace.has_value()) { if (!result_inplace.has_value()) {
...@@ -972,7 +973,7 @@ int32_t WasmMemoryObject::Grow(Isolate* isolate, ...@@ -972,7 +973,7 @@ int32_t WasmMemoryObject::Grow(Isolate* isolate,
return static_cast<int32_t>(result_inplace.value()); // success return static_cast<int32_t>(result_inplace.value()); // success
} }
// Try to grow non-shared memory in-place. // Check if the non-shared memory could grow in-place.
if (result_inplace.has_value()) { if (result_inplace.has_value()) {
// Detach old and create a new one with the grown backing store. // Detach old and create a new one with the grown backing store.
old_buffer->Detach(true); old_buffer->Detach(true);
...@@ -989,6 +990,7 @@ int32_t WasmMemoryObject::Grow(Isolate* isolate, ...@@ -989,6 +990,7 @@ int32_t WasmMemoryObject::Grow(Isolate* isolate,
} }
size_t new_pages = old_pages + pages; size_t new_pages = old_pages + pages;
DCHECK_LT(old_pages, new_pages);
// Try allocating a new backing store and copying. // Try allocating a new backing store and copying.
std::unique_ptr<BackingStore> new_backing_store = std::unique_ptr<BackingStore> new_backing_store =
backing_store->CopyWasmMemory(isolate, new_pages); backing_store->CopyWasmMemory(isolate, new_pages);
......
// Copyright 2021 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.
const k4GB = 4 * 1024 * 1024 * 1024;
let memory = new WebAssembly.Memory({initial: 1});
try {
memory.grow(k4GB - 1);
} catch {}
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