Commit e8d79f07 authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

[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: 's avatarClemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55602}
parent 175f2a6a
......@@ -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_;
};
......
// 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"),
}
......
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