Commit 5fa584c8 authored by Jakob Gruber's avatar Jakob Gruber Committed by Commit Bot

[csa] Check maximal array size on allocation

This condition is easy to miss at call sites and could create 'fast'
arrays that are too large. Let's make this a runtime CHECK instead.

Bug: chromium:901944
Change-Id: I8f8f161781414944b67099007a98f76972496ae2
Reviewed-on: https://chromium-review.googlesource.com/c/1319571Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57281}
parent b8e8b0de
...@@ -897,8 +897,9 @@ Node* ArrayBuiltinsAssembler::FindProcessor(Node* k_value, Node* k) { ...@@ -897,8 +897,9 @@ Node* ArrayBuiltinsAssembler::FindProcessor(Node* k_value, Node* k) {
GotoIf(WordEqual(value, protector_invalid), &runtime); GotoIf(WordEqual(value, protector_invalid), &runtime);
GotoIfNot(TaggedIsPositiveSmi(len), &runtime); GotoIfNot(TaggedIsPositiveSmi(len), &runtime);
GotoIf(SmiAbove(CAST(len), SmiConstant(JSArray::kMaxFastArrayLength)), GotoIfNot(
&runtime); IsValidFastJSArrayCapacity(len, CodeStubAssembler::SMI_PARAMETERS),
&runtime);
// We need to be conservative and start with holey because the builtins // We need to be conservative and start with holey because the builtins
// that create output arrays aren't guaranteed to be called for every // that create output arrays aren't guaranteed to be called for every
......
...@@ -3856,6 +3856,13 @@ void CodeStubAssembler::StoreFieldsNoWriteBarrier(Node* start_address, ...@@ -3856,6 +3856,13 @@ void CodeStubAssembler::StoreFieldsNoWriteBarrier(Node* start_address,
kPointerSize, INTPTR_PARAMETERS, IndexAdvanceMode::kPost); kPointerSize, INTPTR_PARAMETERS, IndexAdvanceMode::kPost);
} }
TNode<BoolT> CodeStubAssembler::IsValidFastJSArrayCapacity(
Node* capacity, ParameterMode capacity_mode) {
return UncheckedCast<BoolT>(
UintPtrLessThanOrEqual(ParameterToIntPtr(capacity, capacity_mode),
IntPtrConstant(JSArray::kMaxFastArrayLength)));
}
TNode<JSArray> CodeStubAssembler::AllocateUninitializedJSArrayWithoutElements( TNode<JSArray> CodeStubAssembler::AllocateUninitializedJSArrayWithoutElements(
TNode<Map> array_map, TNode<Smi> length, Node* allocation_site) { TNode<Map> array_map, TNode<Smi> length, Node* allocation_site) {
Comment("begin allocation of JSArray without elements"); Comment("begin allocation of JSArray without elements");
...@@ -3878,11 +3885,6 @@ CodeStubAssembler::AllocateUninitializedJSArrayWithElements( ...@@ -3878,11 +3885,6 @@ CodeStubAssembler::AllocateUninitializedJSArrayWithElements(
Comment("begin allocation of JSArray with elements"); Comment("begin allocation of JSArray with elements");
CHECK_EQ(allocation_flags & ~kAllowLargeObjectAllocation, 0); CHECK_EQ(allocation_flags & ~kAllowLargeObjectAllocation, 0);
CSA_SLOW_ASSERT(this, TaggedIsPositiveSmi(length)); CSA_SLOW_ASSERT(this, TaggedIsPositiveSmi(length));
CSA_ASSERT(this, IntPtrOrSmiLessThanOrEqual(
capacity,
IntPtrOrSmiConstant(JSArray::kMaxFastArrayLength,
capacity_mode),
capacity_mode));
int base_size = JSArray::kSize; int base_size = JSArray::kSize;
if (allocation_site != nullptr) base_size += AllocationMemento::kSize; if (allocation_site != nullptr) base_size += AllocationMemento::kSize;
...@@ -3908,6 +3910,8 @@ CodeStubAssembler::AllocateUninitializedJSArrayWithElements( ...@@ -3908,6 +3910,8 @@ CodeStubAssembler::AllocateUninitializedJSArrayWithElements(
Label next(this); Label next(this);
GotoIf(IsRegularHeapObjectSize(size), &next); GotoIf(IsRegularHeapObjectSize(size), &next);
CSA_CHECK(this, IsValidFastJSArrayCapacity(capacity, capacity_mode));
// Allocate and initialize the elements first. // Allocate and initialize the elements first.
elements = elements =
AllocateFixedArray(kind, capacity, capacity_mode, allocation_flags); AllocateFixedArray(kind, capacity, capacity_mode, allocation_flags);
......
...@@ -1477,6 +1477,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { ...@@ -1477,6 +1477,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
Node* object, Node* map, Node* instance_size, Node* object, Node* map, Node* instance_size,
int start_offset = JSObject::kHeaderSize); int start_offset = JSObject::kHeaderSize);
TNode<BoolT> IsValidFastJSArrayCapacity(Node* capacity,
ParameterMode capacity_mode);
// Allocate a JSArray without elements and initialize the header fields. // Allocate a JSArray without elements and initialize the header fields.
TNode<JSArray> AllocateUninitializedJSArrayWithoutElements( TNode<JSArray> AllocateUninitializedJSArrayWithoutElements(
TNode<Map> array_map, TNode<Smi> length, Node* allocation_site = nullptr); TNode<Map> array_map, TNode<Smi> length, Node* allocation_site = nullptr);
......
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