Skip to content

Commit

Permalink
Bug 1726476 - Update wasm2c_sandbox_compiler. r=shravanrn
Browse files Browse the repository at this point in the history
  • Loading branch information
glandium committed Aug 20, 2021
1 parent 477919f commit 2a24675
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 22 deletions.
4 changes: 2 additions & 2 deletions config/external/wasm2c_sandbox_compiler/moz.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ origin:
description: wasm2c fork used for rlbox sandboxing
url: https://github.com/PLSysSec/wasm2c_sandbox_compiler

release: commit 66768269859ddbd97cf0ccb9e9c26a9ff23fcf8d (2021-08-05T04:41:21Z).
revision: 66768269859ddbd97cf0ccb9e9c26a9ff23fcf8d
release: commit b785706fd885ffb4255639c31249ba7040b3b83f (2021-08-18T21:38:59Z).
revision: b785706fd885ffb4255639c31249ba7040b3b83f

license: Apache-2.0
license-file: LICENSE
Expand Down
77 changes: 68 additions & 9 deletions third_party/wasm2c/src/c-writer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ class CWriter {
std::string GetFuncStaticOrExport(std::string);
void WriteFuncDeclarations();
void WriteFuncDeclaration(const FuncDeclaration&, const std::string&, bool add_storage_class);
void WriteEntryFuncs();
void WriteEntryFunc(const FuncDeclaration&, const std::string&, bool add_storage_class);
void WriteImportFuncDeclaration(const FuncDeclaration&, const std::string&);
std::string GetMainMemoryName();
void WriteGlobalInitializers();
Expand Down Expand Up @@ -933,6 +935,27 @@ void CWriter::WriteFuncDeclarations() {
}
}


void CWriter::WriteEntryFuncs() {
if (module_->funcs.size() == module_->num_func_imports)
return;

Write(Newline());
Write("#if defined(ENTRY_PROLOGUE) || defined(ENTRY_EPILOGUE)", Newline());

Index func_index = 0;
for (const Func* func : module_->funcs) {
bool is_import = func_index < module_->num_func_imports;
if (!is_import) {
WriteEntryFunc(func->decl, GetGlobalName(func->name), true /* add_storage_class */);
Write(Newline());
}
++func_index;
}

Write("#endif", Newline());
}

std::string CWriter::GetFuncStaticOrExport(std::string name) {
std::string static_export_string = "";
if (name.rfind("w2c___", 0) == 0 || name == "w2c_main") {
Expand Down Expand Up @@ -960,6 +983,38 @@ void CWriter::WriteFuncDeclaration(const FuncDeclaration& decl,
Write(")");
}

void CWriter::WriteEntryFunc(const FuncDeclaration& decl,
const std::string& name,
bool add_storage_class) {
// LLVM adds some extra function calls to all wasm objects prefixed with "__".
// Keep this static (private), else we cause symbol collisions when linking multiple wasm modules
// Additionally windows dlls have to export functions explicitly
if (add_storage_class) {
Write(GetFuncStaticOrExport(name));
}
Write(ResultType(decl.sig.result_types), " w2centry_", name, "(wasm2c_sandbox_t* const sbx");
for (Index i = 0; i < decl.GetNumParams(); ++i) {
Write(", ", decl.GetParamType(i), " p", std::to_string(i));
}
Write(") ", OpenBrace());
{
Write("ENTRY_PROLOGUE;", Newline());
if (!decl.sig.result_types.empty()) {
Write(ResultType(decl.sig.result_types), " ret = ");
}
Write(name, "(sbx");
for (Index i = 0; i < decl.GetNumParams(); ++i) {
Write(", p", std::to_string(i));
}
Write(");", Newline());
Write("ENTRY_EPILOGUE;", Newline());
if (!decl.sig.result_types.empty()) {
Write("return ret;", Newline());
}
}
Write(CloseBrace(), Newline());
}

void CWriter::WriteImportFuncDeclaration(const FuncDeclaration& decl,
const std::string& name) {
Write(ResultType(decl.sig.result_types), " ", name, "(void*");
Expand Down Expand Up @@ -1212,8 +1267,8 @@ void CWriter::WriteElemInitializers() {
Index func_type_index = module_->GetFuncTypeIndex(func->decl.type_var);

Write("sbx->",ExternalRef(table->name), ".data[offset + ", i,
"] = (wasm_rt_elem_t){sbx->func_types[", func_type_index,
"], (wasm_rt_anyfunc_t)", ExternalPtr(func->name), "};", Newline());
"] = (wasm_rt_elem_t){ WASM_RT_INTERNAL_FUNCTION, sbx->func_types[", func_type_index,
"], (wasm_rt_anyfunc_t)", ExternalPtr(func->name), " };", Newline());
if (i >= first_unused_elem) {
first_unused_elem = i+1;
}
Expand Down Expand Up @@ -1253,7 +1308,7 @@ void CWriter::WriteFuncIndexLookup() {
void CWriter::WriteCallbackAddRemove() {
const Table* table = module_->tables.empty() ? nullptr : module_->tables[0];

Write(Newline(), "static u32 add_wasm2c_callback(void* sbx_ptr, u32 func_type_idx, void* func_ptr) ", OpenBrace());
Write(Newline(), "static u32 add_wasm2c_callback(void* sbx_ptr, u32 func_type_idx, void* func_ptr, wasm_rt_elem_target_class_t func_class) ", OpenBrace());
{
Write("wasm2c_sandbox_t* const sbx = (wasm2c_sandbox_t* const) sbx_ptr;", Newline());

Expand All @@ -1275,7 +1330,7 @@ void CWriter::WriteCallbackAddRemove() {
Write("if (sbx->", ExternalRef(table->name), ".data[i].func == 0) ", OpenBrace());
{
Write("sbx->",ExternalRef(table->name), ".data[i]",
" = (wasm_rt_elem_t){func_type_idx, ",
" = (wasm_rt_elem_t){ func_class, func_type_idx, ",
"(wasm_rt_anyfunc_t) func_ptr };", Newline());
Write("return i;", Newline());
}
Expand Down Expand Up @@ -1561,18 +1616,21 @@ void CWriter::Write(const ExprList& exprs) {
Index num_params = decl.GetNumParams();
Index num_results = decl.GetNumResults();
assert(type_stack_.size() > num_params);
if (num_results > 0) {
assert(num_results == 1);
Write(StackVar(num_params, decl.GetResultType(0)), " = ");
}

assert(module_->tables.size() == 1);
const Table* table = module_->tables[0];

assert(decl.has_func_type);
Index func_type_index = module_->GetFuncTypeIndex(decl.type_var);

Write("CALL_INDIRECT(sbx->", ExternalRef(table->name), ", ");
if (num_results > 0) {
assert(num_results == 1);
Write("CALL_INDIRECT_RES(", StackVar(num_params, decl.GetResultType(0)), ", ");
} else {
Write("CALL_INDIRECT_VOID(");
}

Write("sbx->", ExternalRef(table->name), ", ");
WriteFuncDeclaration(decl, "(*)", false /* add_storage_class*/);
Write(", ", func_type_index, ", ", StackVar(0));
Write(", sbx->func_types, sbx");
Expand Down Expand Up @@ -2420,6 +2478,7 @@ void CWriter::WriteCSource() {
WriteSandboxStruct();
WriteFuncTypes();
WriteFuncDeclarations();
WriteEntryFuncs();
WriteGlobalInitializers();
WriteFuncs();
WriteDataInitializers();
Expand Down
43 changes: 38 additions & 5 deletions third_party/wasm2c/src/prebuilt/wasm2c.include.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,51 @@ const char SECTION_NAME(declarations)[] =
"\n"
"#define TRAP(x) (wasm_rt_trap(WASM_RT_TRAP_##x), 0)\n"
"\n"
"#ifndef FUNC_PROLOGUE\n"
"#define FUNC_PROLOGUE\n"
"#endif\n"
"\n"
"#ifndef FUNC_EPILOGUE\n"
"#define FUNC_EPILOGUE\n"
"#endif\n"
"\n"
"#ifdef EXTERNAL_CALLBACK_PROLOGUE\n"
"#define EXTERNAL_CALLBACK_PROLOGUE_EXEC(table, x) \\\n"
" if (UNLIKELY(table.data[x].func_class == WASM_RT_EXTERNAL_FUNCTION)) { \\\n"
" EXTERNAL_CALLBACK_PROLOGUE; \\\n"
" }\n"
"#else\n"
"#define EXTERNAL_CALLBACK_PROLOGUE_EXEC(table, x)\n"
"#endif\n"
"\n"
"#ifdef EXTERNAL_CALLBACK_EPILOGUE\n"
"#define EXTERNAL_CALLBACK_EPILOGUE_EXEC(table, x) \\\n"
" if (UNLIKELY(table.data[x].func_class == WASM_RT_EXTERNAL_FUNCTION)) { \\\n"
" EXTERNAL_CALLBACK_EPILOGUE; \\\n"
" }\n"
"#else\n"
"#define EXTERNAL_CALLBACK_EPILOGUE_EXEC(table, x)\n"
"#endif\n"
"\n"
"#define UNREACHABLE (void) TRAP(UNREACHABLE)\n"
"\n"
"#define CALL_INDIRECT(table, t, ft, x, func_types, ...) \\\n"
" (LIKELY((x) < table.size && table.data[x].func && \\\n"
" table.data[x].func_type == func_types[ft]) \\\n"
" ? ((t)table.data[x].func)(__VA_ARGS__) \\\n"
" : TRAP(CALL_INDIRECT))\n"
"#define CALL_INDIRECT_VOID(table, t, ft, x, func_types, ...) \\\n"
" if (LIKELY((x) < table.size && table.data[x].func && table.data[x].func_type == func_types[ft])) { \\\n"
" EXTERNAL_CALLBACK_PROLOGUE_EXEC(table, x); \\\n"
" ((t)table.data[x].func)(__VA_ARGS__); \\\n"
" EXTERNAL_CALLBACK_EPILOGUE_EXEC(table, x); \\\n"
" } else { \\\n"
" (void) TRAP(CALL_INDIRECT); \\\n"
" }\n"
"\n"
"#define CALL_INDIRECT_RES(res, table, t, ft, x, func_types, ...) \\\n"
" if (LIKELY((x) < table.size && table.data[x].func && table.data[x].func_type == func_types[ft])) { \\\n"
" EXTERNAL_CALLBACK_PROLOGUE_EXEC(table, x); \\\n"
" res = ((t)table.data[x].func)(__VA_ARGS__); \\\n"
" EXTERNAL_CALLBACK_EPILOGUE_EXEC(table, x); \\\n"
" } else { \\\n"
" (void) TRAP(CALL_INDIRECT); \\\n"
" }\n"
"\n"
"#if defined(WASM_CHECK_SHADOW_MEMORY)\n"
"# define WASM2C_SHADOW_MEMORY_LOAD(mem, func_name, ptr, ptr_size) wasm2c_shadow_memory_load(mem, func_name, ptr, ptr_size)\n"
Expand Down
43 changes: 38 additions & 5 deletions third_party/wasm2c/src/wasm2c.c.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,51 @@

#define TRAP(x) (wasm_rt_trap(WASM_RT_TRAP_##x), 0)

#ifndef FUNC_PROLOGUE
#define FUNC_PROLOGUE
#endif

#ifndef FUNC_EPILOGUE
#define FUNC_EPILOGUE
#endif

#ifdef EXTERNAL_CALLBACK_PROLOGUE
#define EXTERNAL_CALLBACK_PROLOGUE_EXEC(table, x) \
if (UNLIKELY(table.data[x].func_class == WASM_RT_EXTERNAL_FUNCTION)) { \
EXTERNAL_CALLBACK_PROLOGUE; \
}
#else
#define EXTERNAL_CALLBACK_PROLOGUE_EXEC(table, x)
#endif

#ifdef EXTERNAL_CALLBACK_EPILOGUE
#define EXTERNAL_CALLBACK_EPILOGUE_EXEC(table, x) \
if (UNLIKELY(table.data[x].func_class == WASM_RT_EXTERNAL_FUNCTION)) { \
EXTERNAL_CALLBACK_EPILOGUE; \
}
#else
#define EXTERNAL_CALLBACK_EPILOGUE_EXEC(table, x)
#endif

#define UNREACHABLE (void) TRAP(UNREACHABLE)

#define CALL_INDIRECT(table, t, ft, x, func_types, ...) \
(LIKELY((x) < table.size && table.data[x].func && \
table.data[x].func_type == func_types[ft]) \
? ((t)table.data[x].func)(__VA_ARGS__) \
: TRAP(CALL_INDIRECT))
#define CALL_INDIRECT_VOID(table, t, ft, x, func_types, ...) \
if (LIKELY((x) < table.size && table.data[x].func && table.data[x].func_type == func_types[ft])) { \
EXTERNAL_CALLBACK_PROLOGUE_EXEC(table, x); \
((t)table.data[x].func)(__VA_ARGS__); \
EXTERNAL_CALLBACK_EPILOGUE_EXEC(table, x); \
} else { \
(void) TRAP(CALL_INDIRECT); \
}

#define CALL_INDIRECT_RES(res, table, t, ft, x, func_types, ...) \
if (LIKELY((x) < table.size && table.data[x].func && table.data[x].func_type == func_types[ft])) { \
EXTERNAL_CALLBACK_PROLOGUE_EXEC(table, x); \
res = ((t)table.data[x].func)(__VA_ARGS__); \
EXTERNAL_CALLBACK_EPILOGUE_EXEC(table, x); \
} else { \
(void) TRAP(CALL_INDIRECT); \
}

#if defined(WASM_CHECK_SHADOW_MEMORY)
# define WASM2C_SHADOW_MEMORY_LOAD(mem, func_name, ptr, ptr_size) wasm2c_shadow_memory_load(mem, func_name, ptr, ptr_size)
Expand Down
2 changes: 2 additions & 0 deletions third_party/wasm2c/wasm2c/wasm-rt-runner.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@

#if defined(_WIN32)
// Ensure the min/max macro in the header doesn't collide with functions in std::
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <Windows.h>
#define LINETERM "\r\n"
#else
Expand Down
11 changes: 10 additions & 1 deletion third_party/wasm2c/wasm2c/wasm-rt.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,17 @@ typedef enum {
* call. */
typedef void (*wasm_rt_anyfunc_t)(void);

/**
* The class of the indirect function being invoked
*/
typedef enum {
WASM_RT_INTERNAL_FUNCTION,
WASM_RT_EXTERNAL_FUNCTION
} wasm_rt_elem_target_class_t;

/** A single element of a Table. */
typedef struct {
wasm_rt_elem_target_class_t func_class;
/** The index as returned from `wasm_rt_register_func_type`. */
uint32_t func_type;
/** The function. The embedder must know the actual C signature of the
Expand Down Expand Up @@ -168,7 +177,7 @@ typedef void* (*create_wasm2c_sandbox_t)(void);
typedef void (*destroy_wasm2c_sandbox_t)(void* sbx_ptr);
typedef void* (*lookup_wasm2c_nonfunc_export_t)(void* sbx_ptr, const char* name);
typedef uint32_t (*lookup_wasm2c_func_index_t)(void* sbx_ptr, uint32_t param_count, uint32_t result_count, wasm_rt_type_t* types);
typedef uint32_t (*add_wasm2c_callback_t)(void* sbx_ptr, uint32_t func_type_idx, void* func_ptr);
typedef uint32_t (*add_wasm2c_callback_t)(void* sbx_ptr, uint32_t func_type_idx, void* func_ptr, wasm_rt_elem_target_class_t func_class);
typedef void (*remove_wasm2c_callback_t)(void* sbx_ptr, uint32_t callback_idx);

typedef struct wasm2c_sandbox_funcs_t {
Expand Down

0 comments on commit 2a24675

Please sign in to comment.