diff options
author | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2015-09-03 10:30:31 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2015-09-03 11:13:30 +0000 |
commit | 844798909ee644ea9ef223d1ad3902736c85605c (patch) | |
tree | fcbe39f464812b6885d6ef4cb64c7077a65ab401 | |
parent | f7c5611ba40305cd723b6794d8fbd3671fee42ac (diff) |
<v8> Cherry-pick fix for CVE-2015-1290
Move compatible receiver check from CompileHandler to UpdateCaches
We also need to do the check before using an existing handler from the
cache
BUG=chromium:505374
R=verwaest@chromium.org
LOG=y
Review URL: https://codereview.chromium.org/1221433010
Change-Id: I65b463301804ded47e730048d110956f68b05c91
Reviewed-by: Kai Koehne <kai.koehne@theqtcompany.com>
-rw-r--r-- | chromium/v8/src/ic/ic.cc | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/chromium/v8/src/ic/ic.cc b/chromium/v8/src/ic/ic.cc index a9369ed4e00..987e0c8e23a 100644 --- a/chromium/v8/src/ic/ic.cc +++ b/chromium/v8/src/ic/ic.cc @@ -965,7 +965,39 @@ void LoadIC::UpdateCaches(LookupIterator* lookup) { code = slow_stub(); } } else { - code = ComputeHandler(lookup); + if (lookup->state() == LookupIterator::ACCESSOR) { + Handle<Object> accessors = lookup->GetAccessors(); + Handle<HeapType> type = receiver_type(); + if (accessors->IsExecutableAccessorInfo()) { + Handle<ExecutableAccessorInfo> info = + Handle<ExecutableAccessorInfo>::cast(accessors); + if ((v8::ToCData<Address>(info->getter()) != 0) && + !ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(), info, + type)) { + TRACE_GENERIC_IC(isolate(), "LoadIC", "incompatible receiver type"); + code = slow_stub(); + } + } else if (accessors->IsAccessorPair()) { + Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(), + isolate()); + Handle<JSObject> holder = lookup->GetHolder<JSObject>(); + Handle<Object> receiver = lookup->GetReceiver(); + if (getter->IsJSFunction() && holder->HasFastProperties()) { + Handle<JSFunction> function = Handle<JSFunction>::cast(getter); + if (receiver->IsJSObject() || function->IsBuiltin() || + function->shared()->strict_mode() != SLOPPY) { + CallOptimization call_optimization(function); + if (call_optimization.is_simple_api_call() && + !call_optimization.IsCompatibleReceiver(receiver, holder)) { + TRACE_GENERIC_IC(isolate(), "LoadIC", + "incompatible receiver type"); + code = slow_stub(); + } + } + } + } + } + if (code.is_null()) code = ComputeHandler(lookup); } PatchCache(lookup->name(), code); @@ -1096,6 +1128,8 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup, if (v8::ToCData<Address>(info->getter()) == 0) break; if (!ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(), info, type)) { + // This case should be already handled in LoadIC::UpdateCaches. + UNREACHABLE(); break; } if (!holder->HasFastProperties()) break; @@ -1118,10 +1152,14 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup, CallOptimization call_optimization(function); NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), holder, cache_holder); - if (call_optimization.is_simple_api_call() && - call_optimization.IsCompatibleReceiver(receiver, holder)) { - return compiler.CompileLoadCallback(lookup->name(), - call_optimization); + if (call_optimization.is_simple_api_call()) { + if (call_optimization.IsCompatibleReceiver(receiver, holder)) { + return compiler.CompileLoadCallback(lookup->name(), + call_optimization); + } else { + // This case should be already handled in LoadIC::UpdateCaches. + UNREACHABLE(); + } } return compiler.CompileLoadViaGetter(lookup->name(), function); } |