Loading config/external/wasm2c_sandbox_compiler/moz.yaml +5 −3 Original line number Diff line number Diff line Loading @@ -9,8 +9,8 @@ origin: description: wasm2c fork used for rlbox sandboxing url: https://github.com/PLSysSec/wasm2c_sandbox_compiler release: commit cdcf20186f3bfef472b32836b10e12b5cdaaebda (2021-11-09T07:39:20Z). revision: cdcf20186f3bfef472b32836b10e12b5cdaaebda release: 3266be52998117f47b490d026b02e4193d5d3338 (2022-11-24T04:56:29Z). revision: 3266be52998117f47b490d026b02e4193d5d3338 license: Apache-2.0 license-file: LICENSE Loading Loading @@ -45,4 +45,6 @@ vendoring: - Makefile - README.md - ubsan.blacklist - wasm2c/examples/hello/.gitignore - wasm2c/wasm-rt-runner.c - wasm2c/wasm-rt-static-runner.c third_party/wasm2c/src/c-writer.cc +23 −6 Original line number Diff line number Diff line Loading @@ -175,6 +175,7 @@ class CWriter { string_view mangled_field_name); std::string DefineGlobalScopeName(const std::string&); std::string DefineLocalScopeName(const std::string&); std::string DefineGlobalVarName(const std::string& name); std::string DefineStackVarName(Index, Type, string_view); void Indent(int size = INDENT_SIZE); Loading @@ -191,6 +192,7 @@ class CWriter { } std::string GetGlobalName(const std::string&) const; std::string GetGlobalVarName(const std::string& name) const; void Write() {} void Write(Newline); Loading Loading @@ -289,9 +291,11 @@ class CWriter { SymbolMap global_sym_map_; SymbolMap local_sym_map_; SymbolMap globalvars_sym_map_; StackVarSymbolMap stack_var_sym_map_; SymbolSet global_syms_; SymbolSet local_syms_; SymbolSet globalvars_syms_; SymbolSet import_syms_; TypeVector type_stack_; std::vector<Label> label_stack_; Loading Loading @@ -510,6 +514,12 @@ std::string CWriter::DefineLocalScopeName(const std::string& name) { return unique; } std::string CWriter::DefineGlobalVarName(const std::string& name) { std::string unique = DefineName(&globalvars_syms_, StripLeadingDollar(name)); globalvars_sym_map_.insert(SymbolMap::value_type(name, unique)); return unique; } std::string CWriter::DefineStackVarName(Index index, Type type, string_view name) { Loading Loading @@ -592,6 +602,13 @@ std::string CWriter::GetGlobalName(const std::string& name) const { return iter->second; } std::string CWriter::GetGlobalVarName(const std::string& name) const { assert(globalvars_sym_map_.count(name) == 1); auto iter = globalvars_sym_map_.find(name); assert(iter != globalvars_sym_map_.end()); return iter->second; } void CWriter::Write(const GlobalName& name) { Write(GetGlobalName(name.name)); } Loading Loading @@ -646,7 +663,7 @@ void CWriter::Write(const LabelDecl& label) { void CWriter::Write(const GlobalVar& var) { assert(var.var.is_name()); Write(ExternalRef(var.var.name())); Write(GetGlobalVarName(var.var.name())); } void CWriter::Write(const StackVar& sv) { Loading Loading @@ -1078,7 +1095,7 @@ void CWriter::WriteGlobals() { for (const Global* global : module_->globals) { bool is_import = global_index < module_->num_global_imports; if (!is_import) { WriteGlobal(*global, DefineGlobalScopeName(global->name)); WriteGlobal(*global, DefineGlobalVarName(global->name)); Write(";", Newline()); } ++global_index; Loading @@ -1093,7 +1110,7 @@ void CWriter::WriteGlobalsExport() { for (const Global* global : module_->globals) { bool is_import = global_index < module_->num_global_imports; if (!is_import) { std::string curr_global_name = GetGlobalName(global->name); std::string curr_global_name = GetGlobalVarName(global->name); Writef("if (strcmp(\"%s\", name) == 0)", curr_global_name.c_str()); Write(OpenBrace()); Write("return &(sbx->", curr_global_name, ");", Newline()); Loading Loading @@ -1122,7 +1139,7 @@ void CWriter::WriteGlobalInitializers() { bool is_import = global_index < module_->num_global_imports; if (!is_import) { assert(!global->init_expr.empty()); Write("sbx->", GlobalName(global->name), " = "); Write("sbx->", GetGlobalVarName(global->name), " = "); WriteInitExpr(global->init_expr); Write(";", Newline()); } Loading @@ -1136,7 +1153,7 @@ void CWriter::WriteGlobalInitializers() { for (const Global* global : module_->globals) { bool is_import = global_index < module_->num_global_imports; if (!is_import) { std::string global_name = GetGlobalName(global->name); std::string global_name = GetGlobalVarName(global->name); std::string global_name_expr = "sbx->" + global_name; Write("WASM2C_SHADOW_MEMORY_RESERVE(&(sbx->", memory_name ,"), ", global_name_expr, ", sizeof(", global_name_expr, "));", Newline()); if (global_name == "w2c___heap_base") { Loading Loading @@ -1597,7 +1614,7 @@ void CWriter::Write(const ExprList& exprs) { Write(StackVar(num_params - 1, func.GetResultType(0)), " = "); } Write(GlobalVar(var), "(sbx"); Write(GlobalName(var.name()), "(sbx"); for (Index i = 0; i < num_params; ++i) { Write(", ", StackVar(num_params - i - 1)); } Loading third_party/wasm2c/src/prebuilt/wasm2c.include.c +9 −0 Original line number Diff line number Diff line Loading @@ -107,6 +107,12 @@ const char SECTION_NAME(declarations)[] = "# define MEM_ACCESS_REF(mem, addr) (char*) addr\n" "#endif\n" "\n" "#ifdef __GNUC__\n" "#define wasm_asm __asm__\n" "#else\n" "#define wasm_asm(X)\n" "#endif\n" "\n" "#if WABT_BIG_ENDIAN\n" "static inline void load_data(void *dest, const void *src, size_t n) {\n" " size_t i = 0;\n" Loading @@ -129,6 +135,7 @@ const char SECTION_NAME(declarations)[] = " t1 result; \\\n" " memcpy(&result, MEM_ACCESS_REF(mem, mem->size - addr - sizeof(t1)), sizeof(t1)); \\\n" " WASM2C_SHADOW_MEMORY_LOAD(mem, func_name, mem->size - addr - sizeof(t1), sizeof(t1)); \\\n" " wasm_asm(\"\" ::\"r\"(result)); \\\n" " return (t3)(t2)result; \\\n" " }\n" "\n" Loading @@ -154,6 +161,7 @@ const char SECTION_NAME(declarations)[] = " t1 result; \\\n" " memcpy(&result, MEM_ACCESS_REF(mem, addr), sizeof(t1)); \\\n" " WASM2C_SHADOW_MEMORY_LOAD(mem, func_name, addr, sizeof(t1)); \\\n" " wasm_asm(\"\" ::\"r\"(result)); \\\n" " return (t3)(t2)result; \\\n" " }\n" "\n" Loading Loading @@ -404,6 +412,7 @@ const char SECTION_NAME(sandboxapis)[] = " init_table(sbx);\n" " wasm_rt_init_wasi(&(sbx->wasi_data));\n" " init_module_starts();\n" " // w2c___wasm_call_ctors(sbx);\n" " return sbx;\n" "}\n" "\n" Loading third_party/wasm2c/src/wasm2c.c.tmpl +9 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,12 @@ void WASM2C_MALLOC_FAIL_CALLBACK(u32 ptr_size); # define MEM_ACCESS_REF(mem, addr) (char*) addr #endif #ifdef __GNUC__ #define wasm_asm __asm__ #else #define wasm_asm(X) #endif #if WABT_BIG_ENDIAN static inline void load_data(void *dest, const void *src, size_t n) { size_t i = 0; Loading @@ -126,6 +132,7 @@ static inline void load_data(void *dest, const void *src, size_t n) { t1 result; \ memcpy(&result, MEM_ACCESS_REF(mem, mem->size - addr - sizeof(t1)), sizeof(t1)); \ WASM2C_SHADOW_MEMORY_LOAD(mem, func_name, mem->size - addr - sizeof(t1), sizeof(t1)); \ wasm_asm("" ::"r"(result)); \ return (t3)(t2)result; \ } Loading @@ -151,6 +158,7 @@ static inline void load_data(void *dest, const void *src, size_t n) { t1 result; \ memcpy(&result, MEM_ACCESS_REF(mem, addr), sizeof(t1)); \ WASM2C_SHADOW_MEMORY_LOAD(mem, func_name, addr, sizeof(t1)); \ wasm_asm("" ::"r"(result)); \ return (t3)(t2)result; \ } Loading Loading @@ -399,6 +407,7 @@ static void* create_wasm2c_sandbox(uint32_t max_wasm_pages) { init_table(sbx); wasm_rt_init_wasi(&(sbx->wasi_data)); init_module_starts(); // w2c___wasm_call_ctors(sbx); return sbx; } Loading third_party/wasm2c/wasm2c/wasm-rt-impl.c +100 −75 Original line number Diff line number Diff line Loading @@ -14,8 +14,8 @@ * limitations under the License. */ #include "wasm-rt.h" #include "wasm-rt-os.h" #include "wasm-rt.h" #include <assert.h> #include <limits.h> Loading @@ -33,8 +33,7 @@ void wasm_rt_trap(wasm_rt_trap_t code) { const char* error_message = "wasm2c: unknown trap"; switch(code) { switch (code) { case WASM_RT_TRAP_NONE: { // this should never happen error_message = "wasm2c: WASM_RT_TRAP_NONE"; Loading Loading @@ -101,7 +100,9 @@ void wasm_rt_trap(wasm_rt_trap_t code) { #endif } void wasm_rt_callback_error_trap(wasm_rt_table_t* table, uint32_t func_index, uint32_t expected_func_type) { void wasm_rt_callback_error_trap(wasm_rt_table_t* table, uint32_t func_index, uint32_t expected_func_type) { if (func_index >= table->size) { wasm_rt_trap(WASM_RT_TRAP_CALL_INDIRECT_OOB_INDEX); } else if (!table->data[func_index].func) { Loading @@ -112,7 +113,6 @@ void wasm_rt_callback_error_trap(wasm_rt_table_t* table, uint32_t func_index, ui wasm_rt_trap(WASM_RT_TRAP_CALL_INDIRECT_UNKNOWN_ERR); } static bool func_types_are_equal(wasm_func_type_t* a, wasm_func_type_t* b) { if (a->param_count != b->param_count || a->result_count != b->result_count) return 0; Loading Loading @@ -170,12 +170,14 @@ uint32_t wasm_rt_register_func_type(wasm_func_type_t** p_func_type_structs, uint32_t idx = (*p_func_type_count)++; // realloc works fine even if *p_func_type_structs is null *p_func_type_structs = realloc(*p_func_type_structs, *p_func_type_count * sizeof(wasm_func_type_t)); *p_func_type_structs = realloc(*p_func_type_structs, *p_func_type_count * sizeof(wasm_func_type_t)); (*p_func_type_structs)[idx] = func_type; return idx + 1; } void wasm_rt_cleanup_func_types(wasm_func_type_t** p_func_type_structs, uint32_t* p_func_type_count) { void wasm_rt_cleanup_func_types(wasm_func_type_t** p_func_type_structs, uint32_t* p_func_type_count) { // Use a u64 to iterate over u32 arrays to prevent infinite loops const uint32_t func_count = *p_func_type_count; for (uint64_t idx = 0; idx < func_count; idx++) { Loading @@ -193,8 +195,7 @@ void wasm_rt_cleanup_func_types(wasm_func_type_t** p_func_type_structs, uint32_t } #if UINTPTR_MAX == 0xffffffff static int is_power_of_two(uint64_t x) { static int is_power_of_two(uint64_t x) { return ((x != 0) && !(x & (x - 1))); } #endif Loading Loading @@ -232,13 +233,23 @@ uint64_t wasm_rt_get_default_max_linear_memory_size() { return ret; } static uint64_t compute_heap_reserve_space(uint32_t chosen_max_pages) { const uint64_t heap_reserve_size = ((uint64_t)chosen_max_pages) * WASM_PAGE_SIZE + WASM_HEAP_GUARD_PAGE_SIZE; return heap_reserve_size; } bool wasm_rt_allocate_memory(wasm_rt_memory_t* memory, uint32_t initial_pages, uint32_t max_pages) { const uint32_t byte_length = initial_pages * WASM_PAGE_SIZE; const uint32_t suggested_max_pages = max_pages == 0? WASM_HEAP_DEFAULT_MAX_PAGES : max_pages; const uint32_t chosen_max_pages = (WASM_HEAP_MAX_ALLOWED_PAGES < suggested_max_pages)? WASM_HEAP_MAX_ALLOWED_PAGES : suggested_max_pages; const uint32_t suggested_max_pages = max_pages == 0 ? WASM_HEAP_DEFAULT_MAX_PAGES : max_pages; const uint32_t chosen_max_pages = (WASM_HEAP_MAX_ALLOWED_PAGES < suggested_max_pages) ? WASM_HEAP_MAX_ALLOWED_PAGES : suggested_max_pages; if (chosen_max_pages < initial_pages) { return false; Loading @@ -246,10 +257,12 @@ bool wasm_rt_allocate_memory(wasm_rt_memory_t* memory, #ifdef WASM_USE_GUARD_PAGES // mmap based heaps with guard pages // Guard pages already allocates memory incrementally thus we don't need to look at WASM_USE_INCREMENTAL_MOVEABLE_MEMORY_ALLOC // Guard pages already allocates memory incrementally thus we don't need to // look at WASM_USE_INCREMENTAL_MOVEABLE_MEMORY_ALLOC void* addr = NULL; const uint64_t retries = 10; const uint64_t heap_reserve_size = ((uint64_t) chosen_max_pages) * WASM_PAGE_SIZE + WASM_HEAP_GUARD_PAGE_SIZE; const uint64_t heap_reserve_size = compute_heap_reserve_space(chosen_max_pages); // 32-bit platforms rely on masking for sandboxing // thus we require the heap reserve size to always be a power of 2 Loading @@ -260,7 +273,9 @@ bool wasm_rt_allocate_memory(wasm_rt_memory_t* memory, #endif for (uint64_t i = 0; i < retries; i++) { addr = os_mmap_aligned(NULL, heap_reserve_size, MMAP_PROT_NONE, MMAP_MAP_NONE, WASM_HEAP_ALIGNMENT, 0 /* alignment_offset */); addr = os_mmap_aligned(NULL, heap_reserve_size, MMAP_PROT_NONE, MMAP_MAP_NONE, WASM_HEAP_ALIGNMENT, 0 /* alignment_offset */); if (addr) { break; } Loading @@ -274,9 +289,11 @@ bool wasm_rt_allocate_memory(wasm_rt_memory_t* memory, if (ret != 0) { return false; } // This is a valid way to initialize a constant field that is not undefined behavior // This is a valid way to initialize a constant field that is not undefined // behavior // https://stackoverflow.com/questions/9691404/how-to-initialize-const-in-a-struct-in-c-with-malloc // Summary: malloc of a struct, followed by a write to the constant fields is still defined behavior iff // Summary: malloc of a struct, followed by a write to the constant fields is // still defined behavior iff // there is no prior read of the field *(uint8_t**)&memory->data = addr; #else Loading Loading @@ -306,7 +323,8 @@ bool wasm_rt_allocate_memory(wasm_rt_memory_t* memory, void wasm_rt_deallocate_memory(wasm_rt_memory_t* memory) { #ifdef WASM_USE_GUARD_PAGES const uint64_t heap_reserve_size = ((uint64_t) memory->max_pages) * WASM_PAGE_SIZE + WASM_HEAP_GUARD_PAGE_SIZE; const uint64_t heap_reserve_size = compute_heap_reserve_space(memory->max_pages); os_munmap(memory->data, heap_reserve_size); #else free(memory->data); Loading @@ -332,12 +350,14 @@ uint32_t wasm_rt_grow_memory(wasm_rt_memory_t* memory, uint32_t delta) { #ifdef WASM_USE_GUARD_PAGES // mmap based heaps with guard pages int ret = os_mmap_commit(memory->data + old_size, delta_size, MMAP_PROT_READ | MMAP_PROT_WRITE); int ret = os_mmap_commit(memory->data + old_size, delta_size, MMAP_PROT_READ | MMAP_PROT_WRITE); if (ret != 0) { return (uint32_t)-1; } #else // malloc based heaps --- if below macro is not defined, the max memory range is already allocated // malloc based heaps --- if below macro is not defined, the max memory range // is already allocated #ifdef WASM_USE_INCREMENTAL_MOVEABLE_MEMORY_ALLOC uint8_t* new_data = realloc(memory->data, new_size); if (new_data == NULL) { Loading Loading @@ -376,7 +396,8 @@ void wasm_rt_deallocate_table(wasm_rt_table_t* table) { free(table->data); } #define WASM_SATURATING_U32_ADD(ret_ptr, a, b) { \ #define WASM_SATURATING_U32_ADD(ret_ptr, a, b) \ { \ if ((a) > (UINT32_MAX - (b))) { \ /* add will overflowed */ \ *ret_ptr = UINT32_MAX; \ Loading @@ -385,7 +406,8 @@ void wasm_rt_deallocate_table(wasm_rt_table_t* table) { } \ } #define WASM_CHECKED_U32_RET_SIZE_T_MULTIPLY(ret_ptr, a, b) { \ #define WASM_CHECKED_U32_RET_SIZE_T_MULTIPLY(ret_ptr, a, b) \ { \ if ((a) > (SIZE_MAX / (b))) { \ /* multiple will overflowed */ \ wasm_rt_trap(WASM_RT_TRAP_CALL_INDIRECT_TABLE_EXPANSION); \ Loading @@ -410,16 +432,19 @@ void wasm_rt_expand_table(wasm_rt_table_t* table) { } size_t allocation_size = 0; WASM_CHECKED_U32_RET_SIZE_T_MULTIPLY(&allocation_size, sizeof(wasm_rt_elem_t), new_size); WASM_CHECKED_U32_RET_SIZE_T_MULTIPLY(&allocation_size, sizeof(wasm_rt_elem_t), new_size); table->data = realloc(table->data, allocation_size); assert(table->data != 0); memset(&(table->data[table->size]), 0, allocation_size - (table->size * sizeof(wasm_rt_elem_t))); memset(&(table->data[table->size]), 0, allocation_size - (table->size * sizeof(wasm_rt_elem_t))); table->size = new_size; } void wasm2c_ensure_linked() { // We use this to ensure the dynamic library with the wasi symbols is loaded for the host application // We use this to ensure the dynamic library with the wasi symbols is loaded // for the host application } #undef WASM_PAGE_SIZE Loading Loading
config/external/wasm2c_sandbox_compiler/moz.yaml +5 −3 Original line number Diff line number Diff line Loading @@ -9,8 +9,8 @@ origin: description: wasm2c fork used for rlbox sandboxing url: https://github.com/PLSysSec/wasm2c_sandbox_compiler release: commit cdcf20186f3bfef472b32836b10e12b5cdaaebda (2021-11-09T07:39:20Z). revision: cdcf20186f3bfef472b32836b10e12b5cdaaebda release: 3266be52998117f47b490d026b02e4193d5d3338 (2022-11-24T04:56:29Z). revision: 3266be52998117f47b490d026b02e4193d5d3338 license: Apache-2.0 license-file: LICENSE Loading Loading @@ -45,4 +45,6 @@ vendoring: - Makefile - README.md - ubsan.blacklist - wasm2c/examples/hello/.gitignore - wasm2c/wasm-rt-runner.c - wasm2c/wasm-rt-static-runner.c
third_party/wasm2c/src/c-writer.cc +23 −6 Original line number Diff line number Diff line Loading @@ -175,6 +175,7 @@ class CWriter { string_view mangled_field_name); std::string DefineGlobalScopeName(const std::string&); std::string DefineLocalScopeName(const std::string&); std::string DefineGlobalVarName(const std::string& name); std::string DefineStackVarName(Index, Type, string_view); void Indent(int size = INDENT_SIZE); Loading @@ -191,6 +192,7 @@ class CWriter { } std::string GetGlobalName(const std::string&) const; std::string GetGlobalVarName(const std::string& name) const; void Write() {} void Write(Newline); Loading Loading @@ -289,9 +291,11 @@ class CWriter { SymbolMap global_sym_map_; SymbolMap local_sym_map_; SymbolMap globalvars_sym_map_; StackVarSymbolMap stack_var_sym_map_; SymbolSet global_syms_; SymbolSet local_syms_; SymbolSet globalvars_syms_; SymbolSet import_syms_; TypeVector type_stack_; std::vector<Label> label_stack_; Loading Loading @@ -510,6 +514,12 @@ std::string CWriter::DefineLocalScopeName(const std::string& name) { return unique; } std::string CWriter::DefineGlobalVarName(const std::string& name) { std::string unique = DefineName(&globalvars_syms_, StripLeadingDollar(name)); globalvars_sym_map_.insert(SymbolMap::value_type(name, unique)); return unique; } std::string CWriter::DefineStackVarName(Index index, Type type, string_view name) { Loading Loading @@ -592,6 +602,13 @@ std::string CWriter::GetGlobalName(const std::string& name) const { return iter->second; } std::string CWriter::GetGlobalVarName(const std::string& name) const { assert(globalvars_sym_map_.count(name) == 1); auto iter = globalvars_sym_map_.find(name); assert(iter != globalvars_sym_map_.end()); return iter->second; } void CWriter::Write(const GlobalName& name) { Write(GetGlobalName(name.name)); } Loading Loading @@ -646,7 +663,7 @@ void CWriter::Write(const LabelDecl& label) { void CWriter::Write(const GlobalVar& var) { assert(var.var.is_name()); Write(ExternalRef(var.var.name())); Write(GetGlobalVarName(var.var.name())); } void CWriter::Write(const StackVar& sv) { Loading Loading @@ -1078,7 +1095,7 @@ void CWriter::WriteGlobals() { for (const Global* global : module_->globals) { bool is_import = global_index < module_->num_global_imports; if (!is_import) { WriteGlobal(*global, DefineGlobalScopeName(global->name)); WriteGlobal(*global, DefineGlobalVarName(global->name)); Write(";", Newline()); } ++global_index; Loading @@ -1093,7 +1110,7 @@ void CWriter::WriteGlobalsExport() { for (const Global* global : module_->globals) { bool is_import = global_index < module_->num_global_imports; if (!is_import) { std::string curr_global_name = GetGlobalName(global->name); std::string curr_global_name = GetGlobalVarName(global->name); Writef("if (strcmp(\"%s\", name) == 0)", curr_global_name.c_str()); Write(OpenBrace()); Write("return &(sbx->", curr_global_name, ");", Newline()); Loading Loading @@ -1122,7 +1139,7 @@ void CWriter::WriteGlobalInitializers() { bool is_import = global_index < module_->num_global_imports; if (!is_import) { assert(!global->init_expr.empty()); Write("sbx->", GlobalName(global->name), " = "); Write("sbx->", GetGlobalVarName(global->name), " = "); WriteInitExpr(global->init_expr); Write(";", Newline()); } Loading @@ -1136,7 +1153,7 @@ void CWriter::WriteGlobalInitializers() { for (const Global* global : module_->globals) { bool is_import = global_index < module_->num_global_imports; if (!is_import) { std::string global_name = GetGlobalName(global->name); std::string global_name = GetGlobalVarName(global->name); std::string global_name_expr = "sbx->" + global_name; Write("WASM2C_SHADOW_MEMORY_RESERVE(&(sbx->", memory_name ,"), ", global_name_expr, ", sizeof(", global_name_expr, "));", Newline()); if (global_name == "w2c___heap_base") { Loading Loading @@ -1597,7 +1614,7 @@ void CWriter::Write(const ExprList& exprs) { Write(StackVar(num_params - 1, func.GetResultType(0)), " = "); } Write(GlobalVar(var), "(sbx"); Write(GlobalName(var.name()), "(sbx"); for (Index i = 0; i < num_params; ++i) { Write(", ", StackVar(num_params - i - 1)); } Loading
third_party/wasm2c/src/prebuilt/wasm2c.include.c +9 −0 Original line number Diff line number Diff line Loading @@ -107,6 +107,12 @@ const char SECTION_NAME(declarations)[] = "# define MEM_ACCESS_REF(mem, addr) (char*) addr\n" "#endif\n" "\n" "#ifdef __GNUC__\n" "#define wasm_asm __asm__\n" "#else\n" "#define wasm_asm(X)\n" "#endif\n" "\n" "#if WABT_BIG_ENDIAN\n" "static inline void load_data(void *dest, const void *src, size_t n) {\n" " size_t i = 0;\n" Loading @@ -129,6 +135,7 @@ const char SECTION_NAME(declarations)[] = " t1 result; \\\n" " memcpy(&result, MEM_ACCESS_REF(mem, mem->size - addr - sizeof(t1)), sizeof(t1)); \\\n" " WASM2C_SHADOW_MEMORY_LOAD(mem, func_name, mem->size - addr - sizeof(t1), sizeof(t1)); \\\n" " wasm_asm(\"\" ::\"r\"(result)); \\\n" " return (t3)(t2)result; \\\n" " }\n" "\n" Loading @@ -154,6 +161,7 @@ const char SECTION_NAME(declarations)[] = " t1 result; \\\n" " memcpy(&result, MEM_ACCESS_REF(mem, addr), sizeof(t1)); \\\n" " WASM2C_SHADOW_MEMORY_LOAD(mem, func_name, addr, sizeof(t1)); \\\n" " wasm_asm(\"\" ::\"r\"(result)); \\\n" " return (t3)(t2)result; \\\n" " }\n" "\n" Loading Loading @@ -404,6 +412,7 @@ const char SECTION_NAME(sandboxapis)[] = " init_table(sbx);\n" " wasm_rt_init_wasi(&(sbx->wasi_data));\n" " init_module_starts();\n" " // w2c___wasm_call_ctors(sbx);\n" " return sbx;\n" "}\n" "\n" Loading
third_party/wasm2c/src/wasm2c.c.tmpl +9 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,12 @@ void WASM2C_MALLOC_FAIL_CALLBACK(u32 ptr_size); # define MEM_ACCESS_REF(mem, addr) (char*) addr #endif #ifdef __GNUC__ #define wasm_asm __asm__ #else #define wasm_asm(X) #endif #if WABT_BIG_ENDIAN static inline void load_data(void *dest, const void *src, size_t n) { size_t i = 0; Loading @@ -126,6 +132,7 @@ static inline void load_data(void *dest, const void *src, size_t n) { t1 result; \ memcpy(&result, MEM_ACCESS_REF(mem, mem->size - addr - sizeof(t1)), sizeof(t1)); \ WASM2C_SHADOW_MEMORY_LOAD(mem, func_name, mem->size - addr - sizeof(t1), sizeof(t1)); \ wasm_asm("" ::"r"(result)); \ return (t3)(t2)result; \ } Loading @@ -151,6 +158,7 @@ static inline void load_data(void *dest, const void *src, size_t n) { t1 result; \ memcpy(&result, MEM_ACCESS_REF(mem, addr), sizeof(t1)); \ WASM2C_SHADOW_MEMORY_LOAD(mem, func_name, addr, sizeof(t1)); \ wasm_asm("" ::"r"(result)); \ return (t3)(t2)result; \ } Loading Loading @@ -399,6 +407,7 @@ static void* create_wasm2c_sandbox(uint32_t max_wasm_pages) { init_table(sbx); wasm_rt_init_wasi(&(sbx->wasi_data)); init_module_starts(); // w2c___wasm_call_ctors(sbx); return sbx; } Loading
third_party/wasm2c/wasm2c/wasm-rt-impl.c +100 −75 Original line number Diff line number Diff line Loading @@ -14,8 +14,8 @@ * limitations under the License. */ #include "wasm-rt.h" #include "wasm-rt-os.h" #include "wasm-rt.h" #include <assert.h> #include <limits.h> Loading @@ -33,8 +33,7 @@ void wasm_rt_trap(wasm_rt_trap_t code) { const char* error_message = "wasm2c: unknown trap"; switch(code) { switch (code) { case WASM_RT_TRAP_NONE: { // this should never happen error_message = "wasm2c: WASM_RT_TRAP_NONE"; Loading Loading @@ -101,7 +100,9 @@ void wasm_rt_trap(wasm_rt_trap_t code) { #endif } void wasm_rt_callback_error_trap(wasm_rt_table_t* table, uint32_t func_index, uint32_t expected_func_type) { void wasm_rt_callback_error_trap(wasm_rt_table_t* table, uint32_t func_index, uint32_t expected_func_type) { if (func_index >= table->size) { wasm_rt_trap(WASM_RT_TRAP_CALL_INDIRECT_OOB_INDEX); } else if (!table->data[func_index].func) { Loading @@ -112,7 +113,6 @@ void wasm_rt_callback_error_trap(wasm_rt_table_t* table, uint32_t func_index, ui wasm_rt_trap(WASM_RT_TRAP_CALL_INDIRECT_UNKNOWN_ERR); } static bool func_types_are_equal(wasm_func_type_t* a, wasm_func_type_t* b) { if (a->param_count != b->param_count || a->result_count != b->result_count) return 0; Loading Loading @@ -170,12 +170,14 @@ uint32_t wasm_rt_register_func_type(wasm_func_type_t** p_func_type_structs, uint32_t idx = (*p_func_type_count)++; // realloc works fine even if *p_func_type_structs is null *p_func_type_structs = realloc(*p_func_type_structs, *p_func_type_count * sizeof(wasm_func_type_t)); *p_func_type_structs = realloc(*p_func_type_structs, *p_func_type_count * sizeof(wasm_func_type_t)); (*p_func_type_structs)[idx] = func_type; return idx + 1; } void wasm_rt_cleanup_func_types(wasm_func_type_t** p_func_type_structs, uint32_t* p_func_type_count) { void wasm_rt_cleanup_func_types(wasm_func_type_t** p_func_type_structs, uint32_t* p_func_type_count) { // Use a u64 to iterate over u32 arrays to prevent infinite loops const uint32_t func_count = *p_func_type_count; for (uint64_t idx = 0; idx < func_count; idx++) { Loading @@ -193,8 +195,7 @@ void wasm_rt_cleanup_func_types(wasm_func_type_t** p_func_type_structs, uint32_t } #if UINTPTR_MAX == 0xffffffff static int is_power_of_two(uint64_t x) { static int is_power_of_two(uint64_t x) { return ((x != 0) && !(x & (x - 1))); } #endif Loading Loading @@ -232,13 +233,23 @@ uint64_t wasm_rt_get_default_max_linear_memory_size() { return ret; } static uint64_t compute_heap_reserve_space(uint32_t chosen_max_pages) { const uint64_t heap_reserve_size = ((uint64_t)chosen_max_pages) * WASM_PAGE_SIZE + WASM_HEAP_GUARD_PAGE_SIZE; return heap_reserve_size; } bool wasm_rt_allocate_memory(wasm_rt_memory_t* memory, uint32_t initial_pages, uint32_t max_pages) { const uint32_t byte_length = initial_pages * WASM_PAGE_SIZE; const uint32_t suggested_max_pages = max_pages == 0? WASM_HEAP_DEFAULT_MAX_PAGES : max_pages; const uint32_t chosen_max_pages = (WASM_HEAP_MAX_ALLOWED_PAGES < suggested_max_pages)? WASM_HEAP_MAX_ALLOWED_PAGES : suggested_max_pages; const uint32_t suggested_max_pages = max_pages == 0 ? WASM_HEAP_DEFAULT_MAX_PAGES : max_pages; const uint32_t chosen_max_pages = (WASM_HEAP_MAX_ALLOWED_PAGES < suggested_max_pages) ? WASM_HEAP_MAX_ALLOWED_PAGES : suggested_max_pages; if (chosen_max_pages < initial_pages) { return false; Loading @@ -246,10 +257,12 @@ bool wasm_rt_allocate_memory(wasm_rt_memory_t* memory, #ifdef WASM_USE_GUARD_PAGES // mmap based heaps with guard pages // Guard pages already allocates memory incrementally thus we don't need to look at WASM_USE_INCREMENTAL_MOVEABLE_MEMORY_ALLOC // Guard pages already allocates memory incrementally thus we don't need to // look at WASM_USE_INCREMENTAL_MOVEABLE_MEMORY_ALLOC void* addr = NULL; const uint64_t retries = 10; const uint64_t heap_reserve_size = ((uint64_t) chosen_max_pages) * WASM_PAGE_SIZE + WASM_HEAP_GUARD_PAGE_SIZE; const uint64_t heap_reserve_size = compute_heap_reserve_space(chosen_max_pages); // 32-bit platforms rely on masking for sandboxing // thus we require the heap reserve size to always be a power of 2 Loading @@ -260,7 +273,9 @@ bool wasm_rt_allocate_memory(wasm_rt_memory_t* memory, #endif for (uint64_t i = 0; i < retries; i++) { addr = os_mmap_aligned(NULL, heap_reserve_size, MMAP_PROT_NONE, MMAP_MAP_NONE, WASM_HEAP_ALIGNMENT, 0 /* alignment_offset */); addr = os_mmap_aligned(NULL, heap_reserve_size, MMAP_PROT_NONE, MMAP_MAP_NONE, WASM_HEAP_ALIGNMENT, 0 /* alignment_offset */); if (addr) { break; } Loading @@ -274,9 +289,11 @@ bool wasm_rt_allocate_memory(wasm_rt_memory_t* memory, if (ret != 0) { return false; } // This is a valid way to initialize a constant field that is not undefined behavior // This is a valid way to initialize a constant field that is not undefined // behavior // https://stackoverflow.com/questions/9691404/how-to-initialize-const-in-a-struct-in-c-with-malloc // Summary: malloc of a struct, followed by a write to the constant fields is still defined behavior iff // Summary: malloc of a struct, followed by a write to the constant fields is // still defined behavior iff // there is no prior read of the field *(uint8_t**)&memory->data = addr; #else Loading Loading @@ -306,7 +323,8 @@ bool wasm_rt_allocate_memory(wasm_rt_memory_t* memory, void wasm_rt_deallocate_memory(wasm_rt_memory_t* memory) { #ifdef WASM_USE_GUARD_PAGES const uint64_t heap_reserve_size = ((uint64_t) memory->max_pages) * WASM_PAGE_SIZE + WASM_HEAP_GUARD_PAGE_SIZE; const uint64_t heap_reserve_size = compute_heap_reserve_space(memory->max_pages); os_munmap(memory->data, heap_reserve_size); #else free(memory->data); Loading @@ -332,12 +350,14 @@ uint32_t wasm_rt_grow_memory(wasm_rt_memory_t* memory, uint32_t delta) { #ifdef WASM_USE_GUARD_PAGES // mmap based heaps with guard pages int ret = os_mmap_commit(memory->data + old_size, delta_size, MMAP_PROT_READ | MMAP_PROT_WRITE); int ret = os_mmap_commit(memory->data + old_size, delta_size, MMAP_PROT_READ | MMAP_PROT_WRITE); if (ret != 0) { return (uint32_t)-1; } #else // malloc based heaps --- if below macro is not defined, the max memory range is already allocated // malloc based heaps --- if below macro is not defined, the max memory range // is already allocated #ifdef WASM_USE_INCREMENTAL_MOVEABLE_MEMORY_ALLOC uint8_t* new_data = realloc(memory->data, new_size); if (new_data == NULL) { Loading Loading @@ -376,7 +396,8 @@ void wasm_rt_deallocate_table(wasm_rt_table_t* table) { free(table->data); } #define WASM_SATURATING_U32_ADD(ret_ptr, a, b) { \ #define WASM_SATURATING_U32_ADD(ret_ptr, a, b) \ { \ if ((a) > (UINT32_MAX - (b))) { \ /* add will overflowed */ \ *ret_ptr = UINT32_MAX; \ Loading @@ -385,7 +406,8 @@ void wasm_rt_deallocate_table(wasm_rt_table_t* table) { } \ } #define WASM_CHECKED_U32_RET_SIZE_T_MULTIPLY(ret_ptr, a, b) { \ #define WASM_CHECKED_U32_RET_SIZE_T_MULTIPLY(ret_ptr, a, b) \ { \ if ((a) > (SIZE_MAX / (b))) { \ /* multiple will overflowed */ \ wasm_rt_trap(WASM_RT_TRAP_CALL_INDIRECT_TABLE_EXPANSION); \ Loading @@ -410,16 +432,19 @@ void wasm_rt_expand_table(wasm_rt_table_t* table) { } size_t allocation_size = 0; WASM_CHECKED_U32_RET_SIZE_T_MULTIPLY(&allocation_size, sizeof(wasm_rt_elem_t), new_size); WASM_CHECKED_U32_RET_SIZE_T_MULTIPLY(&allocation_size, sizeof(wasm_rt_elem_t), new_size); table->data = realloc(table->data, allocation_size); assert(table->data != 0); memset(&(table->data[table->size]), 0, allocation_size - (table->size * sizeof(wasm_rt_elem_t))); memset(&(table->data[table->size]), 0, allocation_size - (table->size * sizeof(wasm_rt_elem_t))); table->size = new_size; } void wasm2c_ensure_linked() { // We use this to ensure the dynamic library with the wasi symbols is loaded for the host application // We use this to ensure the dynamic library with the wasi symbols is loaded // for the host application } #undef WASM_PAGE_SIZE Loading