From 5e47350645b912ab2b804309922bbd252e30332e Mon Sep 17 00:00:00 2001 From: jochen Date: Fri, 9 Oct 2015 06:25:39 -0700 Subject: [PATCH] Pass the context from which a given receiver is accessed explicitly This will allow for probing access from any context to any receiver in a future CL. BUG=none R=jkummerow@chromium.org,verwaest@chromium.org LOG=n Review URL: https://codereview.chromium.org/1398093002 Cr-Commit-Position: refs/heads/master@{#31196} --- src/api.cc | 3 ++- src/builtins.cc | 2 +- src/isolate.cc | 22 ++++++++++++++-------- src/isolate.h | 4 ++-- src/lookup.cc | 3 ++- src/objects.cc | 12 ++++++++---- src/runtime/runtime-classes.cc | 12 ++++++++---- src/runtime/runtime-object.cc | 10 +++++++--- 8 files changed, 44 insertions(+), 24 deletions(-) diff --git a/src/api.cc b/src/api.cc index ae2c8a73d6..75939db8bb 100644 --- a/src/api.cc +++ b/src/api.cc @@ -3498,7 +3498,8 @@ Maybe v8::Object::DefineOwnProperty(v8::Local context, auto key_obj = Utils::OpenHandle(*key); auto value_obj = Utils::OpenHandle(*value); - if (self->IsAccessCheckNeeded() && !isolate->MayAccess(self)) { + if (self->IsAccessCheckNeeded() && + !isolate->MayAccess(handle(isolate->context()), self)) { isolate->ReportFailedAccessCheck(self); return Nothing(); } diff --git a/src/builtins.cc b/src/builtins.cc index c97cb584f3..b672185792 100644 --- a/src/builtins.cc +++ b/src/builtins.cc @@ -1646,7 +1646,7 @@ MUST_USE_RESULT static MaybeHandle HandleApiCallHelper( Handle receiver(&args[0]); if (receiver->IsJSObject() && receiver->IsAccessCheckNeeded()) { Handle js_receiver = Handle::cast(receiver); - if (!isolate->MayAccess(js_receiver)) { + if (!isolate->MayAccess(handle(isolate->context()), js_receiver)) { isolate->ReportFailedAccessCheck(js_receiver); RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); } diff --git a/src/isolate.cc b/src/isolate.cc index 481cb42f05..c6a66cc441 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -782,12 +782,12 @@ bool Isolate::IsInternallyUsedPropertyName(Object* name) { } -bool Isolate::MayAccess(Handle receiver) { +bool Isolate::MayAccess(Handle accessing_context, + Handle receiver) { DCHECK(receiver->IsJSGlobalProxy() || receiver->IsAccessCheckNeeded()); // Check for compatibility between the security tokens in the // current lexical context and the accessed object. - DCHECK(context()); { DisallowHeapAllocation no_gc; @@ -801,7 +801,8 @@ bool Isolate::MayAccess(Handle receiver) { // Get the native context of current top context. // avoid using Isolate::native_context() because it uses Handle. - Context* native_context = context()->global_object()->native_context(); + Context* native_context = + accessing_context->global_object()->native_context(); if (receiver_context == native_context) return true; if (Context::cast(receiver_context)->security_token() == @@ -824,11 +825,16 @@ bool Isolate::MayAccess(Handle receiver) { LOG(this, ApiSecurityCheck()); - // Leaving JavaScript. - VMState state(this); - Handle key = factory()->undefined_value(); - return callback(v8::Utils::ToLocal(receiver), v8::Utils::ToLocal(key), - v8::ACCESS_HAS, v8::Utils::ToLocal(data)); + { + SaveContext save(this); + set_context(accessing_context->native_context()); + + // Leaving JavaScript. + VMState state(this); + Handle key = factory()->undefined_value(); + return callback(v8::Utils::ToLocal(receiver), v8::Utils::ToLocal(key), + v8::ACCESS_HAS, v8::Utils::ToLocal(data)); + } } diff --git a/src/isolate.h b/src/isolate.h index 86ae7b646b..8c167e1421 100644 --- a/src/isolate.h +++ b/src/isolate.h @@ -679,11 +679,11 @@ class Isolate { Handle GetDetailedFromSimpleStackTrace( Handle error_object); - // Returns if the top context may access the given global object. If + // Returns if the given context may access the given global object. If // the result is false, the pending exception is guaranteed to be // set. + bool MayAccess(Handle accessing_context, Handle receiver); - bool MayAccess(Handle receiver); bool IsInternallyUsedPropertyName(Handle name); bool IsInternallyUsedPropertyName(Object* name); diff --git a/src/lookup.cc b/src/lookup.cc index a404cd9cd4..eb79ba190f 100644 --- a/src/lookup.cc +++ b/src/lookup.cc @@ -134,7 +134,8 @@ Handle LookupIterator::GetStoreTarget() const { bool LookupIterator::HasAccess() const { DCHECK_EQ(ACCESS_CHECK, state_); - return isolate_->MayAccess(GetHolder()); + return isolate_->MayAccess(handle(isolate_->context()), + GetHolder()); } diff --git a/src/objects.cc b/src/objects.cc index 8336c12909..80782d8732 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -6001,7 +6001,8 @@ Maybe JSObject::PreventExtensionsInternal(Handle object) { return PreventExtensionsWithTransition(object); } - if (object->IsAccessCheckNeeded() && !isolate->MayAccess(object)) { + if (object->IsAccessCheckNeeded() && + !isolate->MayAccess(handle(isolate->context()), object)) { isolate->ReportFailedAccessCheck(object); RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing()); UNREACHABLE(); @@ -6067,7 +6068,8 @@ MaybeHandle JSObject::PreventExtensions(Handle object) { bool JSObject::IsExtensible(Handle object) { Isolate* isolate = object->GetIsolate(); - if (object->IsAccessCheckNeeded() && !isolate->MayAccess(object)) { + if (object->IsAccessCheckNeeded() && + !isolate->MayAccess(handle(isolate->context()), object)) { return true; } if (object->IsJSGlobalProxy()) { @@ -6113,7 +6115,8 @@ Maybe JSObject::PreventExtensionsWithTransition(Handle object) { DCHECK(!object->map()->is_observed()); Isolate* isolate = object->GetIsolate(); - if (object->IsAccessCheckNeeded() && !isolate->MayAccess(object)) { + if (object->IsAccessCheckNeeded() && + !isolate->MayAccess(handle(isolate->context()), object)) { isolate->ReportFailedAccessCheck(object); RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing()); UNREACHABLE(); @@ -6921,7 +6924,8 @@ MaybeHandle JSReceiver::GetKeys(Handle object, Handle current = PrototypeIterator::GetCurrent(iter); // Check access rights if required. - if (current->IsAccessCheckNeeded() && !isolate->MayAccess(current)) { + if (current->IsAccessCheckNeeded() && + !isolate->MayAccess(handle(isolate->context()), current)) { if (iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) { isolate->ReportFailedAccessCheck(current); RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, FixedArray); diff --git a/src/runtime/runtime-classes.cc b/src/runtime/runtime-classes.cc index 51e682f325..8eee6b808e 100644 --- a/src/runtime/runtime-classes.cc +++ b/src/runtime/runtime-classes.cc @@ -269,7 +269,8 @@ static MaybeHandle LoadFromSuper(Isolate* isolate, Handle home_object, Handle name, LanguageMode language_mode) { - if (home_object->IsAccessCheckNeeded() && !isolate->MayAccess(home_object)) { + if (home_object->IsAccessCheckNeeded() && + !isolate->MayAccess(handle(isolate->context()), home_object)) { isolate->ReportFailedAccessCheck(home_object); RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); } @@ -293,7 +294,8 @@ static MaybeHandle LoadElementFromSuper(Isolate* isolate, Handle home_object, uint32_t index, LanguageMode language_mode) { - if (home_object->IsAccessCheckNeeded() && !isolate->MayAccess(home_object)) { + if (home_object->IsAccessCheckNeeded() && + !isolate->MayAccess(handle(isolate->context()), home_object)) { isolate->ReportFailedAccessCheck(home_object); RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); } @@ -369,7 +371,8 @@ RUNTIME_FUNCTION(Runtime_LoadKeyedFromSuper) { static Object* StoreToSuper(Isolate* isolate, Handle home_object, Handle receiver, Handle name, Handle value, LanguageMode language_mode) { - if (home_object->IsAccessCheckNeeded() && !isolate->MayAccess(home_object)) { + if (home_object->IsAccessCheckNeeded() && + !isolate->MayAccess(handle(isolate->context()), home_object)) { isolate->ReportFailedAccessCheck(home_object); RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); } @@ -393,7 +396,8 @@ static Object* StoreElementToSuper(Isolate* isolate, Handle receiver, uint32_t index, Handle value, LanguageMode language_mode) { - if (home_object->IsAccessCheckNeeded() && !isolate->MayAccess(home_object)) { + if (home_object->IsAccessCheckNeeded() && + !isolate->MayAccess(handle(isolate->context()), home_object)) { isolate->ReportFailedAccessCheck(home_object); RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); } diff --git a/src/runtime/runtime-object.cc b/src/runtime/runtime-object.cc index ce54716862..3d02572a0e 100644 --- a/src/runtime/runtime-object.cc +++ b/src/runtime/runtime-object.cc @@ -160,9 +160,11 @@ RUNTIME_FUNCTION(Runtime_GetPrototype) { // We don't expect access checks to be needed on JSProxy objects. DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject()); PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); + Handle context(isolate->context()); do { if (PrototypeIterator::GetCurrent(iter)->IsAccessCheckNeeded() && - !isolate->MayAccess(PrototypeIterator::GetCurrent(iter))) { + !isolate->MayAccess(context, + PrototypeIterator::GetCurrent(iter))) { return isolate->heap()->null_value(); } iter.AdvanceIgnoringProxies(); @@ -193,7 +195,8 @@ RUNTIME_FUNCTION(Runtime_SetPrototype) { DCHECK(args.length() == 2); CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1); - if (obj->IsAccessCheckNeeded() && !isolate->MayAccess(obj)) { + if (obj->IsAccessCheckNeeded() && + !isolate->MayAccess(handle(isolate->context()), obj)) { isolate->ReportFailedAccessCheck(obj); RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); return isolate->heap()->undefined_value(); @@ -849,7 +852,8 @@ RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) { CHECK_EQ(total_property_count, next_copy_index); - if (object->IsAccessCheckNeeded() && !isolate->MayAccess(object)) { + if (object->IsAccessCheckNeeded() && + !isolate->MayAccess(handle(isolate->context()), object)) { for (int i = 0; i < total_property_count; i++) { Handle name(Name::cast(names->get(i))); if (name.is_identical_to(hidden_string)) continue;