Commit c6096413 authored by Shravan Narayan's avatar Shravan Narayan
Browse files

Bug 1793734 - update wasm2c to fix wasi stub definitions r=glandium

parent 6d90306d
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -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
@@ -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
+23 −6
Original line number Diff line number Diff line
@@ -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);
@@ -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);
@@ -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_;
@@ -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) {
@@ -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));
}
@@ -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) {
@@ -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;
@@ -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());
@@ -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());
      }
@@ -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") {
@@ -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));
        }
+9 −0
Original line number Diff line number Diff line
@@ -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"
@@ -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"
@@ -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"
@@ -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"
+9 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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;                                                                 \
  }

@@ -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;                                                          \
  }

@@ -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;
}

+100 −75
Original line number Diff line number Diff line
@@ -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>
@@ -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";
@@ -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) {
@@ -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;
@@ -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++) {
@@ -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
@@ -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;
@@ -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
@@ -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;
    }
@@ -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
@@ -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);
@@ -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) {
@@ -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;                   \
@@ -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); \
@@ -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