summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-09-03 10:30:31 +0200
committerAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-09-03 11:13:30 +0000
commit844798909ee644ea9ef223d1ad3902736c85605c (patch)
treefcbe39f464812b6885d6ef4cb64c7077a65ab401
parentf7c5611ba40305cd723b6794d8fbd3671fee42ac (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.cc48
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);
}