Commit ea30c011 authored by Yuki Shiino's avatar Yuki Shiino Committed by Commit Bot

v8binding: Check the "script forbidden" status in IDL callbacks.

Checks whether script execution is allowed or not in IDL callbacks.
See the bug for details.

Bug: 964928
Change-Id: Icfe11d7cd029a52794cdd4525d04288735dc3b29
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1624985
Commit-Queue: Yuki Shiino <yukishiino@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarHitoshi Yoshida <peria@chromium.org>
Cr-Commit-Position: refs/heads/master@{#662548}
parent 033c9a28
......@@ -56,6 +56,11 @@
v8::Context::BackupIncumbentScope backup_incumbent_scope(
IncumbentScriptState()->GetContext());
if (UNLIKELY(ScriptForbiddenScope::IsScriptForbidden())) {
ScriptForbiddenScope::ThrowScriptForbiddenException(GetIsolate());
return v8::Nothing<{{return_cpp_type}}>();
}
{% if invoke_or_construct == 'construct' %}
// step 3. If ! IsConstructor(F) is false, throw a TypeError exception.
//
......
......@@ -61,6 +61,11 @@ v8::Maybe<ScriptValue> V8AnyCallbackFunctionOptionalAnyArg::Invoke(bindings::V8V
v8::Context::BackupIncumbentScope backup_incumbent_scope(
IncumbentScriptState()->GetContext());
if (UNLIKELY(ScriptForbiddenScope::IsScriptForbidden())) {
ScriptForbiddenScope::ThrowScriptForbiddenException(GetIsolate());
return v8::Nothing<ScriptValue>();
}
v8::Local<v8::Function> function;
// callback function's invoke:
// step 4. If ! IsCallable(F) is false:
......@@ -154,6 +159,11 @@ v8::Maybe<ScriptValue> V8AnyCallbackFunctionOptionalAnyArg::Construct(ScriptValu
v8::Context::BackupIncumbentScope backup_incumbent_scope(
IncumbentScriptState()->GetContext());
if (UNLIKELY(ScriptForbiddenScope::IsScriptForbidden())) {
ScriptForbiddenScope::ThrowScriptForbiddenException(GetIsolate());
return v8::Nothing<ScriptValue>();
}
// step 3. If ! IsConstructor(F) is false, throw a TypeError exception.
//
// Note that step 7. and 8. are side effect free (except for a very rare
......
......@@ -61,6 +61,11 @@ v8::Maybe<ScriptValue> V8AnyCallbackFunctionVariadicAnyArgs::Invoke(bindings::V8
v8::Context::BackupIncumbentScope backup_incumbent_scope(
IncumbentScriptState()->GetContext());
if (UNLIKELY(ScriptForbiddenScope::IsScriptForbidden())) {
ScriptForbiddenScope::ThrowScriptForbiddenException(GetIsolate());
return v8::Nothing<ScriptValue>();
}
v8::Local<v8::Function> function;
// callback function's invoke:
// step 4. If ! IsCallable(F) is false:
......@@ -161,6 +166,11 @@ v8::Maybe<ScriptValue> V8AnyCallbackFunctionVariadicAnyArgs::Construct(const Vec
v8::Context::BackupIncumbentScope backup_incumbent_scope(
IncumbentScriptState()->GetContext());
if (UNLIKELY(ScriptForbiddenScope::IsScriptForbidden())) {
ScriptForbiddenScope::ThrowScriptForbiddenException(GetIsolate());
return v8::Nothing<ScriptValue>();
}
// step 3. If ! IsConstructor(F) is false, throw a TypeError exception.
//
// Note that step 7. and 8. are side effect free (except for a very rare
......
......@@ -61,6 +61,11 @@ v8::Maybe<void> V8ForEachIteratorCallback::Invoke(bindings::V8ValueOrScriptWrapp
v8::Context::BackupIncumbentScope backup_incumbent_scope(
IncumbentScriptState()->GetContext());
if (UNLIKELY(ScriptForbiddenScope::IsScriptForbidden())) {
ScriptForbiddenScope::ThrowScriptForbiddenException(GetIsolate());
return v8::Nothing<void>();
}
v8::Local<v8::Function> function;
// callback function's invoke:
// step 4. If ! IsCallable(F) is false:
......
......@@ -61,6 +61,11 @@ v8::Maybe<int32_t> V8LongCallbackFunction::Invoke(bindings::V8ValueOrScriptWrapp
v8::Context::BackupIncumbentScope backup_incumbent_scope(
IncumbentScriptState()->GetContext());
if (UNLIKELY(ScriptForbiddenScope::IsScriptForbidden())) {
ScriptForbiddenScope::ThrowScriptForbiddenException(GetIsolate());
return v8::Nothing<int32_t>();
}
v8::Local<v8::Function> function;
// callback function's invoke:
// step 4. If ! IsCallable(F) is false:
......
......@@ -61,6 +61,11 @@ v8::Maybe<Vector<String>> V8StringSequenceCallbackFunctionLongSequenceArg::Invok
v8::Context::BackupIncumbentScope backup_incumbent_scope(
IncumbentScriptState()->GetContext());
if (UNLIKELY(ScriptForbiddenScope::IsScriptForbidden())) {
ScriptForbiddenScope::ThrowScriptForbiddenException(GetIsolate());
return v8::Nothing<Vector<String>>();
}
v8::Local<v8::Function> function;
// callback function's invoke:
// step 4. If ! IsCallable(F) is false:
......
......@@ -59,6 +59,11 @@ v8::Maybe<void> V8TestCallbackInterface::voidMethod(bindings::V8ValueOrScriptWra
v8::Context::BackupIncumbentScope backup_incumbent_scope(
IncumbentScriptState()->GetContext());
if (UNLIKELY(ScriptForbiddenScope::IsScriptForbidden())) {
ScriptForbiddenScope::ThrowScriptForbiddenException(GetIsolate());
return v8::Nothing<void>();
}
v8::Local<v8::Function> function;
if (IsCallbackObjectCallable()) {
// step 9.1. If value's interface is a single operation callback interface
......@@ -162,6 +167,11 @@ v8::Maybe<bool> V8TestCallbackInterface::booleanMethod(bindings::V8ValueOrScript
v8::Context::BackupIncumbentScope backup_incumbent_scope(
IncumbentScriptState()->GetContext());
if (UNLIKELY(ScriptForbiddenScope::IsScriptForbidden())) {
ScriptForbiddenScope::ThrowScriptForbiddenException(GetIsolate());
return v8::Nothing<bool>();
}
v8::Local<v8::Function> function;
if (IsCallbackObjectCallable()) {
// step 9.1. If value's interface is a single operation callback interface
......@@ -277,6 +287,11 @@ v8::Maybe<void> V8TestCallbackInterface::voidMethodBooleanArg(bindings::V8ValueO
v8::Context::BackupIncumbentScope backup_incumbent_scope(
IncumbentScriptState()->GetContext());
if (UNLIKELY(ScriptForbiddenScope::IsScriptForbidden())) {
ScriptForbiddenScope::ThrowScriptForbiddenException(GetIsolate());
return v8::Nothing<void>();
}
v8::Local<v8::Function> function;
if (IsCallbackObjectCallable()) {
// step 9.1. If value's interface is a single operation callback interface
......@@ -385,6 +400,11 @@ v8::Maybe<void> V8TestCallbackInterface::voidMethodSequenceArg(bindings::V8Value
v8::Context::BackupIncumbentScope backup_incumbent_scope(
IncumbentScriptState()->GetContext());
if (UNLIKELY(ScriptForbiddenScope::IsScriptForbidden())) {
ScriptForbiddenScope::ThrowScriptForbiddenException(GetIsolate());
return v8::Nothing<void>();
}
v8::Local<v8::Function> function;
if (IsCallbackObjectCallable()) {
// step 9.1. If value's interface is a single operation callback interface
......@@ -493,6 +513,11 @@ v8::Maybe<void> V8TestCallbackInterface::voidMethodFloatArg(bindings::V8ValueOrS
v8::Context::BackupIncumbentScope backup_incumbent_scope(
IncumbentScriptState()->GetContext());
if (UNLIKELY(ScriptForbiddenScope::IsScriptForbidden())) {
ScriptForbiddenScope::ThrowScriptForbiddenException(GetIsolate());
return v8::Nothing<void>();
}
v8::Local<v8::Function> function;
if (IsCallbackObjectCallable()) {
// step 9.1. If value's interface is a single operation callback interface
......@@ -601,6 +626,11 @@ v8::Maybe<void> V8TestCallbackInterface::voidMethodTestInterfaceEmptyArg(binding
v8::Context::BackupIncumbentScope backup_incumbent_scope(
IncumbentScriptState()->GetContext());
if (UNLIKELY(ScriptForbiddenScope::IsScriptForbidden())) {
ScriptForbiddenScope::ThrowScriptForbiddenException(GetIsolate());
return v8::Nothing<void>();
}
v8::Local<v8::Function> function;
if (IsCallbackObjectCallable()) {
// step 9.1. If value's interface is a single operation callback interface
......@@ -709,6 +739,11 @@ v8::Maybe<void> V8TestCallbackInterface::voidMethodTestInterfaceEmptyStringArg(b
v8::Context::BackupIncumbentScope backup_incumbent_scope(
IncumbentScriptState()->GetContext());
if (UNLIKELY(ScriptForbiddenScope::IsScriptForbidden())) {
ScriptForbiddenScope::ThrowScriptForbiddenException(GetIsolate());
return v8::Nothing<void>();
}
v8::Local<v8::Function> function;
if (IsCallbackObjectCallable()) {
// step 9.1. If value's interface is a single operation callback interface
......@@ -818,6 +853,11 @@ v8::Maybe<void> V8TestCallbackInterface::callbackWithThisValueVoidMethodStringAr
v8::Context::BackupIncumbentScope backup_incumbent_scope(
IncumbentScriptState()->GetContext());
if (UNLIKELY(ScriptForbiddenScope::IsScriptForbidden())) {
ScriptForbiddenScope::ThrowScriptForbiddenException(GetIsolate());
return v8::Nothing<void>();
}
v8::Local<v8::Function> function;
if (IsCallbackObjectCallable()) {
// step 9.1. If value's interface is a single operation callback interface
......@@ -926,6 +966,11 @@ v8::Maybe<void> V8TestCallbackInterface::customVoidMethodTestInterfaceEmptyArg(b
v8::Context::BackupIncumbentScope backup_incumbent_scope(
IncumbentScriptState()->GetContext());
if (UNLIKELY(ScriptForbiddenScope::IsScriptForbidden())) {
ScriptForbiddenScope::ThrowScriptForbiddenException(GetIsolate());
return v8::Nothing<void>();
}
v8::Local<v8::Function> function;
if (IsCallbackObjectCallable()) {
// step 9.1. If value's interface is a single operation callback interface
......
......@@ -117,6 +117,11 @@ v8::Maybe<uint16_t> V8TestLegacyCallbackInterface::acceptNode(bindings::V8ValueO
v8::Context::BackupIncumbentScope backup_incumbent_scope(
IncumbentScriptState()->GetContext());
if (UNLIKELY(ScriptForbiddenScope::IsScriptForbidden())) {
ScriptForbiddenScope::ThrowScriptForbiddenException(GetIsolate());
return v8::Nothing<uint16_t>();
}
v8::Local<v8::Function> function;
if (IsCallbackObjectCallable()) {
// step 9.1. If value's interface is a single operation callback interface
......
......@@ -60,6 +60,11 @@ v8::Maybe<bool> V8TreatNonObjectAsNullBooleanFunction::Invoke(bindings::V8ValueO
v8::Context::BackupIncumbentScope backup_incumbent_scope(
IncumbentScriptState()->GetContext());
if (UNLIKELY(ScriptForbiddenScope::IsScriptForbidden())) {
ScriptForbiddenScope::ThrowScriptForbiddenException(GetIsolate());
return v8::Nothing<bool>();
}
v8::Local<v8::Function> function;
// callback function's invoke:
// step 4. If ! IsCallable(F) is false:
......
......@@ -60,6 +60,11 @@ v8::Maybe<void> V8TreatNonObjectAsNullVoidFunction::Invoke(bindings::V8ValueOrSc
v8::Context::BackupIncumbentScope backup_incumbent_scope(
IncumbentScriptState()->GetContext());
if (UNLIKELY(ScriptForbiddenScope::IsScriptForbidden())) {
ScriptForbiddenScope::ThrowScriptForbiddenException(GetIsolate());
return v8::Nothing<void>();
}
v8::Local<v8::Function> function;
// callback function's invoke:
// step 4. If ! IsCallable(F) is false:
......
......@@ -60,6 +60,11 @@ v8::Maybe<void> V8VoidCallbackFunction::Invoke(bindings::V8ValueOrScriptWrappabl
v8::Context::BackupIncumbentScope backup_incumbent_scope(
IncumbentScriptState()->GetContext());
if (UNLIKELY(ScriptForbiddenScope::IsScriptForbidden())) {
ScriptForbiddenScope::ThrowScriptForbiddenException(GetIsolate());
return v8::Nothing<void>();
}
v8::Local<v8::Function> function;
// callback function's invoke:
// step 4. If ! IsCallable(F) is false:
......
......@@ -61,6 +61,11 @@ v8::Maybe<void> V8VoidCallbackFunctionDictionaryArg::Invoke(bindings::V8ValueOrS
v8::Context::BackupIncumbentScope backup_incumbent_scope(
IncumbentScriptState()->GetContext());
if (UNLIKELY(ScriptForbiddenScope::IsScriptForbidden())) {
ScriptForbiddenScope::ThrowScriptForbiddenException(GetIsolate());
return v8::Nothing<void>();
}
v8::Local<v8::Function> function;
// callback function's invoke:
// step 4. If ! IsCallable(F) is false:
......
......@@ -61,6 +61,11 @@ v8::Maybe<void> V8VoidCallbackFunctionEnumArg::Invoke(bindings::V8ValueOrScriptW
v8::Context::BackupIncumbentScope backup_incumbent_scope(
IncumbentScriptState()->GetContext());
if (UNLIKELY(ScriptForbiddenScope::IsScriptForbidden())) {
ScriptForbiddenScope::ThrowScriptForbiddenException(GetIsolate());
return v8::Nothing<void>();
}
v8::Local<v8::Function> function;
// callback function's invoke:
// step 4. If ! IsCallable(F) is false:
......
......@@ -61,6 +61,11 @@ v8::Maybe<void> V8VoidCallbackFunctionInterfaceArg::Invoke(bindings::V8ValueOrSc
v8::Context::BackupIncumbentScope backup_incumbent_scope(
IncumbentScriptState()->GetContext());
if (UNLIKELY(ScriptForbiddenScope::IsScriptForbidden())) {
ScriptForbiddenScope::ThrowScriptForbiddenException(GetIsolate());
return v8::Nothing<void>();
}
v8::Local<v8::Function> function;
// callback function's invoke:
// step 4. If ! IsCallable(F) is false:
......
......@@ -62,6 +62,11 @@ v8::Maybe<void> V8VoidCallbackFunctionTestInterfaceSequenceArg::Invoke(bindings:
v8::Context::BackupIncumbentScope backup_incumbent_scope(
IncumbentScriptState()->GetContext());
if (UNLIKELY(ScriptForbiddenScope::IsScriptForbidden())) {
ScriptForbiddenScope::ThrowScriptForbiddenException(GetIsolate());
return v8::Nothing<void>();
}
v8::Local<v8::Function> function;
// callback function's invoke:
// step 4. If ! IsCallable(F) is false:
......
......@@ -61,6 +61,11 @@ v8::Maybe<void> V8VoidCallbackFunctionTypedef::Invoke(bindings::V8ValueOrScriptW
v8::Context::BackupIncumbentScope backup_incumbent_scope(
IncumbentScriptState()->GetContext());
if (UNLIKELY(ScriptForbiddenScope::IsScriptForbidden())) {
ScriptForbiddenScope::ThrowScriptForbiddenException(GetIsolate());
return v8::Nothing<void>();
}
v8::Local<v8::Function> function;
// callback function's invoke:
// step 4. If ! IsCallable(F) is false:
......
......@@ -60,6 +60,11 @@ v8::Maybe<void> V8VoidCallbackFunctionModules::Invoke(bindings::V8ValueOrScriptW
v8::Context::BackupIncumbentScope backup_incumbent_scope(
IncumbentScriptState()->GetContext());
if (UNLIKELY(ScriptForbiddenScope::IsScriptForbidden())) {
ScriptForbiddenScope::ThrowScriptForbiddenException(GetIsolate());
return v8::Nothing<void>();
}
v8::Local<v8::Function> function;
// callback function's invoke:
// step 4. If ! IsCallable(F) is false:
......
......@@ -7,6 +7,7 @@
#include "base/auto_reset.h"
#include "base/macros.h"
#include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "third_party/blink/renderer/platform/wtf/stack_util.h"
......@@ -41,7 +42,11 @@ class PLATFORM_EXPORT ScriptForbiddenScope final {
return GetMutableCounter() > 0;
}
// DO NOT USE THESE FUNCTIONS FROM OUTSIDE OF THIS CLASS.
static void ThrowScriptForbiddenException(v8::Isolate* isolate) {
V8ThrowException::ThrowError(isolate, "Script execution is forbidden.");
}
private:
static void Enter() {
if (LIKELY(!WTF::MayNotBeMainThread())) {
++g_main_thread_counter_;
......@@ -58,9 +63,11 @@ class PLATFORM_EXPORT ScriptForbiddenScope final {
}
}
private:
static unsigned& GetMutableCounter();
static unsigned g_main_thread_counter_;
// V8GCController is exceptionally allowed to call Enter/Exit.
friend class V8GCController;
};
} // namespace blink
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment