chore: partial sandbox cleanup

main
Sean McBride 5 years ago
parent cbd64d1f91
commit dc9677e41f

@ -77,11 +77,6 @@ struct sandbox {
char request_response_data[1]; // of rr_data_sz, following sandbox mem..
} PAGE_ALIGNED;
// a runtime resource, malloc on this!
struct sandbox *sandbox__allocate(struct module *module, char *arguments, int socket_descriptor, const struct sockaddr *socket_address, u64 start_time);
// should free stack and heap resources.. also any I/O handles.
void sandbox__free(struct sandbox *sandbox);
extern __thread struct sandbox *current_sandbox;
// next_sandbox only used in SIGUSR1
extern __thread arch_context_t *next_context;
@ -89,6 +84,131 @@ extern __thread arch_context_t *next_context;
typedef struct sandbox sandbox_t;
extern void add_sandbox_to_completion_queue(struct sandbox *sandbox);
/***************************
* Sandbox *
**************************/
// a runtime resource, malloc on this!
struct sandbox *sandbox__allocate(struct module *module, char *arguments, int socket_descriptor, const struct sockaddr *socket_address, u64 start_time);
// should free stack and heap resources.. also any I/O handles.
void sandbox__free(struct sandbox *sandbox);
/**
* Given a sandbox, returns the module that sandbox is executing
* @param sandbox the sandbox whose module we want
* @return the module of the provided sandbox
*/
static inline struct module *
sandbox__get_module(struct sandbox *sandbox)
{
if (!sandbox) return NULL;
return sandbox->module;
}
/**
* Getter for the arguments of the current sandbox
* @return the arguments of the current sandbox
*/
static inline char *
sandbox__get_arguments(struct sandbox *sandbox)
{
if (!sandbox) return NULL;
return (char *)sandbox->arguments;
}
/**
* Initializes and returns an IO handle on the current sandbox ready for use
* @return index of handle we preopened or -1 on error (sandbox is null or all handles are exhausted)
**/
static inline int
sandbox__initialize_io_handle(struct sandbox *sandbox)
{
if (!sandbox) return -1;
int handle_index;
for (handle_index = 0; handle_index < SBOX_MAX_OPEN; handle_index++) {
if (sandbox->handles[handle_index].file_descriptor < 0) break;
}
if (handle_index == SBOX_MAX_OPEN) return -1;
sandbox->handles[handle_index].file_descriptor = SBOX_PREOPEN_MAGIC;
memset(&sandbox->handles[handle_index].libuv_handle, 0, sizeof(union uv_any_handle));
return handle_index;
}
/**
* Initializes and returns an IO handle on the current sandbox ready for use
* @param file_descriptor what we'll set on the IO handle after initialization
* @return index of handle we preopened or -1 if all handles are exhausted
**/
static inline int
sandbox__initialize_io_handle_and_set_file_descriptor(struct sandbox *sandbox, int file_descriptor)
{
if (!sandbox) return -1;
if (file_descriptor < 0) return file_descriptor;
int handle_index = sandbox__initialize_io_handle(sandbox);
if (handle_index != -1) sandbox->handles[handle_index].file_descriptor = file_descriptor; // well, per sandbox.. so synchronization necessary!
return handle_index;
}
/**
* Sets the file descriptor of the sandbox's ith io_handle
* Returns error condition if the file_descriptor to set does not contain sandbox preopen magin
* @param handle_index index of the sandbox handles we want to set
* @param file_descriptor the file descripter we want to set it to
* @returns the index that was set or -1 in case of error
**/
static inline int
sandbox__set_file_descriptor(struct sandbox *sandbox, int handle_index, int file_descriptor)
{
if (!sandbox) return -1;
if (handle_index >= SBOX_MAX_OPEN || handle_index < 0) return -1;
if (file_descriptor < 0 || sandbox->handles[handle_index].file_descriptor != SBOX_PREOPEN_MAGIC) return -1;
sandbox->handles[handle_index].file_descriptor = file_descriptor;
return handle_index;
}
/**
* Get the file descriptor of the sandbox's ith io_handle
* @param handle_index index into the sandbox's handles table
* @returns file descriptor or -1 in case of error
**/
static inline int
sandbox__get_file_descriptor(struct sandbox *sandbox, int handle_index)
{
if (!sandbox) return -1;
if (handle_index >= SBOX_MAX_OPEN || handle_index < 0) return -1;
return sandbox->handles[handle_index].file_descriptor;
}
/**
* Close the sandbox's ith io_handle
* @param handle_index index of the handle to close
**/
static inline void
sandbox__close_file_descriptor(struct sandbox *sandbox, int handle_index)
{
if (handle_index >= SBOX_MAX_OPEN || handle_index < 0) return;
// TODO: Do we actually need to call some sort of close function here?
sandbox->handles[handle_index].file_descriptor = -1;
}
/**
* Get the Libuv handle located at idx of the sandbox ith io_handle
* @param handle_index index of the handle containing libuv_handle???
* @returns any libuv handle or a NULL pointer in case of error
**/
static inline union uv_any_handle *
sandbox__get_libuv_handle(struct sandbox *sandbox, int handle_index)
{
if (!sandbox) return NULL;
if (handle_index >= SBOX_MAX_OPEN || handle_index < 0) return NULL;
return &sandbox->handles[handle_index].libuv_handle;
}
/***************************
* Current Sandbox *
**************************/
/**
* Getter for the current sandbox executing on this thread
@ -117,19 +237,6 @@ current_sandbox__set(struct sandbox *sandbox)
module_indirect_table = sandbox->module->indirect_table;
}
/**
* Given a sandbox, returns the module that sandbox is executing
* @param sandbox the sandbox whose module we want
* @return the module of the provided sandbox
*/
static inline struct module *
sandbox__get_module(struct sandbox *sandbox)
{
if (!sandbox) return NULL;
return sandbox->module;
}
/**
* Getter for the arguments of the current sandbox
* @return the arguments of the current sandbox
@ -138,7 +245,7 @@ static inline char *
current_sandbox__get_arguments(void)
{
struct sandbox *sandbox = current_sandbox__get();
return (char *)sandbox->arguments;
return sandbox__get_arguments(sandbox);
}
void * sandbox_worker_main(void *data);
@ -163,14 +270,7 @@ static inline int
current_sandbox__initialize_io_handle(void)
{
struct sandbox *sandbox = current_sandbox__get();
int handle_index;
for (handle_index = 0; handle_index < SBOX_MAX_OPEN; handle_index++) {
if (sandbox->handles[handle_index].file_descriptor < 0) break;
}
if (handle_index == SBOX_MAX_OPEN) return -1;
sandbox->handles[handle_index].file_descriptor = SBOX_PREOPEN_MAGIC;
memset(&sandbox->handles[handle_index].libuv_handle, 0, sizeof(union uv_any_handle));
return handle_index;
return sandbox__initialize_io_handle(sandbox);
}
/**
@ -182,10 +282,7 @@ static inline int
current_sandbox__initialize_io_handle_and_set_file_descriptor(int file_descriptor)
{
struct sandbox *sandbox = current_sandbox__get();
if (file_descriptor < 0) return file_descriptor;
int handle_index = current_sandbox__initialize_io_handle();
if (handle_index != -1) sandbox->handles[handle_index].file_descriptor = file_descriptor; // well, per sandbox.. so synchronization necessary!
return handle_index;
return sandbox__initialize_io_handle_and_set_file_descriptor(sandbox, file_descriptor);
}
/**
@ -199,10 +296,7 @@ static inline int
current_sandbox__set_file_descriptor(int handle_index, int file_descriptor)
{
struct sandbox *sandbox = current_sandbox__get();
if (handle_index >= SBOX_MAX_OPEN || handle_index < 0) return -1;
if (file_descriptor < 0 || sandbox->handles[handle_index].file_descriptor != SBOX_PREOPEN_MAGIC) return -1;
sandbox->handles[handle_index].file_descriptor = file_descriptor;
return handle_index;
return sandbox__set_file_descriptor(sandbox, handle_index, file_descriptor);
}
/**
@ -214,8 +308,7 @@ static inline int
current_sandbox__get_file_descriptor(int handle_index)
{
struct sandbox *sandbox = current_sandbox__get();
if (handle_index >= SBOX_MAX_OPEN || handle_index < 0) return -1;
return sandbox->handles[handle_index].file_descriptor;
return sandbox__get_file_descriptor(sandbox, handle_index);
}
/**
@ -226,9 +319,7 @@ static inline void
current_sandbox__close_file_descriptor(int handle_index)
{
struct sandbox *sandbox = current_sandbox__get();
if (handle_index >= SBOX_MAX_OPEN || handle_index < 0) return;
// TODO: Do we actually need to call some sort of close function here?
sandbox->handles[handle_index].file_descriptor = -1;
sandbox__close_file_descriptor(sandbox, handle_index);
}
/**
@ -240,8 +331,7 @@ static inline union uv_any_handle *
current_sandbox__get_libuv_handle(int handle_index)
{
struct sandbox *sandbox = current_sandbox__get();
if (handle_index >= SBOX_MAX_OPEN || handle_index < 0) return NULL;
return &sandbox->handles[handle_index].libuv_handle;
return sandbox__get_libuv_handle(sandbox, handle_index);
}
/**

@ -8,46 +8,6 @@
#include <http_api.h>
#include <libuv_callbacks.h>
/**
* Allocates the memory for a sandbox to run a module
* @param module the module that we want to run
* @returns the resulting sandbox or NULL if mmap failed
**/
static inline struct sandbox *
allocate_sandbox_memory(struct module *module)
{
unsigned long memory_size = SBOX_MAX_MEM; // 4GB
// Why do we add max_request_or_response_size?
unsigned long sandbox_size = sizeof(struct sandbox) + module->max_request_or_response_size;
unsigned long linear_memory_size = WASM_PAGE_SIZE * WASM_START_PAGES;
if (linear_memory_size + sandbox_size > memory_size) return NULL;
assert(round_up_to_page(sandbox_size) == sandbox_size);
// What does mmap do exactly with file_descriptor -1?
void *addr = mmap(NULL, sandbox_size + memory_size + /* guard page */ PAGE_SIZE, PROT_NONE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (addr == MAP_FAILED) return NULL;
void *addr_rw = mmap(addr, sandbox_size + linear_memory_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
if (addr_rw == MAP_FAILED) {
munmap(addr, memory_size + PAGE_SIZE);
return NULL;
}
struct sandbox *sandbox = (struct sandbox *)addr;
// can it include sandbox as well?
sandbox->linear_memory_start = (char *)addr + sandbox_size;
sandbox->linear_memory_size = linear_memory_size;
sandbox->module = module;
sandbox->sandbox_size = sandbox_size;
module__acquire(module);
return sandbox;
}
/**
* Takes the arguments from the sandbox struct and writes them into the WebAssembly linear memory
* TODO: why do we have to pass argument count explicitly? Can't we just get this off the sandbox?
@ -267,6 +227,46 @@ sandbox_main(void)
current_sandbox__exit();
}
/**
* Allocates the memory for a sandbox to run a module
* @param module the module that we want to run
* @returns the resulting sandbox or NULL if mmap failed
**/
static inline struct sandbox *
sandbox__allocate_memory(struct module *module)
{
unsigned long memory_size = SBOX_MAX_MEM; // 4GB
// Why do we add max_request_or_response_size?
unsigned long sandbox_size = sizeof(struct sandbox) + module->max_request_or_response_size;
unsigned long linear_memory_size = WASM_PAGE_SIZE * WASM_START_PAGES;
if (linear_memory_size + sandbox_size > memory_size) return NULL;
assert(round_up_to_page(sandbox_size) == sandbox_size);
// What does mmap do exactly with file_descriptor -1?
void *addr = mmap(NULL, sandbox_size + memory_size + /* guard page */ PAGE_SIZE, PROT_NONE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (addr == MAP_FAILED) return NULL;
void *addr_rw = mmap(addr, sandbox_size + linear_memory_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
if (addr_rw == MAP_FAILED) {
munmap(addr, memory_size + PAGE_SIZE);
return NULL;
}
struct sandbox *sandbox = (struct sandbox *)addr;
// can it include sandbox as well?
sandbox->linear_memory_start = (char *)addr + sandbox_size;
sandbox->linear_memory_size = linear_memory_size;
sandbox->module = module;
sandbox->sandbox_size = sandbox_size;
module__acquire(module);
return sandbox;
}
struct sandbox *
sandbox__allocate(struct module *module, char *arguments, int socket_descriptor, const struct sockaddr *socket_address, u64 start_time)
{
@ -274,7 +274,7 @@ sandbox__allocate(struct module *module, char *arguments, int socket_descriptor,
// FIXME: don't use malloc. huge security problem!
// perhaps, main should be in its own sandbox, when it is not running any sandbox.
struct sandbox *sandbox = (struct sandbox *)allocate_sandbox_memory(module);
struct sandbox *sandbox = (struct sandbox *)sandbox__allocate_memory(module);
if (!sandbox) return NULL;
// Assign the start time from the request

Loading…
Cancel
Save