Chromium Code Reviews| Index: src/runtime.cc |
| diff --git a/src/runtime.cc b/src/runtime.cc |
| index 686c3f550fb55c592d4cd5173b1ceffd9ad820d9..631c576dfeba4a5e09252be9896d27a35e3a4de5 100644 |
| --- a/src/runtime.cc |
| +++ b/src/runtime.cc |
| @@ -9759,6 +9759,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 = handle(callee.ToHandleChecked()->context()); |
|
Toon Verwaest
2014/06/11 12:28:44
remove " = handle"
|
| + 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); |
| @@ -9768,6 +9821,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() && |