| Index: src/runtime.cc
|
| diff --git a/src/runtime.cc b/src/runtime.cc
|
| index 7eb753ab1c9d36f6848efb21f6d7b4f83ae05fa6..0f8d79406739ac5d45479c398a24cfc06f78df3e 100644
|
| --- a/src/runtime.cc
|
| +++ b/src/runtime.cc
|
| @@ -9782,6 +9782,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 the same security token as the callee
|
| +// or if an exit frame was hit, in which case allow it through, as it could
|
| +// have come through the api.
|
| +static bool TokensMatchForCompileString(Isolate* isolate) {
|
| + MaybeHandle<JSFunction> callee;
|
| + bool exit_handled = true;
|
| + bool tokens_match = 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<Context> context(callee.ToHandleChecked()->context());
|
| + if (!fun->context()->HasSameSecurityTokenAs(*context)) {
|
| + tokens_match = false;
|
| + done = true;
|
| + continue;
|
| + }
|
| + // Skip bound functions in correct origin.
|
| + if (fun->shared()->bound()) {
|
| + exit_handled = true;
|
| + continue;
|
| + }
|
| + done = true;
|
| + }
|
| + }
|
| + return !exit_handled || tokens_match;
|
| +}
|
| +
|
| +
|
| RUNTIME_FUNCTION(Runtime_CompileString) {
|
| HandleScope scope(isolate);
|
| ASSERT(args.length() == 2);
|
| @@ -9791,6 +9844,11 @@ RUNTIME_FUNCTION(Runtime_CompileString) {
|
| // Extract native context.
|
| Handle<Context> context(isolate->context()->native_context());
|
|
|
| + // Filter cross security context calls.
|
| + if (!TokensMatchForCompileString(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() &&
|
|
|