feat: -1 on wasm memory.grow instruction failure

master
Sean McBride 4 years ago
parent ed61a97d9f
commit c185c751bd

@ -40,7 +40,7 @@ extern void runtime_set_resource_limits_to_max(void);
/* External Symbols */
extern void alloc_linear_memory(void);
extern void expand_memory(void);
extern int expand_memory(void);
INLINE char *get_function_from_table(uint32_t idx, uint32_t type_id);
INLINE char *get_memory_ptr_for_runtime(uint32_t offset, uint32_t bounds_check);
extern void stub_init(int32_t offset);

@ -6,24 +6,36 @@
#include <sys/mman.h>
void
/**
* @brief Expand the linear memory of the active WebAssembly sandbox by a single page
*
* @return int
*/
int
expand_memory(void)
{
struct sandbox *sandbox = current_sandbox_get();
assert(sandbox->state == SANDBOX_RUNNING);
assert(local_sandbox_context_cache.memory.size % WASM_PAGE_SIZE == 0);
// TODO: Refactor to return RC signifying out-of-mem to caller. Issue #96.
if (local_sandbox_context_cache.memory.size + WASM_PAGE_SIZE >= local_sandbox_context_cache.memory.max)
panic("expand_memory - Out of Memory!. %u out of %lu\n", local_sandbox_context_cache.memory.size,
local_sandbox_context_cache.memory.max);
/* Return -1 if we've hit the linear memory max */
if (unlikely(local_sandbox_context_cache.memory.size + WASM_PAGE_SIZE
>= local_sandbox_context_cache.memory.max)) {
debuglog("expand_memory - Out of Memory!. %u out of %lu\n", local_sandbox_context_cache.memory.size,
local_sandbox_context_cache.memory.max);
return -1;
}
// Remap the relevant wasm page to readable
char *mem_as_chars = local_sandbox_context_cache.memory.start;
char *page_address = &mem_as_chars[local_sandbox_context_cache.memory.size];
void *map_result = mmap(page_address, WASM_PAGE_SIZE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
if (map_result == MAP_FAILED) panic("Mapping of new memory failed");
if (map_result == MAP_FAILED) {
debuglog("Mapping of new memory failed");
return -1;
}
local_sandbox_context_cache.memory.size += WASM_PAGE_SIZE;
@ -38,6 +50,7 @@ expand_memory(void)
// local_sandbox_context_cache is "forked state", so update authoritative member
sandbox->memory.size = local_sandbox_context_cache.memory.size;
return 0;
}
INLINE char *
@ -54,3 +67,51 @@ get_memory_ptr_for_runtime(uint32_t offset, uint32_t bounds_check)
return address;
}
/**
* @brief Stub that implements the WebAssembly memory.grow instruction
*
* @param count number of pages to grow the WebAssembly linear memory by
* @return The previous size of the linear memory in pages or -1 if enough memory cannot be allocated
*/
int32_t
instruction_memory_grow(uint32_t count)
{
int rc = local_sandbox_context_cache.memory.size / WASM_PAGE_SIZE;
for (int i = 0; i < count; i++) {
if (unlikely(expand_memory() != 0)) {
rc = -1;
break;
}
}
return rc;
}
/*
* Table handling functionality
* This was moved from compiletime in order to place the
* function in the callstack in GDB. It can be moved back
* to runtime/compiletime/memory/64bit_nix.c to remove the
* additional function call
*/
char *
get_function_from_table(uint32_t idx, uint32_t type_id)
{
#ifdef LOG_FUNCTION_TABLE
fprintf(stderr, "get_function_from_table(idx: %u, type_id: %u)\n", idx, type_id);
fprintf(stderr, "indirect_table_size: %u\n", INDIRECT_TABLE_SIZE);
#endif
assert(idx < INDIRECT_TABLE_SIZE);
struct indirect_table_entry f = local_sandbox_context_cache.module_indirect_table[idx];
#ifdef LOG_FUNCTION_TABLE
fprintf(stderr, "assumed type: %u, type in table: %u\n", type_id, f.type_id);
#endif
assert(f.type_id == type_id);
assert(f.func_pointer != NULL);
return f.func_pointer;
}

Loading…
Cancel
Save