Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(99)

Unified Diff: src/builtins.cc

Issue 2034083002: Don't compile functions in a context the caller doesn't have access to (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « include/v8.h ('k') | src/d8.h » ('j') | src/d8.cc » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/builtins.cc
diff --git a/src/builtins.cc b/src/builtins.cc
index 07817fe8c0899444decbddebeb73acd90d6a5e6c..6e604ed5e9a9f13bb6c6db7ac932005a35b4b30c 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -4102,8 +4102,48 @@ void Builtins::Generate_DatePrototypeGetUTCSeconds(MacroAssembler* masm) {
namespace {
+// Walk up the stack expecting:
+// - ExitFrame
+// - 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 HasAccessToContextForCreateDynamicFunction(
+ Isolate* isolate, Handle<JSObject> target_global_proxy) {
+ bool exit_handled = true;
+ bool has_access = true;
+ bool done = false;
+ StackFrameIterator it(isolate);
+ // Skip exit frame that corresponds to the builtin call.
+ it.Advance();
+ for (; !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();
+ if (!isolate->MayAccess(handle(fun->context()), target_global_proxy)) {
+ has_access = false;
+ done = true;
+ continue;
+ }
+ done = true;
+ }
+ }
+ return !exit_handled || has_access;
+}
+
// ES6 section 19.2.1.1.1 CreateDynamicFunction
-MaybeHandle<JSFunction> CreateDynamicFunction(
+MaybeHandle<Object> CreateDynamicFunction(
Isolate* isolate,
BuiltinArguments<BuiltinExtraArguments::kTargetAndNewTarget> args,
const char* token) {
@@ -4111,6 +4151,15 @@ MaybeHandle<JSFunction> CreateDynamicFunction(
DCHECK_LE(1, args.length());
int const argc = args.length() - 1;
+ Handle<JSFunction> target = args.target<JSFunction>();
+ Handle<JSObject> target_global_proxy(target->global_proxy(), isolate);
+
+ if (!HasAccessToContextForCreateDynamicFunction(isolate,
+ target_global_proxy)) {
+ isolate->CountUsage(v8::Isolate::kFunctionConstructorReturnedUndefined);
+ return isolate->factory()->undefined_value();
+ }
+
// Build the source string.
Handle<String> source;
{
@@ -4125,7 +4174,7 @@ MaybeHandle<JSFunction> CreateDynamicFunction(
Handle<String> param;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, param, Object::ToString(isolate, args.at<Object>(i)),
- JSFunction);
+ Object);
param = String::Flatten(param);
builder.AppendString(param);
// If the formal parameters string include ) - an illegal
@@ -4150,37 +4199,35 @@ MaybeHandle<JSFunction> CreateDynamicFunction(
Handle<String> body;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, body, Object::ToString(isolate, args.at<Object>(argc)),
- JSFunction);
+ Object);
builder.AppendString(body);
}
builder.AppendCString("\n})");
- ASSIGN_RETURN_ON_EXCEPTION(isolate, source, builder.Finish(), JSFunction);
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, source, builder.Finish(), Object);
// The SyntaxError must be thrown after all the (observable) ToString
// conversions are done.
if (parenthesis_in_arg_string) {
THROW_NEW_ERROR(isolate,
NewSyntaxError(MessageTemplate::kParenthesisInArgString),
- JSFunction);
+ Object);
}
}
// Compile the string in the constructor and not a helper so that errors to
// come from here.
- Handle<JSFunction> target = args.target<JSFunction>();
- Handle<JSObject> target_global_proxy(target->global_proxy(), isolate);
Handle<JSFunction> function;
{
ASSIGN_RETURN_ON_EXCEPTION(
isolate, function,
CompileString(handle(target->native_context(), isolate), source,
ONLY_SINGLE_FUNCTION_LITERAL),
- JSFunction);
+ Object);
Handle<Object> result;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, result,
Execution::Call(isolate, function, target_global_proxy, 0, nullptr),
- JSFunction);
+ Object);
function = Handle<JSFunction>::cast(result);
function->shared()->set_name_should_print_as_anonymous(true);
}
@@ -4199,7 +4246,7 @@ MaybeHandle<JSFunction> CreateDynamicFunction(
Handle<Map> initial_map;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, initial_map,
- JSFunction::GetDerivedMap(isolate, target, new_target), JSFunction);
+ JSFunction::GetDerivedMap(isolate, target, new_target), Object);
Handle<SharedFunctionInfo> shared_info(function->shared(), isolate);
Handle<Map> map = Map::AsLanguageMode(
@@ -4218,7 +4265,7 @@ MaybeHandle<JSFunction> CreateDynamicFunction(
// ES6 section 19.2.1.1 Function ( p1, p2, ... , pn, body )
BUILTIN(FunctionConstructor) {
HandleScope scope(isolate);
- Handle<JSFunction> result;
+ Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result, CreateDynamicFunction(isolate, args, "function"));
return *result;
« no previous file with comments | « include/v8.h ('k') | src/d8.h » ('j') | src/d8.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698