Commit 550364fb authored by clemensh's avatar clemensh Committed by Commit bot

[wasm] Extend wasm object validation to WasmCompiledModule

I am removing three fields from the wasm object in a follow-up commit,
and using information in the compiled module instead. In order to not
weaken the verification, this commit adds appropriate checks on the
compiled module.

R=titzer@chromium.org,mtrofin@chromium.org

Review-Url: https://codereview.chromium.org/2394663008
Cr-Commit-Position: refs/heads/master@{#40061}
parent 8352a0fe
...@@ -1127,7 +1127,8 @@ MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions( ...@@ -1127,7 +1127,8 @@ MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions(
Handle<String> module_bytes_string = Handle<String> module_bytes_string =
factory->NewStringFromOneByte(module_bytes_vec, TENURED) factory->NewStringFromOneByte(module_bytes_vec, TENURED)
.ToHandleChecked(); .ToHandleChecked();
ret->set_module_bytes(module_bytes_string); DCHECK(module_bytes_string->IsSeqOneByteString());
ret->set_module_bytes(Handle<SeqOneByteString>::cast(module_bytes_string));
} }
Handle<ByteArray> function_name_table = Handle<ByteArray> function_name_table =
...@@ -1308,8 +1309,8 @@ class WasmInstanceBuilder { ...@@ -1308,8 +1309,8 @@ class WasmInstanceBuilder {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Set up the debug support for the new instance. // Set up the debug support for the new instance.
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// TODO(wasm): avoid referencing this stuff from the instance, use it off // TODO(clemensh): avoid referencing this stuff from the instance, use it
// the compiled module instead. See the following 3 assignments: // off the compiled module instead. See the following 3 assignments:
if (compiled_module_->has_module_bytes()) { if (compiled_module_->has_module_bytes()) {
instance->SetInternalField(kWasmModuleBytesString, instance->SetInternalField(kWasmModuleBytesString,
compiled_module_->ptr_to_module_bytes()); compiled_module_->ptr_to_module_bytes());
...@@ -1413,8 +1414,6 @@ class WasmInstanceBuilder { ...@@ -1413,8 +1414,6 @@ class WasmInstanceBuilder {
} }
} }
DCHECK(wasm::IsWasmObject(*instance));
{ {
Handle<WeakCell> link_to_owner = factory->NewWeakCell(instance); Handle<WeakCell> link_to_owner = factory->NewWeakCell(instance);
...@@ -1441,6 +1440,9 @@ class WasmInstanceBuilder { ...@@ -1441,6 +1440,9 @@ class WasmInstanceBuilder {
v8::WeakCallbackType::kFinalizer); v8::WeakCallbackType::kFinalizer);
} }
} }
DCHECK(wasm::IsWasmObject(*instance));
TRACE("Finishing instance %d\n", compiled_module_->instance_id()); TRACE("Finishing instance %d\n", compiled_module_->instance_id());
TRACE_CHAIN(WasmCompiledModule::cast(module_object_->GetInternalField(0))); TRACE_CHAIN(WasmCompiledModule::cast(module_object_->GetInternalField(0)));
return instance; return instance;
...@@ -1871,8 +1873,12 @@ Handle<WasmCompiledModule> WasmCompiledModule::New(Isolate* isolate, ...@@ -1871,8 +1873,12 @@ Handle<WasmCompiledModule> WasmCompiledModule::New(Isolate* isolate,
Smi::FromInt(static_cast<int>(min_memory_pages))); Smi::FromInt(static_cast<int>(min_memory_pages)));
ret->set(kID_globals_size, Smi::FromInt(static_cast<int>(globals_size))); ret->set(kID_globals_size, Smi::FromInt(static_cast<int>(globals_size)));
ret->set(kID_origin, Smi::FromInt(static_cast<int>(origin))); ret->set(kID_origin, Smi::FromInt(static_cast<int>(origin)));
WasmCompiledModule::cast(*ret)->Init();
return handle(WasmCompiledModule::cast(*ret)); // WasmCompiledModule::cast would fail since module bytes are not set yet.
Handle<WasmCompiledModule> module(reinterpret_cast<WasmCompiledModule*>(*ret),
isolate);
module->Init();
return module;
} }
void WasmCompiledModule::Init() { void WasmCompiledModule::Init() {
...@@ -1883,6 +1889,34 @@ void WasmCompiledModule::Init() { ...@@ -1883,6 +1889,34 @@ void WasmCompiledModule::Init() {
#endif #endif
} }
bool WasmCompiledModule::IsWasmCompiledModule(Object* obj) {
if (!obj->IsFixedArray()) return false;
FixedArray* arr = FixedArray::cast(obj);
if (arr->length() != PropertyIndices::Count) return false;
Isolate* isolate = arr->GetIsolate();
#define WCM_CHECK_SMALL_NUMBER(TYPE, NAME) \
if (!arr->get(kID_##NAME)->IsSmi()) return false;
#define WCM_CHECK_OBJECT_OR_WEAK(TYPE, NAME) \
if (!arr->get(kID_##NAME)->IsUndefined(isolate) && \
!arr->get(kID_##NAME)->Is##TYPE()) \
return false;
#define WCM_CHECK_OBJECT(TYPE, NAME) WCM_CHECK_OBJECT_OR_WEAK(TYPE, NAME)
#define WCM_CHECK_WEAK_LINK(TYPE, NAME) WCM_CHECK_OBJECT_OR_WEAK(WeakCell, NAME)
#define WCM_CHECK(KIND, TYPE, NAME) WCM_CHECK_##KIND(TYPE, NAME)
WCM_PROPERTY_TABLE(WCM_CHECK)
#undef WCM_CHECK
WasmCompiledModule* compiled_module =
reinterpret_cast<WasmCompiledModule*>(obj);
if (!compiled_module->has_module_bytes()) return false;
SeqOneByteString* module_bytes = compiled_module->ptr_to_module_bytes();
if (module_bytes->length() < 4) return false;
if (memcmp(module_bytes->GetChars(), "\0asm", 4)) return false;
// All checks passed.
return true;
}
void WasmCompiledModule::PrintInstancesChain() { void WasmCompiledModule::PrintInstancesChain() {
#if DEBUG #if DEBUG
if (!FLAG_trace_wasm_instances) return; if (!FLAG_trace_wasm_instances) return;
...@@ -1935,23 +1969,16 @@ bool IsWasmObject(Object* object) { ...@@ -1935,23 +1969,16 @@ bool IsWasmObject(Object* object) {
} }
Object* mem = obj->GetInternalField(kWasmMemArrayBuffer); Object* mem = obj->GetInternalField(kWasmMemArrayBuffer);
if (obj->GetInternalField(kWasmModuleCodeTable)->IsFixedArray() && if (!obj->GetInternalField(kWasmModuleCodeTable)->IsFixedArray() ||
(mem->IsUndefined(isolate) || mem->IsJSArrayBuffer()) && !(mem->IsUndefined(isolate) || mem->IsJSArrayBuffer()) ||
obj->GetInternalField(kWasmFunctionNamesArray)->IsByteArray()) { !obj->GetInternalField(kWasmFunctionNamesArray)->IsByteArray() ||
Object* debug_bytes = obj->GetInternalField(kWasmModuleBytesString); !WasmCompiledModule::IsWasmCompiledModule(
if (!debug_bytes->IsUndefined(isolate)) { obj->GetInternalField(kWasmCompiledModule))) {
if (!debug_bytes->IsSeqOneByteString()) { return false;
return false;
}
DisallowHeapAllocation no_gc;
SeqOneByteString* bytes = SeqOneByteString::cast(debug_bytes);
if (bytes->length() < 4) return false;
if (memcmp(bytes->GetChars(), "\0asm", 4)) return false;
// All checks passed.
}
return true;
} }
return false;
// All checks passed.
return true;
} }
SeqOneByteString* GetWasmBytes(JSObject* wasm) { SeqOneByteString* GetWasmBytes(JSObject* wasm) {
......
...@@ -347,6 +347,7 @@ typedef Result<FunctionOffsets> FunctionOffsetsResult; ...@@ -347,6 +347,7 @@ typedef Result<FunctionOffsets> FunctionOffsetsResult;
class WasmCompiledModule : public FixedArray { class WasmCompiledModule : public FixedArray {
public: public:
static WasmCompiledModule* cast(Object* fixed_array) { static WasmCompiledModule* cast(Object* fixed_array) {
SLOW_DCHECK(IsWasmCompiledModule(fixed_array));
return reinterpret_cast<WasmCompiledModule*>(fixed_array); return reinterpret_cast<WasmCompiledModule*>(fixed_array);
} }
...@@ -393,7 +394,7 @@ class WasmCompiledModule : public FixedArray { ...@@ -393,7 +394,7 @@ class WasmCompiledModule : public FixedArray {
MACRO(OBJECT, FixedArray, inits) \ MACRO(OBJECT, FixedArray, inits) \
MACRO(OBJECT, FixedArray, startup_function) \ MACRO(OBJECT, FixedArray, startup_function) \
MACRO(OBJECT, FixedArray, indirect_function_tables) \ MACRO(OBJECT, FixedArray, indirect_function_tables) \
MACRO(OBJECT, String, module_bytes) \ MACRO(OBJECT, SeqOneByteString, module_bytes) \
MACRO(OBJECT, ByteArray, function_names) \ MACRO(OBJECT, ByteArray, function_names) \
MACRO(SMALL_NUMBER, uint32_t, min_memory_pages) \ MACRO(SMALL_NUMBER, uint32_t, min_memory_pages) \
MACRO(OBJECT, FixedArray, data_segments_info) \ MACRO(OBJECT, FixedArray, data_segments_info) \
...@@ -454,6 +455,8 @@ class WasmCompiledModule : public FixedArray { ...@@ -454,6 +455,8 @@ class WasmCompiledModule : public FixedArray {
WCM_PROPERTY_TABLE(DECLARATION) WCM_PROPERTY_TABLE(DECLARATION)
#undef DECLARATION #undef DECLARATION
static bool IsWasmCompiledModule(Object* obj);
void PrintInstancesChain(); void PrintInstancesChain();
private: private:
......
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