зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1723447 - Get latest rlbox, wasm2c plugin, rt, compiler for 32bit platform support r=glandium
Differential Revision: https://phabricator.services.mozilla.com/D121503
This commit is contained in:
Родитель
f1aac2b3e6
Коммит
ac42d89404
|
@ -9,8 +9,8 @@ origin:
|
|||
description: rlbox integration for the wasm2c sandboxed code
|
||||
url: https://github.com/PLSysSec/rlbox_wasm2c_sandbox
|
||||
|
||||
release: commit 1cd3e4165d30d3ecc30974744e6fd52caa2a3f1d (2021-07-23T02:53:22Z).
|
||||
revision: 1cd3e4165d30d3ecc30974744e6fd52caa2a3f1d
|
||||
release: commit e92b497df1ee919182a95433c477f4998ca451bb (2021-07-31T07:25:03Z).
|
||||
revision: e92b497df1ee919182a95433c477f4998ca451bb
|
||||
|
||||
license: MIT
|
||||
license-file: LICENSE
|
||||
|
|
|
@ -9,8 +9,8 @@ origin:
|
|||
description: wasm2c fork used for rlbox sandboxing
|
||||
url: https://github.com/PLSysSec/wasm2c_sandbox_compiler
|
||||
|
||||
release: commit df7630a80686c1e3bc775a6cb261841e99484b54 (2021-07-28T00:22:29Z).
|
||||
revision: df7630a80686c1e3bc775a6cb261841e99484b54
|
||||
release: commit 8b0e6e8c96d534698bf8c2cf0c860883ec2b7d34 (2021-08-04T21:00:09Z).
|
||||
revision: 8b0e6e8c96d534698bf8c2cf0c860883ec2b7d34
|
||||
|
||||
license: Apache-2.0
|
||||
license-file: LICENSE
|
||||
|
|
|
@ -397,7 +397,7 @@ protected:
|
|||
detail::dynamic_check(sandbox == nullptr, "Sandbox already initialized");
|
||||
|
||||
#if defined(_WIN32)
|
||||
library = LoadLibraryA(wasm2c_module_path);
|
||||
library = (void*) LoadLibraryA(wasm2c_module_path);
|
||||
#else
|
||||
library = dlopen(wasm2c_module_path, RTLD_LAZY);
|
||||
#endif
|
||||
|
@ -439,16 +439,16 @@ protected:
|
|||
detail::dynamic_check(sandbox_memory_info != nullptr, "Could not get wasm2c sandbox memory info");
|
||||
|
||||
heap_base = reinterpret_cast<uintptr_t>(impl_get_memory_location());
|
||||
// Check that the address space is larger than the sandbox heap i.e. 4GB
|
||||
// sandbox heap, host has to have more than 4GB
|
||||
static_assert(sizeof(uintptr_t) > sizeof(T_PointerType));
|
||||
// Check that the heap is aligned to the pointer size i.e. 32-bit pointer =>
|
||||
// aligned to 4GB. The implementations of
|
||||
// impl_get_unsandboxed_pointer_no_ctx and impl_get_sandboxed_pointer_no_ctx
|
||||
// below rely on this.
|
||||
uintptr_t heap_offset_mask = std::numeric_limits<T_PointerType>::max();
|
||||
detail::dynamic_check((heap_base & heap_offset_mask) == 0,
|
||||
"Sandbox heap not aligned to 4GB");
|
||||
|
||||
if constexpr (sizeof(uintptr_t) != sizeof(uint32_t)) {
|
||||
// On larger platforms, check that the heap is aligned to the pointer size
|
||||
// i.e. 32-bit pointer => aligned to 4GB. The implementations of
|
||||
// impl_get_unsandboxed_pointer_no_ctx and impl_get_sandboxed_pointer_no_ctx
|
||||
// below rely on this.
|
||||
uintptr_t heap_offset_mask = std::numeric_limits<T_PointerType>::max();
|
||||
detail::dynamic_check((heap_base & heap_offset_mask) == 0,
|
||||
"Sandbox heap not aligned to 4GB");
|
||||
}
|
||||
|
||||
// cache these for performance
|
||||
exec_env = sandbox;
|
||||
|
@ -509,7 +509,11 @@ protected:
|
|||
}
|
||||
return static_cast<T_PointerType>(slot_number);
|
||||
} else {
|
||||
return static_cast<T_PointerType>(reinterpret_cast<uintptr_t>(p));
|
||||
if constexpr (sizeof(uintptr_t) == sizeof(uint32_t)) {
|
||||
return static_cast<T_PointerType>(reinterpret_cast<uintptr_t>(p) - heap_base);
|
||||
} else {
|
||||
return static_cast<T_PointerType>(reinterpret_cast<uintptr_t>(p));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -520,20 +524,26 @@ protected:
|
|||
rlbox_wasm2c_sandbox* (*expensive_sandbox_finder)(
|
||||
const void* example_unsandboxed_ptr))
|
||||
{
|
||||
if constexpr (std::is_function_v<std::remove_pointer_t<T>>) {
|
||||
// swizzling function pointers needs access to the function pointer tables
|
||||
// and thus cannot be done without context
|
||||
// on 32-bit platforms we don't assume the heap is aligned
|
||||
if constexpr (sizeof(uintptr_t) == sizeof(uint32_t)) {
|
||||
auto sandbox = expensive_sandbox_finder(example_unsandboxed_ptr);
|
||||
return sandbox->impl_get_unsandboxed_pointer<T>(p);
|
||||
} else {
|
||||
// grab the memory base from the example_unsandboxed_ptr
|
||||
uintptr_t heap_base_mask =
|
||||
std::numeric_limits<uintptr_t>::max() &
|
||||
~(static_cast<uintptr_t>(std::numeric_limits<T_PointerType>::max()));
|
||||
uintptr_t computed_heap_base =
|
||||
reinterpret_cast<uintptr_t>(example_unsandboxed_ptr) & heap_base_mask;
|
||||
uintptr_t ret = computed_heap_base | p;
|
||||
return reinterpret_cast<void*>(ret);
|
||||
if constexpr (std::is_function_v<std::remove_pointer_t<T>>) {
|
||||
// swizzling function pointers needs access to the function pointer tables
|
||||
// and thus cannot be done without context
|
||||
auto sandbox = expensive_sandbox_finder(example_unsandboxed_ptr);
|
||||
return sandbox->impl_get_unsandboxed_pointer<T>(p);
|
||||
} else {
|
||||
// grab the memory base from the example_unsandboxed_ptr
|
||||
uintptr_t heap_base_mask =
|
||||
std::numeric_limits<uintptr_t>::max() &
|
||||
~(static_cast<uintptr_t>(std::numeric_limits<T_PointerType>::max()));
|
||||
uintptr_t computed_heap_base =
|
||||
reinterpret_cast<uintptr_t>(example_unsandboxed_ptr) & heap_base_mask;
|
||||
uintptr_t ret = computed_heap_base | p;
|
||||
return reinterpret_cast<void*>(ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -544,17 +554,23 @@ protected:
|
|||
rlbox_wasm2c_sandbox* (*expensive_sandbox_finder)(
|
||||
const void* example_unsandboxed_ptr))
|
||||
{
|
||||
if constexpr (std::is_function_v<std::remove_pointer_t<T>>) {
|
||||
// swizzling function pointers needs access to the function pointer tables
|
||||
// and thus cannot be done without context
|
||||
// on 32-bit platforms we don't assume the heap is aligned
|
||||
if constexpr (sizeof(uintptr_t) == sizeof(uint32_t)) {
|
||||
auto sandbox = expensive_sandbox_finder(example_unsandboxed_ptr);
|
||||
return sandbox->impl_get_sandboxed_pointer<T>(p);
|
||||
} else {
|
||||
// Just clear the memory base to leave the offset
|
||||
RLBOX_WASM2C_UNUSED(example_unsandboxed_ptr);
|
||||
uintptr_t ret = reinterpret_cast<uintptr_t>(p) &
|
||||
std::numeric_limits<T_PointerType>::max();
|
||||
return static_cast<T_PointerType>(ret);
|
||||
if constexpr (std::is_function_v<std::remove_pointer_t<T>>) {
|
||||
// swizzling function pointers needs access to the function pointer tables
|
||||
// and thus cannot be done without context
|
||||
auto sandbox = expensive_sandbox_finder(example_unsandboxed_ptr);
|
||||
return sandbox->impl_get_sandboxed_pointer<T>(p);
|
||||
} else {
|
||||
// Just clear the memory base to leave the offset
|
||||
RLBOX_WASM2C_UNUSED(example_unsandboxed_ptr);
|
||||
uintptr_t ret = reinterpret_cast<uintptr_t>(p) &
|
||||
std::numeric_limits<T_PointerType>::max();
|
||||
return static_cast<T_PointerType>(ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -580,7 +596,7 @@ protected:
|
|||
|
||||
inline size_t impl_get_total_memory() { return sandbox_memory_info->size; }
|
||||
|
||||
inline void* impl_get_memory_location()
|
||||
inline void* impl_get_memory_location() const
|
||||
{
|
||||
return sandbox_memory_info->data;
|
||||
}
|
||||
|
@ -695,8 +711,10 @@ protected:
|
|||
|
||||
inline T_PointerType impl_malloc_in_sandbox(size_t size)
|
||||
{
|
||||
detail::dynamic_check(size <= std::numeric_limits<uint32_t>::max(),
|
||||
"Attempting to malloc more than the heap size");
|
||||
if constexpr(sizeof(size) > sizeof(uint32_t)) {
|
||||
detail::dynamic_check(size <= std::numeric_limits<uint32_t>::max(),
|
||||
"Attempting to malloc more than the heap size");
|
||||
}
|
||||
using T_Func = void*(size_t);
|
||||
using T_Converted = T_PointerType(uint32_t);
|
||||
T_PointerType ret = impl_invoke_with_func_ptr<T_Func, T_Converted>(
|
||||
|
|
|
@ -159,7 +159,6 @@ class CWriter {
|
|||
void PopLabel();
|
||||
|
||||
static std::string AddressOf(const std::string&);
|
||||
static std::string Deref(const std::string&);
|
||||
|
||||
static char MangleType(Type);
|
||||
static std::string MangleTypes(const TypeVector&);
|
||||
|
@ -382,11 +381,6 @@ std::string CWriter::AddressOf(const std::string& s) {
|
|||
return "(&" + s + ")";
|
||||
}
|
||||
|
||||
// static
|
||||
std::string CWriter::Deref(const std::string& s) {
|
||||
return "(*" + s + ")";
|
||||
}
|
||||
|
||||
// static
|
||||
char CWriter::MangleType(Type type) {
|
||||
switch (type) {
|
||||
|
@ -489,7 +483,7 @@ std::string CWriter::DefineImportName(const std::string& name,
|
|||
import_syms_.insert(name);
|
||||
global_syms_.insert(mangled);
|
||||
global_sym_map_.insert(SymbolMap::value_type(name, mangled));
|
||||
return "(*" + mangled + ")";
|
||||
return mangled;
|
||||
}
|
||||
|
||||
std::string CWriter::DefineGlobalScopeName(const std::string& name) {
|
||||
|
@ -600,12 +594,7 @@ void CWriter::Write(const ExternalPtr& name) {
|
|||
}
|
||||
|
||||
void CWriter::Write(const ExternalRef& name) {
|
||||
bool is_import = import_syms_.count(name.name) != 0;
|
||||
if (is_import) {
|
||||
Write(Deref(GetGlobalName(name.name)));
|
||||
} else {
|
||||
Write(GetGlobalName(name.name));
|
||||
}
|
||||
Write(GetGlobalName(name.name));
|
||||
}
|
||||
|
||||
void CWriter::Write(const Var& var) {
|
||||
|
|
|
@ -50,7 +50,7 @@ const char SECTION_NAME(declarations)[] =
|
|||
"#define MEMCHECK(mem, a, t)\n"
|
||||
"#else\n"
|
||||
"#define MEMCHECK(mem, a, t) \\\n"
|
||||
" if (UNLIKELY((a) + sizeof(t) > mem->size)) TRAP(OOB)\n"
|
||||
" if (UNLIKELY((a) + sizeof(t) > mem->size)) (void) TRAP(OOB)\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"#if defined(WASM_USING_GLOBAL_HEAP)\n"
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
#define MEMCHECK(mem, a, t)
|
||||
#else
|
||||
#define MEMCHECK(mem, a, t) \
|
||||
if (UNLIKELY((a) + sizeof(t) > mem->size)) TRAP(OOB)
|
||||
if (UNLIKELY((a) + sizeof(t) > mem->size)) (void) TRAP(OOB)
|
||||
#endif
|
||||
|
||||
#if defined(WASM_USING_GLOBAL_HEAP)
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define PAGE_SIZE 65536
|
||||
#define WASM_PAGE_SIZE 65536
|
||||
|
||||
void wasm_rt_trap(wasm_rt_trap_t code) {
|
||||
assert(code != WASM_RT_TRAP_NONE);
|
||||
|
@ -99,15 +99,28 @@ void wasm_rt_cleanup_func_types(wasm_func_type_t** p_func_type_structs, uint32_t
|
|||
void wasm_rt_allocate_memory(wasm_rt_memory_t* memory,
|
||||
uint32_t initial_pages,
|
||||
uint32_t max_pages) {
|
||||
uint32_t byte_length = initial_pages * PAGE_SIZE;
|
||||
uint32_t byte_length = initial_pages * WASM_PAGE_SIZE;
|
||||
#if WASM_USING_GUARD_PAGES == 1
|
||||
/* Reserve 8GiB. */
|
||||
const uint64_t heap_alignment = 0x100000000ul;
|
||||
/* Reserve 8GiB, aligned to 4GB. */
|
||||
const size_t heap_alignment = 0x100000000ull;
|
||||
const size_t reserve_size = 0x200000000ull;
|
||||
const uint32_t chosen_max_pages = max_pages;
|
||||
#else
|
||||
/* Reserve 8MB, aligned to 8MB. */
|
||||
const size_t heap_alignment = 0x800000ul;
|
||||
const size_t reserve_size = 0x800000ul;
|
||||
const uint32_t allowed_max_pages = reserve_size / WASM_PAGE_SIZE;
|
||||
uint32_t chosen_max_pages = max_pages;
|
||||
if (allowed_max_pages < max_pages) {
|
||||
chosen_max_pages = allowed_max_pages;
|
||||
}
|
||||
#endif
|
||||
|
||||
void* addr = NULL;
|
||||
const uint64_t retries = 10;
|
||||
|
||||
for (uint64_t i = 0; i < retries; i++) {
|
||||
addr = os_mmap_aligned(NULL, 0x200000000ul, MMAP_PROT_NONE, MMAP_MAP_NONE, heap_alignment, 0 /* alignment_offset */);
|
||||
addr = os_mmap_aligned(NULL, reserve_size, MMAP_PROT_NONE, MMAP_MAP_NONE, heap_alignment, 0 /* alignment_offset */);
|
||||
if (addr) {
|
||||
break;
|
||||
}
|
||||
|
@ -126,12 +139,10 @@ void wasm_rt_allocate_memory(wasm_rt_memory_t* memory,
|
|||
// 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
|
||||
memory->data = calloc(byte_length, 1);
|
||||
#endif
|
||||
|
||||
memory->size = byte_length;
|
||||
memory->pages = initial_pages;
|
||||
memory->max_pages = max_pages;
|
||||
memory->max_pages = chosen_max_pages;
|
||||
|
||||
#if defined(WASM_CHECK_SHADOW_MEMORY)
|
||||
wasm2c_shadow_memory_create(memory);
|
||||
|
@ -140,10 +151,12 @@ void wasm_rt_allocate_memory(wasm_rt_memory_t* memory,
|
|||
|
||||
void wasm_rt_deallocate_memory(wasm_rt_memory_t* memory) {
|
||||
#if WASM_USING_GUARD_PAGES == 1
|
||||
os_munmap(memory->data, 0x200000000ul);
|
||||
const size_t reserve_size = 0x200000000ull;
|
||||
#else
|
||||
os_munmap(memory->data, memory->size);
|
||||
const size_t reserve_size = 0x800000ul;
|
||||
#endif
|
||||
os_munmap(memory->data, reserve_size);
|
||||
|
||||
#if defined(WASM_CHECK_SHADOW_MEMORY)
|
||||
wasm2c_shadow_memory_destroy(memory);
|
||||
#endif
|
||||
|
@ -158,25 +171,14 @@ uint32_t wasm_rt_grow_memory(wasm_rt_memory_t* memory, uint32_t delta) {
|
|||
if (new_pages < old_pages || new_pages > memory->max_pages) {
|
||||
return (uint32_t)-1;
|
||||
}
|
||||
uint32_t old_size = old_pages * PAGE_SIZE;
|
||||
uint32_t new_size = new_pages * PAGE_SIZE;
|
||||
uint32_t delta_size = delta * PAGE_SIZE;
|
||||
uint32_t old_size = old_pages * WASM_PAGE_SIZE;
|
||||
uint32_t new_size = new_pages * WASM_PAGE_SIZE;
|
||||
uint32_t delta_size = delta * WASM_PAGE_SIZE;
|
||||
|
||||
#if WASM_USING_GUARD_PAGES == 1
|
||||
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
|
||||
uint8_t* new_data = realloc(memory->data, new_size);
|
||||
if (new_data == NULL) {
|
||||
return (uint32_t)-1;
|
||||
}
|
||||
#if !WABT_BIG_ENDIAN
|
||||
memset(new_data + old_size, 0, delta_size);
|
||||
#endif
|
||||
memory->data = new_data;
|
||||
#endif
|
||||
|
||||
#if WABT_BIG_ENDIAN
|
||||
memmove(memory->data + new_size - old_size, memory->data, old_size);
|
||||
|
@ -250,4 +252,4 @@ void wasm2c_ensure_linked() {
|
|||
// We use this to ensure the dynamic library with the wasi symbols is loaded for the host application
|
||||
}
|
||||
|
||||
#undef PAGE_SIZE
|
||||
#undef WASM_PAGE_SIZE
|
||||
|
|
|
@ -140,14 +140,11 @@ DEFINE_WASI_STORE(wasm_i64_store32, u32, u64);
|
|||
#define VERBOSE_LOG(...)
|
||||
#endif
|
||||
|
||||
#define IMPORT_IMPL(ret, name, params, body) \
|
||||
static ret _##name params { \
|
||||
VERBOSE_LOG("[import: " #name "]\n"); \
|
||||
body \
|
||||
} \
|
||||
ret (*name) params = _##name
|
||||
|
||||
#define STUB_IMPORT_IMPL(ret, name, params, returncode) IMPORT_IMPL(ret, name, params, { return returncode; })
|
||||
#define STUB_IMPORT_IMPL(ret, name, params, returncode) \
|
||||
ret name params { \
|
||||
VERBOSE_LOG("[stub import: " #name "]\n"); \
|
||||
return returncode; \
|
||||
}
|
||||
|
||||
// Generic abort method for a runtime error in the runtime.
|
||||
|
||||
|
@ -159,21 +156,21 @@ static void abort_with_message(const char* message) {
|
|||
/////////////////////////////////////////// Emscripten runtime ///////////////////////////////////////////////
|
||||
|
||||
// Setjmp/longjmp are not currently supported safely. So lonjmp with abort, setjmp can be a noop.
|
||||
IMPORT_IMPL(void, Z_envZ_emscripten_longjmpZ_vii, (wasm_sandbox_wasi_data* wasi_data, u32 buf, u32 value), {
|
||||
void Z_envZ_emscripten_longjmpZ_vii(wasm_sandbox_wasi_data* wasi_data, u32 buf, u32 value) {
|
||||
abort_with_message("longjmp not supported");
|
||||
});
|
||||
}
|
||||
|
||||
STUB_IMPORT_IMPL(u32, Z_envZ_emscripten_setjmpZ_ii, (wasm_sandbox_wasi_data* wasi_data, u32 buf), 0);
|
||||
|
||||
IMPORT_IMPL(void, Z_envZ_emscripten_notify_memory_growthZ_vi, (wasm_sandbox_wasi_data* wasi_data, u32 size), {});
|
||||
void Z_envZ_emscripten_notify_memory_growthZ_vi(wasm_sandbox_wasi_data* wasi_data, u32 size) {}
|
||||
|
||||
IMPORT_IMPL(u32, Z_envZ_getTempRet0Z_iv, (wasm_sandbox_wasi_data* wasi_data), {
|
||||
u32 Z_envZ_getTempRet0Z_iv(wasm_sandbox_wasi_data* wasi_data) {
|
||||
return wasi_data->tempRet0;
|
||||
});
|
||||
}
|
||||
|
||||
IMPORT_IMPL(void, Z_envZ_setTempRet0Z_vi, (wasm_sandbox_wasi_data* wasi_data, u32 x), {
|
||||
void Z_envZ_setTempRet0Z_vi(wasm_sandbox_wasi_data* wasi_data, u32 x) {
|
||||
wasi_data->tempRet0 = x;
|
||||
});
|
||||
}
|
||||
|
||||
static const char* get_null_file_path()
|
||||
{
|
||||
|
@ -318,7 +315,7 @@ static int get_native_fd(wasm_sandbox_wasi_data* wasi_data, u32 fd) {
|
|||
return wasi_data->wasm_fd_to_native[fd];
|
||||
}
|
||||
|
||||
IMPORT_IMPL(u32, Z_envZ___sys_accessZ_iii, (wasm_sandbox_wasi_data* wasi_data, u32 pathname, u32 mode), {
|
||||
u32 Z_envZ___sys_accessZ_iii(wasm_sandbox_wasi_data* wasi_data, u32 pathname, u32 mode) {
|
||||
VERBOSE_LOG(" access: %s 0x%x\n", MEMACCESS(wasi_data->heap_memory, pathname), mode);
|
||||
|
||||
// only permit access checks on the the null file
|
||||
|
@ -335,10 +332,9 @@ IMPORT_IMPL(u32, Z_envZ___sys_accessZ_iii, (wasm_sandbox_wasi_data* wasi_data, u
|
|||
return EM_EACCES;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
IMPORT_IMPL(u32, Z_envZ___sys_openZ_iiii, (wasm_sandbox_wasi_data* wasi_data, u32 path, u32 flags, u32 varargs), {
|
||||
u32 Z_envZ___sys_openZ_iiii(wasm_sandbox_wasi_data* wasi_data, u32 path, u32 flags, u32 varargs) {
|
||||
VERBOSE_LOG(" open: %s %d\n", MEMACCESS(wasi_data->heap_memory, path), flags);
|
||||
|
||||
// only permit opening the null file
|
||||
|
@ -359,18 +355,18 @@ IMPORT_IMPL(u32, Z_envZ___sys_openZ_iiii, (wasm_sandbox_wasi_data* wasi_data, u3
|
|||
return fd;
|
||||
}
|
||||
return -1;
|
||||
});
|
||||
}
|
||||
|
||||
IMPORT_IMPL(u32, Z_envZ___sys_fstat64Z_iii, (wasm_sandbox_wasi_data* wasi_data, u32 fd, u32 buf), {
|
||||
u32 Z_envZ___sys_fstat64Z_iii(wasm_sandbox_wasi_data* wasi_data, u32 fd, u32 buf) {
|
||||
int nfd = get_native_fd(wasi_data, fd);
|
||||
VERBOSE_LOG(" fstat64 %d (=> %d) %d\n", fd, nfd, buf);
|
||||
if (nfd < 0) {
|
||||
return EM_EACCES;
|
||||
}
|
||||
return do_stat(wasi_data, nfd, buf);
|
||||
});
|
||||
}
|
||||
|
||||
IMPORT_IMPL(u32, Z_envZ___sys_stat64Z_iii, (wasm_sandbox_wasi_data* wasi_data, u32 path, u32 buf), {
|
||||
u32 Z_envZ___sys_stat64Z_iii(wasm_sandbox_wasi_data* wasi_data, u32 path, u32 buf) {
|
||||
VERBOSE_LOG(" stat64: %s\n", MEMACCESS(wasi_data->heap_memory, path));
|
||||
int fd = Z_envZ___sys_openZ_iiii(wasi_data, path, 0 /* read_only */, 0);
|
||||
int nfd = get_native_fd(wasi_data, fd);
|
||||
|
@ -379,9 +375,9 @@ IMPORT_IMPL(u32, Z_envZ___sys_stat64Z_iii, (wasm_sandbox_wasi_data* wasi_data, u
|
|||
return EM_EACCES;
|
||||
}
|
||||
return do_stat(wasi_data, nfd, buf);
|
||||
});
|
||||
}
|
||||
|
||||
IMPORT_IMPL(u32, Z_envZ___sys_readZ_iiii, (wasm_sandbox_wasi_data* wasi_data, u32 fd, u32 buf, u32 count), {
|
||||
u32 Z_envZ___sys_readZ_iiii(wasm_sandbox_wasi_data* wasi_data, u32 fd, u32 buf, u32 count) {
|
||||
int nfd = get_native_fd(wasi_data, fd);
|
||||
VERBOSE_LOG(" read %d (=> %d) %d %d\n", fd, nfd, buf, count);
|
||||
if (nfd < 0) {
|
||||
|
@ -399,7 +395,7 @@ IMPORT_IMPL(u32, Z_envZ___sys_readZ_iiii, (wasm_sandbox_wasi_data* wasi_data, u3
|
|||
return EM_EACCES;
|
||||
}
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
STUB_IMPORT_IMPL(u32, Z_envZ_dlopenZ_iii, (wasm_sandbox_wasi_data* wasi_data, u32 a, u32 b), 1);
|
||||
|
@ -536,7 +532,7 @@ STUB_IMPORT_IMPL(u32, Z_wasi_snapshot_preview1Z_sock_shutdownZ_iii, (u32 a, u32
|
|||
|
||||
// Original file: Modified emscripten/tools/wasm2c/main.c
|
||||
|
||||
IMPORT_IMPL(u32, Z_wasi_snapshot_preview1Z_args_getZ_iii, (wasm_sandbox_wasi_data* wasi_data, u32 argv, u32 argv_buf), {
|
||||
u32 Z_wasi_snapshot_preview1Z_args_getZ_iii(wasm_sandbox_wasi_data* wasi_data, u32 argv, u32 argv_buf) {
|
||||
u32 buf_size = 0;
|
||||
for (u32 i = 0; i < wasi_data->main_argc; i++) {
|
||||
u32 ptr = argv_buf + buf_size;
|
||||
|
@ -554,9 +550,9 @@ IMPORT_IMPL(u32, Z_wasi_snapshot_preview1Z_args_getZ_iii, (wasm_sandbox_wasi_dat
|
|||
buf_size += len;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
IMPORT_IMPL(u32, Z_wasi_snapshot_preview1Z_args_sizes_getZ_iii, (wasm_sandbox_wasi_data* wasi_data, u32 pargc, u32 pargv_buf_size), {
|
||||
u32 Z_wasi_snapshot_preview1Z_args_sizes_getZ_iii(wasm_sandbox_wasi_data* wasi_data, u32 pargc, u32 pargv_buf_size) {
|
||||
wasm_i32_store(wasi_data->heap_memory, pargc, wasi_data->main_argc);
|
||||
u32 buf_size = 0;
|
||||
for (u32 i = 0; i < wasi_data->main_argc; i++) {
|
||||
|
@ -564,41 +560,41 @@ IMPORT_IMPL(u32, Z_wasi_snapshot_preview1Z_args_sizes_getZ_iii, (wasm_sandbox_wa
|
|||
}
|
||||
wasm_i32_store(wasi_data->heap_memory, pargv_buf_size, buf_size);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
// Original file: Modified emscripten/tools/wasm2c/os.c
|
||||
|
||||
#ifdef WASM2C_WASI_EXIT_HOST_ON_MODULE_EXIT
|
||||
IMPORT_IMPL(void, Z_wasi_snapshot_preview1Z_proc_exitZ_vi, (wasm_sandbox_wasi_data* wasi_data, u32 x), {
|
||||
void Z_wasi_snapshot_preview1Z_proc_exitZ_vi(wasm_sandbox_wasi_data* wasi_data, u32 x) {
|
||||
exit(1);
|
||||
});
|
||||
}
|
||||
#else
|
||||
IMPORT_IMPL(void, Z_wasi_snapshot_preview1Z_proc_exitZ_vi, (wasm_sandbox_wasi_data* wasi_data, u32 x), {
|
||||
void Z_wasi_snapshot_preview1Z_proc_exitZ_vi(wasm_sandbox_wasi_data* wasi_data, u32 x) {
|
||||
// upstream emscripten implements this as exit(x)
|
||||
// This seems like a bad idea as a misbehaving sandbox will cause the app to exit
|
||||
// Since this is a library sandboxing runtime, it's fine to do nothing here.
|
||||
// Worst case the library continues execution and returns malformed data, which is already a possibility in any sandbox library
|
||||
VERBOSE_LOG("wasm2c module called proc_exit: this is a noop in this runtime\n");
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
IMPORT_IMPL(u32, Z_wasi_snapshot_preview1Z_environ_sizes_getZ_iii, (wasm_sandbox_wasi_data* wasi_data, u32 pcount, u32 pbuf_size), {
|
||||
u32 Z_wasi_snapshot_preview1Z_environ_sizes_getZ_iii(wasm_sandbox_wasi_data* wasi_data, u32 pcount, u32 pbuf_size) {
|
||||
// TODO: Allow the sandbox to have its own env
|
||||
wasm_i32_store(wasi_data->heap_memory, pcount, 0);
|
||||
wasm_i32_store(wasi_data->heap_memory, pbuf_size, 0);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
IMPORT_IMPL(u32, Z_wasi_snapshot_preview1Z_environ_getZ_iii, (wasm_sandbox_wasi_data* wasi_data, u32 __environ, u32 environ_buf), {
|
||||
u32 Z_wasi_snapshot_preview1Z_environ_getZ_iii(wasm_sandbox_wasi_data* wasi_data, u32 __environ, u32 environ_buf) {
|
||||
// TODO: Allow the sandbox to have its own env
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
////////// File operations
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
IMPORT_IMPL(u32, Z_wasi_snapshot_preview1Z_fd_prestat_getZ_iii, (wasm_sandbox_wasi_data* wasi_data, u32 fd, u32 prestat), {
|
||||
u32 Z_wasi_snapshot_preview1Z_fd_prestat_getZ_iii(wasm_sandbox_wasi_data* wasi_data, u32 fd, u32 prestat) {
|
||||
int nfd = get_native_fd(wasi_data, fd);
|
||||
VERBOSE_LOG(" fd_prestat_get wasm %d => native %d\n", fd, nfd);
|
||||
if (nfd < 0) {
|
||||
|
@ -606,9 +602,9 @@ IMPORT_IMPL(u32, Z_wasi_snapshot_preview1Z_fd_prestat_getZ_iii, (wasm_sandbox_wa
|
|||
}
|
||||
|
||||
return WASI_DEFAULT_ERROR;
|
||||
});
|
||||
}
|
||||
|
||||
IMPORT_IMPL(u32, Z_wasi_snapshot_preview1Z_fd_writeZ_iiiii, (wasm_sandbox_wasi_data* wasi_data, u32 fd, u32 iov, u32 iovcnt, u32 pnum), {
|
||||
u32 Z_wasi_snapshot_preview1Z_fd_writeZ_iiiii(wasm_sandbox_wasi_data* wasi_data, u32 fd, u32 iov, u32 iovcnt, u32 pnum) {
|
||||
int nfd = get_native_fd(wasi_data, fd);
|
||||
VERBOSE_LOG(" fd_write wasm %d => native %d\n", fd, nfd);
|
||||
if (nfd < 0) {
|
||||
|
@ -637,7 +633,7 @@ IMPORT_IMPL(u32, Z_wasi_snapshot_preview1Z_fd_writeZ_iiiii, (wasm_sandbox_wasi_d
|
|||
VERBOSE_LOG(" error, %d %s\n", errno, strerror(errno));
|
||||
return WASI_DEFAULT_ERROR;
|
||||
}
|
||||
if (result != len) {
|
||||
if ((size_t) result != len) {
|
||||
VERBOSE_LOG(" amount error, %ld %d\n", result, len);
|
||||
return WASI_DEFAULT_ERROR;
|
||||
}
|
||||
|
@ -646,9 +642,9 @@ IMPORT_IMPL(u32, Z_wasi_snapshot_preview1Z_fd_writeZ_iiiii, (wasm_sandbox_wasi_d
|
|||
VERBOSE_LOG(" success: %d\n", num);
|
||||
wasm_i32_store(wasi_data->heap_memory, pnum, num);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
IMPORT_IMPL(u32, Z_wasi_snapshot_preview1Z_fd_readZ_iiiii, (wasm_sandbox_wasi_data* wasi_data, u32 fd, u32 iov, u32 iovcnt, u32 pnum), {
|
||||
u32 Z_wasi_snapshot_preview1Z_fd_readZ_iiiii(wasm_sandbox_wasi_data* wasi_data, u32 fd, u32 iov, u32 iovcnt, u32 pnum) {
|
||||
int nfd = get_native_fd(wasi_data, fd);
|
||||
VERBOSE_LOG(" fd_read wasm %d => native %d\n", fd, nfd);
|
||||
if (nfd < 0) {
|
||||
|
@ -669,16 +665,16 @@ IMPORT_IMPL(u32, Z_wasi_snapshot_preview1Z_fd_readZ_iiiii, (wasm_sandbox_wasi_da
|
|||
return WASI_DEFAULT_ERROR;
|
||||
}
|
||||
num += result;
|
||||
if (result != len) {
|
||||
if ((size_t) result != len) {
|
||||
break; // nothing more to read
|
||||
}
|
||||
}
|
||||
VERBOSE_LOG(" success: %d\n", num);
|
||||
wasm_i32_store(wasi_data->heap_memory, pnum, num);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
IMPORT_IMPL(u32, Z_wasi_snapshot_preview1Z_fd_closeZ_ii, (wasm_sandbox_wasi_data* wasi_data, u32 fd), {
|
||||
u32 Z_wasi_snapshot_preview1Z_fd_closeZ_ii(wasm_sandbox_wasi_data* wasi_data, u32 fd) {
|
||||
int nfd = get_native_fd(wasi_data, fd);
|
||||
VERBOSE_LOG(" close wasm %d => native %d\n", fd, nfd);
|
||||
if (nfd < 0) {
|
||||
|
@ -690,7 +686,7 @@ IMPORT_IMPL(u32, Z_wasi_snapshot_preview1Z_fd_closeZ_ii, (wasm_sandbox_wasi_data
|
|||
}
|
||||
POSIX_PREFIX(close)(nfd);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
static int whence_to_native(u32 whence) {
|
||||
if (whence == 0) return SEEK_SET;
|
||||
|
@ -699,7 +695,7 @@ static int whence_to_native(u32 whence) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
IMPORT_IMPL(u32, Z_wasi_snapshot_preview1Z_fd_seekZ_iijii, (wasm_sandbox_wasi_data* wasi_data, u32 fd, u64 offset, u32 whence, u32 new_offset), {
|
||||
u32 Z_wasi_snapshot_preview1Z_fd_seekZ_iijii(wasm_sandbox_wasi_data* wasi_data, u32 fd, u64 offset, u32 whence, u32 new_offset) {
|
||||
int nfd = get_native_fd(wasi_data, fd);
|
||||
int nwhence = whence_to_native(whence);
|
||||
VERBOSE_LOG(" seek %d (=> native %d) %ld %d (=> %d) %d\n", fd, nfd, offset, whence, nwhence, new_offset);
|
||||
|
@ -720,12 +716,12 @@ IMPORT_IMPL(u32, Z_wasi_snapshot_preview1Z_fd_seekZ_iijii, (wasm_sandbox_wasi_da
|
|||
}
|
||||
wasm_i64_store(wasi_data->heap_memory, new_offset, off);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
// wasm2c includes a version of seek, the u64 offset in two u32 parts. Unclear if this is needed, as WASI does not require this, but no harm in including it.
|
||||
IMPORT_IMPL(u32, Z_wasi_snapshot_preview1Z_fd_seekZ_iiiiii, (wasm_sandbox_wasi_data* wasi_data, u32 a, u32 b, u32 c, u32 d, u32 e), {
|
||||
u32 Z_wasi_snapshot_preview1Z_fd_seekZ_iiiiii(wasm_sandbox_wasi_data* wasi_data, u32 a, u32 b, u32 c, u32 d, u32 e) {
|
||||
return Z_wasi_snapshot_preview1Z_fd_seekZ_iijii(wasi_data, a, b + (((u64)c) << 32), d, e);
|
||||
});
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
////////// Clock operations
|
||||
|
@ -741,38 +737,31 @@ static int check_clock(u32 clock_id) {
|
|||
clock_id == WASM_CLOCK_PROCESS_CPUTIME || clock_id == WASM_CLOCK_THREAD_CPUTIME_ID;
|
||||
}
|
||||
|
||||
// out is a pointer index to a struct of the form
|
||||
// // https://github.com/WebAssembly/wasi-libc/blob/659ff414560721b1660a19685110e484a081c3d4/libc-bottom-half/headers/public/__struct_timespec.h
|
||||
// struct timespec {
|
||||
// // https://github.com/WebAssembly/wasi-libc/blob/659ff414560721b1660a19685110e484a081c3d4/libc-bottom-half/headers/public/__typedef_time_t.h
|
||||
// // time is long long in wasm32 which is an i64
|
||||
// time_t tv_sec
|
||||
// // long in wasm is an i32
|
||||
// long tv_nsec;
|
||||
// }
|
||||
IMPORT_IMPL(u32, Z_wasi_snapshot_preview1Z_clock_time_getZ_iiji, (wasm_sandbox_wasi_data* wasi_data, u32 clock_id, u64 max_lag, u32 out), {
|
||||
// out is a pointer to a u64 timestamp in nanoseconds
|
||||
// https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#-timestamp-u64
|
||||
u32 Z_wasi_snapshot_preview1Z_clock_time_getZ_iiji(wasm_sandbox_wasi_data* wasi_data, u32 clock_id, u32 precision, u32 out) {
|
||||
if (!check_clock(clock_id)) {
|
||||
return WASI_INVAL_ERROR;
|
||||
}
|
||||
|
||||
struct timespec out_struct;
|
||||
int ret = os_clock_gettime(wasi_data->clock_data, clock_id, &out_struct);
|
||||
wasm_i64_store(wasi_data->heap_memory, out, (u64) out_struct.tv_sec);
|
||||
wasm_i32_store(wasi_data->heap_memory, out + sizeof(u64), (u32) out_struct.tv_nsec);
|
||||
u64 result = ((u64)out_struct.tv_sec)*1000000 + ((u64)out_struct.tv_nsec)/1000;
|
||||
wasm_i64_store(wasi_data->heap_memory, out, result);
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
|
||||
IMPORT_IMPL(u32, Z_wasi_snapshot_preview1Z_clock_res_getZ_iii, (wasm_sandbox_wasi_data* wasi_data, u32 clock_id, u32 out), {
|
||||
u32 Z_wasi_snapshot_preview1Z_clock_res_getZ_iii(wasm_sandbox_wasi_data* wasi_data, u32 clock_id, u32 out) {
|
||||
if (!check_clock(clock_id)) {
|
||||
return WASI_INVAL_ERROR;
|
||||
}
|
||||
|
||||
struct timespec out_struct;
|
||||
int ret = os_clock_getres(wasi_data->clock_data, clock_id, &out_struct);
|
||||
wasm_i64_store(wasi_data->heap_memory, out, (u64) out_struct.tv_sec);
|
||||
wasm_i32_store(wasi_data->heap_memory, out + sizeof(u64), (u32) out_struct.tv_nsec);
|
||||
u64 result = ((u64)out_struct.tv_sec)*1000000 + ((u64)out_struct.tv_nsec)/1000;
|
||||
wasm_i64_store(wasi_data->heap_memory, out, result);
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
////////// Misc
|
||||
|
|
|
@ -106,11 +106,7 @@ typedef struct {
|
|||
/** A Memory object. */
|
||||
typedef struct {
|
||||
/** The linear memory data, with a byte length of `size`. */
|
||||
#if WASM_USING_GUARD_PAGES == 1
|
||||
uint8_t* const data;
|
||||
#else
|
||||
uint8_t* data;
|
||||
#endif
|
||||
/** The current and maximum page count for this Memory object. If there is no
|
||||
* maximum, `max_pages` is 0xffffffffu (i.e. UINT32_MAX). */
|
||||
uint32_t pages, max_pages;
|
||||
|
|
Загрузка…
Ссылка в новой задаче