From c27758bcc761821ea882d27b0ad254e3386bb7e5 Mon Sep 17 00:00:00 2001 From: "mstarzinger@chromium.org" Date: Thu, 20 Mar 2014 18:14:33 +0000 Subject: [PATCH] Fix missing access check in Runtime_SetPrototype. R=rossberg@chromium.org BUG=chromium:354123 TEST=cctest/test-api/Regress354123 LOG=y Review URL: https://codereview.chromium.org/205033011 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20138 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/runtime.cc | 8 ++++++++ test/cctest/test-api.cc | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/src/runtime.cc b/src/runtime.cc index 3fd5c33..109e415 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -1686,6 +1686,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetPrototype) { ASSERT(args.length() == 2); CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1); + if (obj->IsAccessCheckNeeded() && + !isolate->MayNamedAccessWrapper(obj, + isolate->factory()->proto_string(), + v8::ACCESS_SET)) { + isolate->ReportFailedAccessCheckWrapper(obj, v8::ACCESS_SET); + RETURN_IF_SCHEDULED_EXCEPTION(isolate); + return isolate->heap()->undefined_value(); + } if (obj->map()->is_observed()) { Handle old_value( GetPrototypeSkipHiddenPrototypes(isolate, *obj), isolate); diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index eea97c4..a1b05f9 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -22298,3 +22298,48 @@ TEST(ThrowOnJavascriptExecution) { CompileRun("1+1"); CHECK(try_catch.HasCaught()); } + + +TEST(Regress354123) { + LocalContext current; + v8::Isolate* isolate = current->GetIsolate(); + v8::HandleScope scope(isolate); + + v8::Handle templ = v8::ObjectTemplate::New(isolate); + templ->SetAccessCheckCallbacks(NamedAccessCounter, IndexedAccessCounter); + current->Global()->Set(v8_str("friend"), templ->NewInstance()); + + // Test access using __proto__ from the prototype chain. + named_access_count = 0; + CompileRun("friend.__proto__ = {};"); + CHECK_EQ(2, named_access_count); + CompileRun("friend.__proto__;"); + CHECK_EQ(4, named_access_count); + + // Test access using __proto__ as a hijacked function (A). + named_access_count = 0; + CompileRun("var p = Object.prototype;" + "var f = Object.getOwnPropertyDescriptor(p, '__proto__').set;" + "f.call(friend, {});"); + CHECK_EQ(1, named_access_count); + CompileRun("var p = Object.prototype;" + "var f = Object.getOwnPropertyDescriptor(p, '__proto__').get;" + "f.call(friend);"); + CHECK_EQ(2, named_access_count); + + // Test access using __proto__ as a hijacked function (B). + named_access_count = 0; + CompileRun("var f = Object.prototype.__lookupSetter__('__proto__');" + "f.call(friend, {});"); + CHECK_EQ(1, named_access_count); + CompileRun("var f = Object.prototype.__lookupGetter__('__proto__');" + "f.call(friend);"); + CHECK_EQ(2, named_access_count); + + // Test access using Object.setPrototypeOf reflective method. + named_access_count = 0; + CompileRun("Object.setPrototypeOf(friend, {});"); + CHECK_EQ(1, named_access_count); + CompileRun("Object.getPrototypeOf(friend);"); + CHECK_EQ(2, named_access_count); +} -- 2.7.4