| Index: src/runtime/runtime-compiler.cc
|
| diff --git a/src/runtime/runtime-compiler.cc b/src/runtime/runtime-compiler.cc
|
| index 8790da05e39a1b62b50da1d22a1c229d02c79684..d115c35e22847276d17ea5bcc0e2c6eef015ffb1 100644
|
| --- a/src/runtime/runtime-compiler.cc
|
| +++ b/src/runtime/runtime-compiler.cc
|
| @@ -352,6 +352,59 @@ bool CodeGenerationFromStringsAllowed(Isolate* isolate,
|
| }
|
|
|
|
|
| +// Walk up the stack expecting:
|
| +// - Runtime_CompileString
|
| +// - JSFunction callee (eval, Function constructor, etc)
|
| +// - call() (maybe)
|
| +// - apply() (maybe)
|
| +// - bind() (maybe)
|
| +// - JSFunction caller (maybe)
|
| +//
|
| +// return true if the caller has access to the callee or if an exit frame was
|
| +// hit, in which case allow it through, as it could have come through the api.
|
| +bool HasAccessToContextForCompileString(Isolate* isolate) {
|
| + MaybeHandle<JSFunction> callee;
|
| + bool exit_handled = true;
|
| + bool has_access = true;
|
| + bool done = false;
|
| + for (StackFrameIterator it(isolate); !it.done() && !done; it.Advance()) {
|
| + StackFrame* raw_frame = it.frame();
|
| + if (!raw_frame->is_java_script()) {
|
| + if (raw_frame->is_exit()) exit_handled = false;
|
| + continue;
|
| + }
|
| + JavaScriptFrame* outer_frame = JavaScriptFrame::cast(raw_frame);
|
| + List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
|
| + outer_frame->Summarize(&frames);
|
| + for (int i = frames.length() - 1; i >= 0 && !done; --i) {
|
| + FrameSummary& frame = frames[i];
|
| + Handle<JSFunction> fun = frame.function();
|
| + // Capture the callee function.
|
| + if (callee.is_null()) {
|
| + callee = fun;
|
| + exit_handled = true;
|
| + continue;
|
| + }
|
| + // Exit condition.
|
| + Handle<JSObject> callee_global_proxy(
|
| + callee.ToHandleChecked()->context()->global_proxy());
|
| + if (!isolate->MayAccess(handle(fun->context()), callee_global_proxy)) {
|
| + has_access = false;
|
| + done = true;
|
| + continue;
|
| + }
|
| + // Skip bound functions in correct origin.
|
| + if (fun->shared()->bound()) {
|
| + exit_handled = true;
|
| + continue;
|
| + }
|
| + done = true;
|
| + }
|
| + }
|
| + return !exit_handled || has_access;
|
| +}
|
| +
|
| +
|
| RUNTIME_FUNCTION(Runtime_CompileString) {
|
| HandleScope scope(isolate);
|
| DCHECK(args.length() == 2);
|
| @@ -361,6 +414,11 @@ RUNTIME_FUNCTION(Runtime_CompileString) {
|
| // Extract native context.
|
| Handle<Context> context(isolate->native_context());
|
|
|
| + // Filter cross security context calls.
|
| + if (!HasAccessToContextForCompileString(isolate)) {
|
| + return isolate->heap()->undefined_value();
|
| + }
|
| +
|
| // Check if native context allows code generation from
|
| // strings. Throw an exception if it doesn't.
|
| if (context->allow_code_gen_from_strings()->IsFalse() &&
|
|
|