[runtime] Fix TypedArrayPrototype protector cell checks
Previously, we were looking up the prototype of the receiver and checking that against %TypedArrayPrototype% before invalidating the protector cell. This is incorrect as it's possible to patch the prototype and then change the constructor property, bypassing this check. This CL adds a new instance type to prototype of all TypedArray constructors and checks the receiver against this instance type. TBR: tebbi@chromium.org Bug: v8:11274, v8:11256 Change-Id: I2ff6280e4cf820b06c5593fe4addd36f7ac656c4 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2594776 Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/master@{#71799}
This commit is contained in:
parent
62355eeb2c
commit
15c227befb
@ -149,6 +149,9 @@ extern class JSRegExpPrototype extends JSPrototype
|
||||
extern class JSPromisePrototype extends JSPrototype
|
||||
generates 'TNode<JSObject>';
|
||||
@doNotGenerateCast
|
||||
extern class JSTypedArrayPrototype extends JSPrototype
|
||||
generates 'TNode<JSObject>';
|
||||
@doNotGenerateCast
|
||||
extern class JSSetPrototype extends JSPrototype
|
||||
generates 'TNode<JSObject>';
|
||||
@doNotGenerateCast
|
||||
|
@ -198,6 +198,7 @@ Type::bitset BitsetType::Lub(const MapRefLike& map) {
|
||||
case JS_GLOBAL_PROXY_TYPE:
|
||||
case JS_API_OBJECT_TYPE:
|
||||
case JS_SPECIAL_API_OBJECT_TYPE:
|
||||
case JS_TYPED_ARRAY_PROTOTYPE_TYPE:
|
||||
if (map.is_undetectable()) {
|
||||
// Currently we assume that every undetectable receiver is also
|
||||
// callable, which is what we need to support document.all. We
|
||||
|
@ -228,6 +228,7 @@ void HeapObject::HeapObjectVerify(Isolate* isolate) {
|
||||
case JS_SET_PROTOTYPE_TYPE:
|
||||
case JS_SPECIAL_API_OBJECT_TYPE:
|
||||
case JS_STRING_ITERATOR_PROTOTYPE_TYPE:
|
||||
case JS_TYPED_ARRAY_PROTOTYPE_TYPE:
|
||||
JSObject::cast(*this).JSObjectVerify(isolate);
|
||||
break;
|
||||
case WASM_INSTANCE_OBJECT_TYPE:
|
||||
|
@ -173,6 +173,7 @@ void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT
|
||||
case JS_SET_PROTOTYPE_TYPE:
|
||||
case JS_SPECIAL_API_OBJECT_TYPE:
|
||||
case JS_STRING_ITERATOR_PROTOTYPE_TYPE:
|
||||
case JS_TYPED_ARRAY_PROTOTYPE_TYPE:
|
||||
JSObject::cast(*this).JSObjectPrint(os);
|
||||
break;
|
||||
case WASM_INSTANCE_OBJECT_TYPE:
|
||||
|
@ -4044,6 +4044,10 @@ Handle<JSFunction> Genesis::InstallTypedArray(const char* name,
|
||||
kDontThrow)
|
||||
.FromJust());
|
||||
|
||||
CHECK_NE(prototype->map().ptr(),
|
||||
isolate_->initial_object_prototype()->map().ptr());
|
||||
prototype->map().set_instance_type(JS_TYPED_ARRAY_PROTOTYPE_TYPE);
|
||||
|
||||
InstallConstant(isolate(), prototype, "BYTES_PER_ELEMENT", bytes_per_element);
|
||||
return result;
|
||||
}
|
||||
|
@ -520,6 +520,7 @@ bool CanSubclassHaveInobjectProperties(InstanceType instance_type) {
|
||||
case JS_SET_ITERATOR_PROTOTYPE_TYPE:
|
||||
case JS_SET_PROTOTYPE_TYPE:
|
||||
case JS_STRING_ITERATOR_PROTOTYPE_TYPE:
|
||||
case JS_TYPED_ARRAY_PROTOTYPE_TYPE:
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
case JS_COLLATOR_TYPE:
|
||||
case JS_DATE_TIME_FORMAT_TYPE:
|
||||
|
@ -2185,6 +2185,7 @@ int JSObject::GetHeaderSize(InstanceType type,
|
||||
case JS_SPECIAL_API_OBJECT_TYPE:
|
||||
case JS_STRING_ITERATOR_PROTOTYPE_TYPE:
|
||||
case JS_ARRAY_ITERATOR_PROTOTYPE_TYPE:
|
||||
case JS_TYPED_ARRAY_PROTOTYPE_TYPE:
|
||||
return JSObject::kHeaderSize;
|
||||
case JS_GENERATOR_OBJECT_TYPE:
|
||||
return JSGeneratorObject::kHeaderSize;
|
||||
|
@ -234,9 +234,6 @@ void LookupIterator::InternalUpdateProtector(Isolate* isolate,
|
||||
DisallowGarbageCollection no_gc;
|
||||
// Setting the constructor of any prototype with the @@species protector
|
||||
// (of any realm) also needs to invalidate the protector.
|
||||
// For typed arrays, we check a prototype of this receiver since
|
||||
// TypedArrays have different prototypes for each type, and their parent
|
||||
// prototype is pointing the same TYPED_ARRAY_PROTOTYPE.
|
||||
if (isolate->IsInAnyContext(*receiver,
|
||||
Context::INITIAL_ARRAY_PROTOTYPE_INDEX)) {
|
||||
if (!Protectors::IsArraySpeciesLookupChainIntact(isolate)) return;
|
||||
@ -251,9 +248,7 @@ void LookupIterator::InternalUpdateProtector(Isolate* isolate,
|
||||
Context::REGEXP_PROTOTYPE_INDEX)) {
|
||||
if (!Protectors::IsRegExpSpeciesLookupChainIntact(isolate)) return;
|
||||
Protectors::InvalidateRegExpSpeciesLookupChain(isolate);
|
||||
} else if (isolate->IsInAnyContext(
|
||||
receiver->map(isolate).prototype(isolate),
|
||||
Context::TYPED_ARRAY_PROTOTYPE_INDEX)) {
|
||||
} else if (receiver->IsJSTypedArrayPrototype()) {
|
||||
if (!Protectors::IsTypedArraySpeciesLookupChainIntact(isolate)) return;
|
||||
Protectors::InvalidateTypedArraySpeciesLookupChain(isolate);
|
||||
}
|
||||
|
@ -283,6 +283,7 @@ VisitorId Map::GetVisitorId(Map map) {
|
||||
case JS_SET_VALUE_ITERATOR_TYPE:
|
||||
case JS_STRING_ITERATOR_PROTOTYPE_TYPE:
|
||||
case JS_STRING_ITERATOR_TYPE:
|
||||
case JS_TYPED_ARRAY_PROTOTYPE_TYPE:
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
case JS_V8_BREAK_ITERATOR_TYPE:
|
||||
case JS_COLLATOR_TYPE:
|
||||
|
@ -283,6 +283,7 @@ class ZoneForwardList;
|
||||
V(JSIteratorPrototype) \
|
||||
V(JSArrayIteratorPrototype) \
|
||||
V(JSMapIteratorPrototype) \
|
||||
V(JSTypedArrayPrototype) \
|
||||
V(JSSetIteratorPrototype) \
|
||||
V(JSStringIteratorPrototype)
|
||||
|
||||
|
@ -975,6 +975,7 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
|
||||
case JS_SPECIAL_API_OBJECT_TYPE:
|
||||
case JS_STRING_ITERATOR_PROTOTYPE_TYPE:
|
||||
case JS_STRING_ITERATOR_TYPE:
|
||||
case JS_TYPED_ARRAY_PROTOTYPE_TYPE:
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
case JS_V8_BREAK_ITERATOR_TYPE:
|
||||
case JS_COLLATOR_TYPE:
|
||||
|
@ -540,6 +540,7 @@ Maybe<bool> ValueSerializer::WriteJSReceiver(Handle<JSReceiver> receiver) {
|
||||
case JS_SET_ITERATOR_PROTOTYPE_TYPE:
|
||||
case JS_SET_PROTOTYPE_TYPE:
|
||||
case JS_STRING_ITERATOR_PROTOTYPE_TYPE:
|
||||
case JS_TYPED_ARRAY_PROTOTYPE_TYPE:
|
||||
case JS_API_OBJECT_TYPE: {
|
||||
Handle<JSObject> js_object = Handle<JSObject>::cast(receiver);
|
||||
if (JSObject::GetEmbedderFieldCount(js_object->map())) {
|
||||
|
20
test/mjsunit/regress/regress-11274.js
Normal file
20
test/mjsunit/regress/regress-11274.js
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright 2020 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.
|
||||
|
||||
var typedArrayProto = Uint8Array.prototype.__proto__;
|
||||
var typedArrayConstructor = Uint8Array.prototype.constructor[Symbol.species];
|
||||
var called = false;
|
||||
|
||||
Uint8Array.prototype.__proto__ = {};
|
||||
Uint8Array.prototype.constructor = {
|
||||
get [Symbol.species]() {
|
||||
called = true;
|
||||
return typedArrayConstructor;
|
||||
}
|
||||
}
|
||||
|
||||
Uint8Array.prototype.__proto__ = typedArrayProto;
|
||||
var arr = new Uint8Array(8);
|
||||
arr.slice(1, 5);
|
||||
assertTrue(called);
|
@ -162,56 +162,57 @@ INSTANCE_TYPES = {
|
||||
1048: "JS_SET_ITERATOR_PROTOTYPE_TYPE",
|
||||
1049: "JS_SET_PROTOTYPE_TYPE",
|
||||
1050: "JS_STRING_ITERATOR_PROTOTYPE_TYPE",
|
||||
1051: "JS_MAP_KEY_ITERATOR_TYPE",
|
||||
1052: "JS_MAP_KEY_VALUE_ITERATOR_TYPE",
|
||||
1053: "JS_MAP_VALUE_ITERATOR_TYPE",
|
||||
1054: "JS_SET_KEY_VALUE_ITERATOR_TYPE",
|
||||
1055: "JS_SET_VALUE_ITERATOR_TYPE",
|
||||
1051: "JS_TYPED_ARRAY_PROTOTYPE_TYPE",
|
||||
1052: "JS_GENERATOR_OBJECT_TYPE",
|
||||
1053: "JS_ASYNC_FUNCTION_OBJECT_TYPE",
|
||||
1054: "JS_ASYNC_GENERATOR_OBJECT_TYPE",
|
||||
1055: "JS_ARGUMENTS_OBJECT_TYPE",
|
||||
1056: "JS_API_OBJECT_TYPE",
|
||||
1058: "JS_GENERATOR_OBJECT_TYPE",
|
||||
1059: "JS_ASYNC_FUNCTION_OBJECT_TYPE",
|
||||
1060: "JS_ASYNC_GENERATOR_OBJECT_TYPE",
|
||||
1061: "JS_DATA_VIEW_TYPE",
|
||||
1062: "JS_TYPED_ARRAY_TYPE",
|
||||
1063: "JS_MAP_TYPE",
|
||||
1064: "JS_SET_TYPE",
|
||||
1065: "JS_WEAK_MAP_TYPE",
|
||||
1066: "JS_WEAK_SET_TYPE",
|
||||
1067: "JS_ARGUMENTS_OBJECT_TYPE",
|
||||
1068: "JS_ARRAY_TYPE",
|
||||
1069: "JS_ARRAY_BUFFER_TYPE",
|
||||
1070: "JS_ARRAY_ITERATOR_TYPE",
|
||||
1071: "JS_ASYNC_FROM_SYNC_ITERATOR_TYPE",
|
||||
1072: "JS_COLLATOR_TYPE",
|
||||
1073: "JS_CONTEXT_EXTENSION_OBJECT_TYPE",
|
||||
1074: "JS_DATE_TYPE",
|
||||
1075: "JS_DATE_TIME_FORMAT_TYPE",
|
||||
1076: "JS_DISPLAY_NAMES_TYPE",
|
||||
1077: "JS_ERROR_TYPE",
|
||||
1078: "JS_FINALIZATION_REGISTRY_TYPE",
|
||||
1079: "JS_LIST_FORMAT_TYPE",
|
||||
1080: "JS_LOCALE_TYPE",
|
||||
1081: "JS_MESSAGE_OBJECT_TYPE",
|
||||
1082: "JS_NUMBER_FORMAT_TYPE",
|
||||
1083: "JS_PLURAL_RULES_TYPE",
|
||||
1084: "JS_PROMISE_TYPE",
|
||||
1085: "JS_REG_EXP_TYPE",
|
||||
1086: "JS_REG_EXP_STRING_ITERATOR_TYPE",
|
||||
1087: "JS_RELATIVE_TIME_FORMAT_TYPE",
|
||||
1088: "JS_SEGMENT_ITERATOR_TYPE",
|
||||
1089: "JS_SEGMENTER_TYPE",
|
||||
1090: "JS_SEGMENTS_TYPE",
|
||||
1091: "JS_STRING_ITERATOR_TYPE",
|
||||
1092: "JS_V8_BREAK_ITERATOR_TYPE",
|
||||
1093: "JS_WEAK_REF_TYPE",
|
||||
1094: "WASM_EXCEPTION_OBJECT_TYPE",
|
||||
1095: "WASM_GLOBAL_OBJECT_TYPE",
|
||||
1096: "WASM_INSTANCE_OBJECT_TYPE",
|
||||
1097: "WASM_MEMORY_OBJECT_TYPE",
|
||||
1098: "WASM_MODULE_OBJECT_TYPE",
|
||||
1099: "WASM_TABLE_OBJECT_TYPE",
|
||||
1100: "JS_BOUND_FUNCTION_TYPE",
|
||||
1101: "JS_FUNCTION_TYPE",
|
||||
1058: "JS_MAP_KEY_ITERATOR_TYPE",
|
||||
1059: "JS_MAP_KEY_VALUE_ITERATOR_TYPE",
|
||||
1060: "JS_MAP_VALUE_ITERATOR_TYPE",
|
||||
1061: "JS_SET_KEY_VALUE_ITERATOR_TYPE",
|
||||
1062: "JS_SET_VALUE_ITERATOR_TYPE",
|
||||
1063: "JS_DATA_VIEW_TYPE",
|
||||
1064: "JS_TYPED_ARRAY_TYPE",
|
||||
1065: "JS_MAP_TYPE",
|
||||
1066: "JS_SET_TYPE",
|
||||
1067: "JS_WEAK_MAP_TYPE",
|
||||
1068: "JS_WEAK_SET_TYPE",
|
||||
1069: "JS_ARRAY_TYPE",
|
||||
1070: "JS_ARRAY_BUFFER_TYPE",
|
||||
1071: "JS_ARRAY_ITERATOR_TYPE",
|
||||
1072: "JS_ASYNC_FROM_SYNC_ITERATOR_TYPE",
|
||||
1073: "JS_COLLATOR_TYPE",
|
||||
1074: "JS_CONTEXT_EXTENSION_OBJECT_TYPE",
|
||||
1075: "JS_DATE_TYPE",
|
||||
1076: "JS_DATE_TIME_FORMAT_TYPE",
|
||||
1077: "JS_DISPLAY_NAMES_TYPE",
|
||||
1078: "JS_ERROR_TYPE",
|
||||
1079: "JS_FINALIZATION_REGISTRY_TYPE",
|
||||
1080: "JS_LIST_FORMAT_TYPE",
|
||||
1081: "JS_LOCALE_TYPE",
|
||||
1082: "JS_MESSAGE_OBJECT_TYPE",
|
||||
1083: "JS_NUMBER_FORMAT_TYPE",
|
||||
1084: "JS_PLURAL_RULES_TYPE",
|
||||
1085: "JS_PROMISE_TYPE",
|
||||
1086: "JS_REG_EXP_TYPE",
|
||||
1087: "JS_REG_EXP_STRING_ITERATOR_TYPE",
|
||||
1088: "JS_RELATIVE_TIME_FORMAT_TYPE",
|
||||
1089: "JS_SEGMENT_ITERATOR_TYPE",
|
||||
1090: "JS_SEGMENTER_TYPE",
|
||||
1091: "JS_SEGMENTS_TYPE",
|
||||
1092: "JS_STRING_ITERATOR_TYPE",
|
||||
1093: "JS_V8_BREAK_ITERATOR_TYPE",
|
||||
1094: "JS_WEAK_REF_TYPE",
|
||||
1095: "WASM_EXCEPTION_OBJECT_TYPE",
|
||||
1096: "WASM_GLOBAL_OBJECT_TYPE",
|
||||
1097: "WASM_INSTANCE_OBJECT_TYPE",
|
||||
1098: "WASM_MEMORY_OBJECT_TYPE",
|
||||
1099: "WASM_MODULE_OBJECT_TYPE",
|
||||
1100: "WASM_TABLE_OBJECT_TYPE",
|
||||
1101: "JS_BOUND_FUNCTION_TYPE",
|
||||
1102: "JS_FUNCTION_TYPE",
|
||||
}
|
||||
|
||||
# List of known V8 maps.
|
||||
@ -369,7 +370,7 @@ KNOWN_MAPS = {
|
||||
("read_only_space", 0x05d2d): (78, "StoreHandler2Map"),
|
||||
("read_only_space", 0x05d55): (78, "StoreHandler3Map"),
|
||||
("map_space", 0x02115): (1057, "ExternalMap"),
|
||||
("map_space", 0x0213d): (1081, "JSMessageObjectMap"),
|
||||
("map_space", 0x0213d): (1082, "JSMessageObjectMap"),
|
||||
("map_space", 0x02165): (182, "WasmRttEqrefMap"),
|
||||
("map_space", 0x0218d): (182, "WasmRttAnyrefMap"),
|
||||
("map_space", 0x021b5): (182, "WasmRttExternrefMap"),
|
||||
|
Loading…
Reference in New Issue
Block a user