[wasm] Make exception creation non-observable by JS.
This fixes exception creation (by the WebAssembly throw operation) so that it is not observable by JavaScript. Internal properties are now stored with symbol names instead of string names, which also prevents them from being accessed or monkey-patched directly by JavaScript. R=clemensh@chromium.org TEST=mjsunit/regress/wasm/regress-8094 BUG=v8:8094 Change-Id: I33cb27f4373114cd4db28d9aef23560093e55242 Reviewed-on: https://chromium-review.googlesource.com/1203951 Commit-Queue: Michael Starzinger <mstarzinger@chromium.org> Reviewed-by: Clemens Hammacher <clemensh@chromium.org> Cr-Commit-Position: refs/heads/master@{#55602}
This commit is contained in:
parent
175f2a6a6c
commit
e8d79f070c
@ -273,6 +273,8 @@
|
||||
V(sealed_symbol) \
|
||||
V(stack_trace_symbol) \
|
||||
V(strict_function_transition_symbol) \
|
||||
V(wasm_exception_runtime_id_symbol) \
|
||||
V(wasm_exception_values_symbol) \
|
||||
V(uninitialized_symbol)
|
||||
|
||||
#define PUBLIC_SYMBOL_LIST(V) \
|
||||
|
@ -835,12 +835,32 @@ RUNTIME_FUNCTION(Runtime_IsWasmTrapHandlerEnabled) {
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_GetWasmRecoveredTrapCount) {
|
||||
HandleScope shs(isolate);
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(0, args.length());
|
||||
size_t trap_count = trap_handler::GetRecoveredTrapCount();
|
||||
return *isolate->factory()->NewNumberFromSize(trap_count);
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_GetWasmExceptionId) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(1, args.length());
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, exception, 0);
|
||||
RETURN_RESULT_OR_FAILURE(
|
||||
isolate, JSReceiver::GetProperty(
|
||||
isolate, exception,
|
||||
isolate->factory()->wasm_exception_runtime_id_symbol()));
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_GetWasmExceptionValues) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(1, args.length());
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, exception, 0);
|
||||
RETURN_RESULT_OR_FAILURE(
|
||||
isolate, JSReceiver::GetProperty(
|
||||
isolate, exception,
|
||||
isolate->factory()->wasm_exception_values_symbol()));
|
||||
}
|
||||
|
||||
namespace {
|
||||
bool EnableWasmThreads(v8::Local<v8::Context> context) { return true; }
|
||||
|
||||
|
@ -123,18 +123,18 @@ RUNTIME_FUNCTION(Runtime_WasmThrowCreate) {
|
||||
static_cast<MessageTemplate::Template>(
|
||||
MessageTemplate::kWasmExceptionError));
|
||||
CONVERT_ARG_HANDLE_CHECKED(Smi, id, 0);
|
||||
CHECK(!JSReceiver::SetProperty(isolate, exception,
|
||||
isolate->factory()->InternalizeUtf8String(
|
||||
wasm::WasmException::kRuntimeIdStr),
|
||||
id, LanguageMode::kStrict)
|
||||
CHECK(!JSReceiver::SetProperty(
|
||||
isolate, exception,
|
||||
isolate->factory()->wasm_exception_runtime_id_symbol(), id,
|
||||
LanguageMode::kStrict)
|
||||
.is_null());
|
||||
CONVERT_SMI_ARG_CHECKED(size, 1);
|
||||
Handle<JSTypedArray> values =
|
||||
isolate->factory()->NewJSTypedArray(ElementsKind::UINT16_ELEMENTS, size);
|
||||
CHECK(!JSReceiver::SetProperty(isolate, exception,
|
||||
isolate->factory()->InternalizeUtf8String(
|
||||
wasm::WasmException::kRuntimeValuesStr),
|
||||
values, LanguageMode::kStrict)
|
||||
CHECK(!JSReceiver::SetProperty(
|
||||
isolate, exception,
|
||||
isolate->factory()->wasm_exception_values_symbol(), values,
|
||||
LanguageMode::kStrict)
|
||||
.is_null());
|
||||
return *exception;
|
||||
}
|
||||
@ -160,9 +160,9 @@ RUNTIME_FUNCTION(Runtime_WasmGetExceptionRuntimeId) {
|
||||
if (!except_obj.is_null() && except_obj->IsJSReceiver()) {
|
||||
Handle<JSReceiver> exception(JSReceiver::cast(*except_obj), isolate);
|
||||
Handle<Object> tag;
|
||||
if (JSReceiver::GetProperty(isolate, exception,
|
||||
isolate->factory()->InternalizeUtf8String(
|
||||
wasm::WasmException::kRuntimeIdStr))
|
||||
if (JSReceiver::GetProperty(
|
||||
isolate, exception,
|
||||
isolate->factory()->wasm_exception_runtime_id_symbol())
|
||||
.ToHandle(&tag)) {
|
||||
if (tag->IsSmi()) {
|
||||
return *tag;
|
||||
@ -182,9 +182,9 @@ RUNTIME_FUNCTION(Runtime_WasmExceptionGetElement) {
|
||||
if (!except_obj.is_null() && except_obj->IsJSReceiver()) {
|
||||
Handle<JSReceiver> exception(JSReceiver::cast(*except_obj), isolate);
|
||||
Handle<Object> values_obj;
|
||||
if (JSReceiver::GetProperty(isolate, exception,
|
||||
isolate->factory()->InternalizeUtf8String(
|
||||
wasm::WasmException::kRuntimeValuesStr))
|
||||
if (JSReceiver::GetProperty(
|
||||
isolate, exception,
|
||||
isolate->factory()->wasm_exception_values_symbol())
|
||||
.ToHandle(&values_obj)) {
|
||||
if (values_obj->IsJSTypedArray()) {
|
||||
Handle<JSTypedArray> values = Handle<JSTypedArray>::cast(values_obj);
|
||||
@ -210,9 +210,9 @@ RUNTIME_FUNCTION(Runtime_WasmExceptionSetElement) {
|
||||
if (!except_obj.is_null() && except_obj->IsJSReceiver()) {
|
||||
Handle<JSReceiver> exception(JSReceiver::cast(*except_obj), isolate);
|
||||
Handle<Object> values_obj;
|
||||
if (JSReceiver::GetProperty(isolate, exception,
|
||||
isolate->factory()->InternalizeUtf8String(
|
||||
wasm::WasmException::kRuntimeValuesStr))
|
||||
if (JSReceiver::GetProperty(
|
||||
isolate, exception,
|
||||
isolate->factory()->wasm_exception_values_symbol())
|
||||
.ToHandle(&values_obj)) {
|
||||
if (values_obj->IsJSTypedArray()) {
|
||||
Handle<JSTypedArray> values = Handle<JSTypedArray>::cast(values_obj);
|
||||
|
@ -486,6 +486,8 @@ namespace internal {
|
||||
F(GetDeoptCount, 1, 1) \
|
||||
F(GetOptimizationStatus, -1, 1) \
|
||||
F(GetUndetectable, 0, 1) \
|
||||
F(GetWasmExceptionId, 1, 1) \
|
||||
F(GetWasmExceptionValues, 1, 1) \
|
||||
F(GetWasmRecoveredTrapCount, 0, 1) \
|
||||
F(GlobalPrint, 1, 1) \
|
||||
F(HasDictionaryElements, 1, 1) \
|
||||
|
@ -30,12 +30,6 @@ namespace wasm {
|
||||
// static
|
||||
const WasmExceptionSig WasmException::empty_sig_(0, 0, nullptr);
|
||||
|
||||
// static
|
||||
constexpr const char* WasmException::kRuntimeIdStr;
|
||||
|
||||
// static
|
||||
constexpr const char* WasmException::kRuntimeValuesStr;
|
||||
|
||||
WireBytesRef WasmModule::LookupFunctionName(const ModuleWireBytes& wire_bytes,
|
||||
uint32_t function_index) const {
|
||||
if (!function_names) {
|
||||
|
@ -81,10 +81,6 @@ struct WasmException {
|
||||
|
||||
const WasmExceptionSig* sig; // type signature of the exception.
|
||||
|
||||
// Used to hold data on runtime exceptions.
|
||||
static constexpr const char* kRuntimeIdStr = "WasmExceptionRuntimeId";
|
||||
static constexpr const char* kRuntimeValuesStr = "WasmExceptionValues";
|
||||
|
||||
private:
|
||||
static const WasmExceptionSig empty_sig_;
|
||||
};
|
||||
|
30
test/mjsunit/regress/wasm/regress-8094.js
Normal file
30
test/mjsunit/regress/wasm/regress-8094.js
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright 2018 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --expose-wasm --experimental-wasm-eh
|
||||
|
||||
load("test/mjsunit/wasm/wasm-constants.js");
|
||||
load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
|
||||
// Instantiate a throwing module.
|
||||
var builder = new WasmModuleBuilder();
|
||||
builder.addException(kSig_v_v);
|
||||
builder.addFunction("propel", kSig_v_v)
|
||||
.addBody([kExprThrow, 0])
|
||||
.exportFunc();
|
||||
var instance = builder.instantiate();
|
||||
|
||||
// Catch the exception.
|
||||
var exception;
|
||||
try {
|
||||
instance.exports.propel();
|
||||
} catch (e) {
|
||||
exception = e;
|
||||
}
|
||||
|
||||
// Check that the exception is an instance of the correct error function and
|
||||
// that no extraneous properties exist. Setting such properties could be
|
||||
// observable by JavaScript and could break compatibility.
|
||||
assertInstanceof(exception, WebAssembly.RuntimeError);
|
||||
assertArrayEquals(["stack", "message"], Object.getOwnPropertyNames(exception));
|
@ -2,11 +2,31 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --expose-wasm --experimental-wasm-eh
|
||||
// Flags: --expose-wasm --experimental-wasm-eh --allow-natives-syntax
|
||||
|
||||
load("test/mjsunit/wasm/wasm-constants.js");
|
||||
load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
|
||||
function assertWasmThrows(runtime_id, values, code) {
|
||||
try {
|
||||
if (typeof code === 'function') {
|
||||
code();
|
||||
} else {
|
||||
eval(code);
|
||||
}
|
||||
} catch (e) {
|
||||
assertInstanceof(e, WebAssembly.RuntimeError);
|
||||
var e_runtime_id = %GetWasmExceptionId(e);
|
||||
assertTrue(Number.isInteger(e_runtime_id));
|
||||
assertEquals(e_runtime_id, runtime_id);
|
||||
var e_values = %GetWasmExceptionValues(e);
|
||||
assertArrayEquals(values, e_values);
|
||||
return; // Success.
|
||||
}
|
||||
throw new MjsUnitAssertionError('Did not throw expected <' + runtime_id +
|
||||
'> with values: ' + values);
|
||||
}
|
||||
|
||||
// First we just test that "except_ref" local variables are allowed.
|
||||
(function TestLocalExceptRef() {
|
||||
let builder = new WasmModuleBuilder();
|
||||
|
@ -409,30 +409,6 @@ function assertTraps(trap, code) {
|
||||
throw new MjsUnitAssertionError('Did not trap, expected: ' + kTrapMsgs[trap]);
|
||||
}
|
||||
|
||||
function assertWasmThrows(runtime_id, values, code) {
|
||||
try {
|
||||
if (typeof code === 'function') {
|
||||
code();
|
||||
} else {
|
||||
eval(code);
|
||||
}
|
||||
} catch (e) {
|
||||
assertTrue(e instanceof WebAssembly.RuntimeError);
|
||||
var e_runtime_id = e['WasmExceptionRuntimeId'];
|
||||
assertEquals(e_runtime_id, runtime_id);
|
||||
assertTrue(Number.isInteger(e_runtime_id));
|
||||
var e_values = e['WasmExceptionValues'];
|
||||
assertEquals(values.length, e_values.length);
|
||||
for (i = 0; i < values.length; ++i) {
|
||||
assertEquals(values[i], e_values[i]);
|
||||
}
|
||||
// Success.
|
||||
return;
|
||||
}
|
||||
throw new MjsUnitAssertionError('Did not throw expected <' + runtime_id +
|
||||
'> with values: ' + values);
|
||||
}
|
||||
|
||||
function wasmI32Const(val) {
|
||||
let bytes = [kExprI32Const];
|
||||
for (let i = 0; i < 4; ++i) {
|
||||
|
@ -285,32 +285,32 @@ KNOWN_MAPS = {
|
||||
("RO_SPACE", 0x04811): (173, "ArrayBoilerplateDescriptionMap"),
|
||||
("RO_SPACE", 0x04b01): (161, "InterceptorInfoMap"),
|
||||
("RO_SPACE", 0x04bf9): (169, "ScriptMap"),
|
||||
("RO_SPACE", 0x09a81): (154, "AccessorInfoMap"),
|
||||
("RO_SPACE", 0x09ad1): (153, "AccessCheckInfoMap"),
|
||||
("RO_SPACE", 0x09b21): (155, "AccessorPairMap"),
|
||||
("RO_SPACE", 0x09b71): (156, "AliasedArgumentsEntryMap"),
|
||||
("RO_SPACE", 0x09bc1): (157, "AllocationMementoMap"),
|
||||
("RO_SPACE", 0x09c11): (158, "AsyncGeneratorRequestMap"),
|
||||
("RO_SPACE", 0x09c61): (159, "DebugInfoMap"),
|
||||
("RO_SPACE", 0x09cb1): (160, "FunctionTemplateInfoMap"),
|
||||
("RO_SPACE", 0x09d01): (162, "InterpreterDataMap"),
|
||||
("RO_SPACE", 0x09d51): (163, "ModuleInfoEntryMap"),
|
||||
("RO_SPACE", 0x09da1): (164, "ModuleMap"),
|
||||
("RO_SPACE", 0x09df1): (165, "ObjectTemplateInfoMap"),
|
||||
("RO_SPACE", 0x09e41): (166, "PromiseCapabilityMap"),
|
||||
("RO_SPACE", 0x09e91): (167, "PromiseReactionMap"),
|
||||
("RO_SPACE", 0x09ee1): (168, "PrototypeInfoMap"),
|
||||
("RO_SPACE", 0x09f31): (170, "StackFrameInfoMap"),
|
||||
("RO_SPACE", 0x09f81): (172, "Tuple3Map"),
|
||||
("RO_SPACE", 0x09fd1): (174, "WasmDebugInfoMap"),
|
||||
("RO_SPACE", 0x0a021): (175, "WasmExportedFunctionDataMap"),
|
||||
("RO_SPACE", 0x0a071): (176, "CallableTaskMap"),
|
||||
("RO_SPACE", 0x0a0c1): (177, "CallbackTaskMap"),
|
||||
("RO_SPACE", 0x0a111): (178, "PromiseFulfillReactionJobTaskMap"),
|
||||
("RO_SPACE", 0x0a161): (179, "PromiseRejectReactionJobTaskMap"),
|
||||
("RO_SPACE", 0x0a1b1): (180, "PromiseResolveThenableJobTaskMap"),
|
||||
("RO_SPACE", 0x0a201): (181, "AllocationSiteMap"),
|
||||
("RO_SPACE", 0x0a251): (181, "AllocationSiteMap"),
|
||||
("RO_SPACE", 0x09ac1): (154, "AccessorInfoMap"),
|
||||
("RO_SPACE", 0x09b11): (153, "AccessCheckInfoMap"),
|
||||
("RO_SPACE", 0x09b61): (155, "AccessorPairMap"),
|
||||
("RO_SPACE", 0x09bb1): (156, "AliasedArgumentsEntryMap"),
|
||||
("RO_SPACE", 0x09c01): (157, "AllocationMementoMap"),
|
||||
("RO_SPACE", 0x09c51): (158, "AsyncGeneratorRequestMap"),
|
||||
("RO_SPACE", 0x09ca1): (159, "DebugInfoMap"),
|
||||
("RO_SPACE", 0x09cf1): (160, "FunctionTemplateInfoMap"),
|
||||
("RO_SPACE", 0x09d41): (162, "InterpreterDataMap"),
|
||||
("RO_SPACE", 0x09d91): (163, "ModuleInfoEntryMap"),
|
||||
("RO_SPACE", 0x09de1): (164, "ModuleMap"),
|
||||
("RO_SPACE", 0x09e31): (165, "ObjectTemplateInfoMap"),
|
||||
("RO_SPACE", 0x09e81): (166, "PromiseCapabilityMap"),
|
||||
("RO_SPACE", 0x09ed1): (167, "PromiseReactionMap"),
|
||||
("RO_SPACE", 0x09f21): (168, "PrototypeInfoMap"),
|
||||
("RO_SPACE", 0x09f71): (170, "StackFrameInfoMap"),
|
||||
("RO_SPACE", 0x09fc1): (172, "Tuple3Map"),
|
||||
("RO_SPACE", 0x0a011): (174, "WasmDebugInfoMap"),
|
||||
("RO_SPACE", 0x0a061): (175, "WasmExportedFunctionDataMap"),
|
||||
("RO_SPACE", 0x0a0b1): (176, "CallableTaskMap"),
|
||||
("RO_SPACE", 0x0a101): (177, "CallbackTaskMap"),
|
||||
("RO_SPACE", 0x0a151): (178, "PromiseFulfillReactionJobTaskMap"),
|
||||
("RO_SPACE", 0x0a1a1): (179, "PromiseRejectReactionJobTaskMap"),
|
||||
("RO_SPACE", 0x0a1f1): (180, "PromiseResolveThenableJobTaskMap"),
|
||||
("RO_SPACE", 0x0a241): (181, "AllocationSiteMap"),
|
||||
("RO_SPACE", 0x0a291): (181, "AllocationSiteMap"),
|
||||
("MAP_SPACE", 0x02201): (1057, "ExternalMap"),
|
||||
("MAP_SPACE", 0x02251): (1072, "JSMessageObjectMap"),
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user