From f61f34f08aa698e57d62a66e22247c4899abb884 Mon Sep 17 00:00:00 2001 From: Sean McBride Date: Wed, 8 Sep 2021 11:32:43 -0400 Subject: [PATCH] refactor: Clean up HTTP handling --- runtime/include/client_socket.h | 4 + runtime/include/http.h | 60 +++++++++++-- runtime/include/module.h | 6 +- runtime/include/sandbox_receive_request.h | 44 +++++----- runtime/include/sandbox_send_response.h | 100 ++++++---------------- runtime/include/sandbox_types.h | 59 +++++++------ runtime/src/current_sandbox.c | 15 ++-- runtime/src/module.c | 9 +- runtime/src/sandbox.c | 60 +++++++------ runtime/tests/Makefile | 21 +++-- 10 files changed, 201 insertions(+), 177 deletions(-) diff --git a/runtime/include/client_socket.h b/runtime/include/client_socket.h index 67b146a..807dca8 100644 --- a/runtime/include/client_socket.h +++ b/runtime/include/client_socket.h @@ -47,6 +47,10 @@ client_socket_send(int client_socket, int status_code) response = HTTP_RESPONSE_503_SERVICE_UNAVAILABLE; http_total_increment_5XX(); break; + case 413: + response = HTTP_RESPONSE_413_PAYLOAD_TOO_LARGE; + http_total_increment_4XX(); + break; case 400: response = HTTP_RESPONSE_400_BAD_REQUEST; http_total_increment_4XX(); diff --git a/runtime/include/http.h b/runtime/include/http.h index f938826..1f8b932 100644 --- a/runtime/include/http.h +++ b/runtime/include/http.h @@ -1,14 +1,58 @@ #pragma once +#include + #define HTTP_MAX_HEADER_COUNT 16 #define HTTP_MAX_HEADER_LENGTH 32 #define HTTP_MAX_HEADER_VALUE_LENGTH 64 -#define HTTP_RESPONSE_200_OK "HTTP/1.1 200 OK\r\n" -#define HTTP_RESPONSE_503_SERVICE_UNAVAILABLE "HTTP/1.1 503 Service Unavailable\r\n\r\n" -#define HTTP_RESPONSE_400_BAD_REQUEST "HTTP/1.1 400 Bad Request\r\n\r\n" -#define HTTP_RESPONSE_CONTENT_LENGTH "Content-Length: " -#define HTTP_RESPONSE_CONTENT_LENGTH_TERMINATOR "\r\n\r\n" /* content body follows this */ -#define HTTP_RESPONSE_CONTENT_TYPE "Content-Type: " -#define HTTP_RESPONSE_CONTENT_TYPE_PLAIN "text/plain" -#define HTTP_RESPONSE_CONTENT_TYPE_TERMINATOR " \r\n" +#define HTTP_RESPONSE_400_BAD_REQUEST "HTTP/1.1 400 Bad Request\r\n\r\n" +#define HTTP_RESPONSE_413_PAYLOAD_TOO_LARGE "HTTP/1.1 413 Payload Too Large\r\n\r\n" +#define HTTP_RESPONSE_503_SERVICE_UNAVAILABLE "HTTP/1.1 503 Service Unavailable\r\n\r\n" + +#define HTTP_RESPONSE_200_TEMPLATE \ + "HTTP/1.1 200 OK\r\n" \ + "Content-Type: %s\r\n" \ + "Content-Length: %s\r\n" \ + "\r\n" + +/* The sum of format specifier characters in the template above */ +#define HTTP_RESPONSE_200_TEMPLATE_FORMAT_SPECIFIER_LENGTH 4 + +/** + * Calculates the number of bytes of the HTTP response containing the passed header values + * @return total size in bytes + */ +static inline size_t +http_response_200_size(char *content_type, char *content_length) +{ + size_t size = 0; + size += strlen(HTTP_RESPONSE_200_TEMPLATE) - HTTP_RESPONSE_200_TEMPLATE_FORMAT_SPECIFIER_LENGTH; + size += strlen(content_type); + size += strlen(content_length); + return size; +} + +/** + * Writes the HTTP response header to the destination. This is assumed to have been sized + * using the value returned by http_response_200_size. We have to use an intermediate buffer + * in order to truncate off the null terminator + * @return 0 on success, -1 otherwise + */ +static inline int +http_response_200(char *destination, char *content_type, char *content_length) +{ + size_t response_size = http_response_200_size(content_type, content_length); + char buffer[response_size + 1]; + int rc = 0; + rc = sprintf(buffer, HTTP_RESPONSE_200_TEMPLATE, content_type, content_length); + if (rc <= 0) goto err; + memmove(destination, buffer, response_size); + rc = 0; + +done: + return rc; +err: + rc = -1; + goto done; +} diff --git a/runtime/include/module.h b/runtime/include/module.h index 980e167..97bd8b0 100644 --- a/runtime/include/module.h +++ b/runtime/include/module.h @@ -40,14 +40,12 @@ struct module { uint64_t max_memory; /* perhaps a specification of the module. (max 4GB) */ uint32_t relative_deadline_us; int port; - unsigned long max_request_size; - unsigned long max_response_size; /* resp size including headers! */ struct admissions_info admissions_info; uint64_t relative_deadline; /* cycles */ - /* HTTP State */ - unsigned long max_request_or_response_size; /* largest of max_request_size or max_response_size */ + size_t max_request_size; + size_t max_response_size; char response_content_type[HTTP_MAX_HEADER_VALUE_LENGTH]; struct sockaddr_in socket_address; int socket_descriptor; diff --git a/runtime/include/sandbox_receive_request.h b/runtime/include/sandbox_receive_request.h index f5aac31..85c3233 100644 --- a/runtime/include/sandbox_receive_request.h +++ b/runtime/include/sandbox_receive_request.h @@ -18,14 +18,14 @@ /** * Receive and Parse the Request for the current sandbox - * @return 0 if message parsing complete, -1 on error + * @return 0 if message parsing complete, -1 on error, -2 if buffers run out of space */ static inline int sandbox_receive_request(struct sandbox *sandbox) { assert(sandbox != NULL); assert(sandbox->module->max_request_size > 0); - assert(sandbox->buffer.length == 0); + assert(sandbox->request.length == 0); int rc = 0; @@ -36,26 +36,28 @@ sandbox_receive_request(struct sandbox *sandbox) http_parser * parser = &sandbox->http_parser; const http_parser_settings *settings = http_parser_settings_get(); - int fd = sandbox->client_socket_descriptor; - char * buf = &sandbox->buffer.start[sandbox->buffer.length]; - size_t len = sandbox->module->max_request_size - sandbox->buffer.length; + if (sandbox->module->max_request_size <= sandbox->request.length) { + debuglog("Sandbox %lu: Ran out of Request Buffer before message end\n", sandbox->id); + goto err_nobufs; + } - ssize_t recved = recv(fd, buf, len, 0); + ssize_t bytes_received = recv(sandbox->client_socket_descriptor, + &sandbox->request.base[sandbox->request.length], + sandbox->module->max_request_size - sandbox->request.length, 0); - if (recved < 0) { + if (bytes_received == -1) { if (errno == EAGAIN) { scheduler_block(); continue; } else { - /* All other errors */ debuglog("Error reading socket %d - %s\n", sandbox->client_socket_descriptor, strerror(errno)); goto err; } } - /* Client request is malformed */ - if (recved == 0 && !sandbox->http_request.message_end) { + /* If we received an EOF before we were able to parse a complete HTTP header, request is malformed */ + if (bytes_received == 0 && !sandbox->http_request.message_end) { char client_address_text[INET6_ADDRSTRLEN] = {}; if (unlikely(inet_ntop(AF_INET, &sandbox->client_address, client_address_text, INET6_ADDRSTRLEN) == NULL)) { @@ -63,37 +65,37 @@ sandbox_receive_request(struct sandbox *sandbox) } debuglog("Sandbox %lu: recv returned 0 before a complete request was received\n", sandbox->id); - debuglog("Socket: %d. Address: %s\n", fd, client_address_text); + debuglog("Socket: %d. Address: %s\n", sandbox->client_socket_descriptor, client_address_text); http_request_print(&sandbox->http_request); goto err; } #ifdef LOG_HTTP_PARSER debuglog("Sandbox: %lu http_parser_execute(%p, %p, %p, %zu\n)", sandbox->id, parser, settings, buf, - recved); + bytes_received); #endif - size_t nparsed = http_parser_execute(parser, settings, buf, recved); + size_t bytes_parsed = http_parser_execute(parser, settings, + &sandbox->request.base[sandbox->request.length], + bytes_received); - if (nparsed != recved) { - /* TODO: Is this error */ + if (bytes_parsed != bytes_received) { debuglog("Error: %s, Description: %s\n", http_errno_name((enum http_errno)sandbox->http_parser.http_errno), http_errno_description((enum http_errno)sandbox->http_parser.http_errno)); - debuglog("Length Parsed %zu, Length Read %zu\n", nparsed, recved); + debuglog("Length Parsed %zu, Length Read %zu\n", bytes_parsed, bytes_received); debuglog("Error parsing socket %d\n", sandbox->client_socket_descriptor); goto err; } - - sandbox->buffer.length += nparsed; + sandbox->request.length += bytes_parsed; } - - sandbox->http_request_length = sandbox->buffer.length; - rc = 0; done: return rc; +err_nobufs: + rc = -2; + goto done; err: rc = -1; goto done; diff --git a/runtime/include/sandbox_send_response.h b/runtime/include/sandbox_send_response.h index e333667..8ccc323 100644 --- a/runtime/include/sandbox_send_response.h +++ b/runtime/include/sandbox_send_response.h @@ -24,97 +24,51 @@ static inline int sandbox_send_response(struct sandbox *sandbox) { assert(sandbox != NULL); + /* Assumption: The HTTP Request Buffer immediately precedes the HTTP Response Buffer, + * meaning that when we prepend, we are overwritting the tail of the HTTP request buffer */ + assert(sandbox->request.base + sandbox->module->max_request_size == sandbox->response.base); - /* - * At this point the HTTP Request has filled the buffer up to request_length, after which - * the STDOUT of the sandbox has been appended. We assume that our HTTP Response header is - * smaller than the HTTP Request header, which allows us to use memmove once without copying - * to an intermediate buffer. - */ - memset(sandbox->buffer.start, 0, sandbox->http_request_length); - - /* - * We use this cursor to keep track of our position in the buffer and later assert that we - * haven't overwritten body data. - */ - size_t response_cursor = 0; - - /* Append 200 OK */ - strncpy(sandbox->buffer.start, HTTP_RESPONSE_200_OK, strlen(HTTP_RESPONSE_200_OK)); - response_cursor += strlen(HTTP_RESPONSE_200_OK); - - /* Content Type */ - strncpy(sandbox->buffer.start + response_cursor, HTTP_RESPONSE_CONTENT_TYPE, - strlen(HTTP_RESPONSE_CONTENT_TYPE)); - response_cursor += strlen(HTTP_RESPONSE_CONTENT_TYPE); - - /* Custom content type if provided, text/plain by default */ - if (strlen(sandbox->module->response_content_type) <= 0) { - strncpy(sandbox->buffer.start + response_cursor, HTTP_RESPONSE_CONTENT_TYPE_PLAIN, - strlen(HTTP_RESPONSE_CONTENT_TYPE_PLAIN)); - response_cursor += strlen(HTTP_RESPONSE_CONTENT_TYPE_PLAIN); - } else { - strncpy(sandbox->buffer.start + response_cursor, sandbox->module->response_content_type, - strlen(sandbox->module->response_content_type)); - response_cursor += strlen(sandbox->module->response_content_type); - } - - strncpy(sandbox->buffer.start + response_cursor, HTTP_RESPONSE_CONTENT_TYPE_TERMINATOR, - strlen(HTTP_RESPONSE_CONTENT_TYPE_TERMINATOR)); - response_cursor += strlen(HTTP_RESPONSE_CONTENT_TYPE_TERMINATOR); - - /* Content Length */ - strncpy(sandbox->buffer.start + response_cursor, HTTP_RESPONSE_CONTENT_LENGTH, - strlen(HTTP_RESPONSE_CONTENT_LENGTH)); - response_cursor += strlen(HTTP_RESPONSE_CONTENT_LENGTH); - - size_t body_size = sandbox->buffer.length - sandbox->http_request_length; - - char len[10] = { 0 }; - sprintf(len, "%zu", body_size); - strncpy(sandbox->buffer.start + response_cursor, len, strlen(len)); - response_cursor += strlen(len); + int rc; - strncpy(sandbox->buffer.start + response_cursor, HTTP_RESPONSE_CONTENT_LENGTH_TERMINATOR, - strlen(HTTP_RESPONSE_CONTENT_LENGTH_TERMINATOR)); - response_cursor += strlen(HTTP_RESPONSE_CONTENT_LENGTH_TERMINATOR); + /* Determine values to template into our HTTP response */ + ssize_t response_body_size = sandbox->response.length; + char content_length[20] = { 0 }; + sprintf(content_length, "%zu", response_body_size); + char *module_content_type = sandbox->module->response_content_type; + char *content_type = strlen(module_content_type) > 0 ? module_content_type : "text/plain"; - /* - * Assumption: Our response header is smaller than the request header, so we do not overwrite - * actual data that the program appended to the HTTP Request. If proves to be a bad assumption, - * we have to copy the STDOUT string to a temporary buffer before writing the header - */ - if (unlikely(response_cursor >= sandbox->http_request_length)) { - panic("Response Cursor: %zd is less that Request Length: %zd\n", response_cursor, - sandbox->http_request_length); - } - - /* Move the Sandbox's Data after the HTTP Response Data */ - memmove(sandbox->buffer.start + response_cursor, sandbox->buffer.start + sandbox->http_request_length, - body_size); - response_cursor += body_size; + /* Prepend HTTP Response Headers */ + size_t response_header_size = http_response_200_size(content_type, content_length); + char * response_header = sandbox->response.base - response_header_size; + rc = http_response_200(response_header, content_type, content_length); + if (rc < 0) goto err; /* Capture Timekeeping data for end-to-end latency */ uint64_t end_time = __getcycles(); sandbox->total_time = end_time - sandbox->timestamp_of.request_arrival; - int rc; - int sent = 0; - while (sent < response_cursor) { - rc = write(sandbox->client_socket_descriptor, &sandbox->buffer.start[sent], response_cursor - sent); + /* Send HTTP Response */ + int sent = 0; + size_t response_size = response_header_size + response_body_size; + while (sent < response_size) { + rc = write(sandbox->client_socket_descriptor, response_header, response_size - sent); if (rc < 0) { if (errno == EAGAIN) scheduler_block(); else { perror("write"); - return -1; + goto err; } } - sent += rc; } http_total_increment_2xx(); + rc = 0; - return 0; +done: + return rc; +err: + rc = -1; + goto done; } diff --git a/runtime/include/sandbox_types.h b/runtime/include/sandbox_types.h index 61c0492..4d822f5 100644 --- a/runtime/include/sandbox_types.h +++ b/runtime/include/sandbox_types.h @@ -40,41 +40,46 @@ struct sandbox_timestamps { }; /* - * In-memory buffer used to read requests, buffer write to STDOUT, and write HTTP responses - * The HTTP request is read in, updating buffer.length and http_request_length - * -------------------------------------------------- - * | Request | Empty | - * -------------------------------------------------- - * Writes to STDOUT are written starting at http_request_length, updating buffer.length - * -------------------------------------------------- - * | Request | STDOUT | Empty | - * -------------------------------------------------- - * The HTTP Response is written over the Request (assumes the response is smaller) - * -------------------------------------------------- - * | Response | Gap | STDOUT | Empty | - * -------------------------------------------------- - * And the STDOUT buffer is compacted to immediately follow the response - * -------------------------------------------------- - * | Response | STDOUT | Empty | - * -------------------------------------------------- + * Static In-memory buffers are used for HTTP requests read in via STDIN and HTTP + * responses written back out via STDOUT. These are allocated in pages immediately + * adjacent to the sandbox struct in the following layout. The capacity of these + * buffers are configured in the module spec and stored in sandbox->module.max_request_size + * and sandbox->module.max_response_size. + * + * Because the sandbox struct, the request header, and the response header are sized + * in pages, we must store the base pointer to the buffer. The length is increased + * and should not exceed the respective module max size. + * + * --------------------------------------------------- + * | Sandbox | Request | Response | + * --------------------------------------------------- + * + * After the sandbox writes its response, a header is written at a negative offset + * overwriting the tail end of the request buffer. This assumes that the request + * data is no longer needed because the sandbox has run to completion + * + * --------------------------------------------------- + * | Sandbox | Garbage | HDR | Response | + * --------------------------------------------------- */ struct sandbox_buffer { - ssize_t length; /* Should be <= module->max_request_or_response_size */ - char start[1]; + char * base; + size_t length; }; struct sandbox { uint64_t id; sandbox_state_t state; - uint32_t sandbox_size; /* The struct plus enough buffer to hold the request or response (sized off largest) */ - struct ps_list list; /* used by ps_list's default name-based MACROS for the scheduling runqueue */ + struct ps_list list; /* used by ps_list's default name-based MACROS for the scheduling runqueue */ /* HTTP State */ - struct sockaddr client_address; /* client requesting connection! */ - int client_socket_descriptor; - http_parser http_parser; - struct http_request http_request; - ssize_t http_request_length; + struct sockaddr client_address; /* client requesting connection! */ + int client_socket_descriptor; + http_parser http_parser; + struct http_request http_request; + ssize_t http_request_length; /* TODO: Get rid of me */ + struct sandbox_buffer request; + struct sandbox_buffer response; /* WebAssembly Module State */ struct module *module; /* the module this is an instance of */ @@ -97,6 +102,4 @@ struct sandbox { int32_t arguments_offset; /* actual placement of arguments in the sandbox. */ int32_t return_value; - /* This contains a Variable Length Array and thus MUST be the final member of this struct */ - struct sandbox_buffer buffer; } PAGE_ALIGNED; diff --git a/runtime/src/current_sandbox.c b/runtime/src/current_sandbox.c index b0d35f8..1b9a21c 100644 --- a/runtime/src/current_sandbox.c +++ b/runtime/src/current_sandbox.c @@ -68,13 +68,19 @@ current_sandbox_start(void) assert(sandbox->state == SANDBOX_RUNNING); char *error_message = ""; + int rc = 0; sandbox_open_http(sandbox); - if (sandbox_receive_request(sandbox) < 0) { - error_message = "Unable to receive or parse client request\n"; + rc = sandbox_receive_request(sandbox); + if (rc == -2) { + /* Request size exceeded Buffer, send 413 Payload Too Large */ + client_socket_send(sandbox->client_socket_descriptor, 413); goto err; - }; + } else if (rc == -1) { + client_socket_send(sandbox->client_socket_descriptor, 400); + goto err; + } /* Initialize sandbox memory */ struct module *current_module = sandbox_get_module(sandbox); @@ -116,9 +122,6 @@ err: debuglog("%s", error_message); assert(sandbox->state == SANDBOX_RUNNING); - /* Send a 400 error back to the client */ - client_socket_send(sandbox->client_socket_descriptor, 400); - sandbox_close_http(sandbox); sandbox_set_as_error(sandbox, SANDBOX_RUNNING); goto done; diff --git a/runtime/src/module.c b/runtime/src/module.c index eaf0538..4b5a66d 100644 --- a/runtime/src/module.c +++ b/runtime/src/module.c @@ -185,13 +185,8 @@ module_new(char *name, char *path, uint32_t stack_size, uint32_t max_memory, uin /* Request Response Buffer */ if (request_size == 0) request_size = MODULE_DEFAULT_REQUEST_RESPONSE_SIZE; if (response_size == 0) response_size = MODULE_DEFAULT_REQUEST_RESPONSE_SIZE; - module->max_request_size = request_size; - module->max_response_size = response_size; - if (request_size > response_size) { - module->max_request_or_response_size = round_up_to_page(request_size); - } else { - module->max_request_or_response_size = round_up_to_page(response_size); - } + module->max_request_size = round_up_to_page(request_size); + module->max_response_size = round_up_to_page(response_size); /* Table initialization calls a function that runs within the sandbox. Rather than setting the current sandbox, * we partially fake this out by only setting the module_indirect_table and then clearing after table diff --git a/runtime/src/sandbox.c b/runtime/src/sandbox.c index 6ca629b..c02f691 100644 --- a/runtime/src/sandbox.c +++ b/runtime/src/sandbox.c @@ -10,7 +10,7 @@ /** * Allocates a WebAssembly sandbox represented by the following layout - * struct sandbox | Buffer for HTTP Req/Resp | 4GB of Wasm Linear Memory | Guard Page + * struct sandbox | HTTP Req Buffer | HTTP Resp Buffer | 4GB of Wasm Linear Memory | Guard Page * @param module the module that we want to run * @returns the resulting sandbox or NULL if mmap failed */ @@ -19,22 +19,25 @@ sandbox_allocate_memory(struct module *module) { assert(module != NULL); - char * error_message = NULL; - unsigned long memory_size = WASM_PAGE_SIZE * WASM_MEMORY_PAGES_INITIAL; /* The initial pages */ - uint64_t memory_max = (uint64_t)WASM_PAGE_SIZE * WASM_MEMORY_PAGES_MAX; - struct sandbox *sandbox = NULL; - unsigned long sandbox_size = sizeof(struct sandbox) + module->max_request_or_response_size; + char * error_message = NULL; + unsigned long memory_size = WASM_PAGE_SIZE * WASM_MEMORY_PAGES_INITIAL; /* The initial pages */ + uint64_t memory_max = (uint64_t)WASM_PAGE_SIZE * WASM_MEMORY_PAGES_MAX; + struct sandbox *sandbox = NULL; + unsigned long page_aligned_sandbox_size = round_up_to_page(sizeof(struct sandbox)); + + unsigned long size_to_alloc = page_aligned_sandbox_size + module->max_request_size + module->max_request_size + + memory_max + /* guard page */ PAGE_SIZE; + unsigned long size_to_read_write = page_aligned_sandbox_size + module->max_request_size + + module->max_request_size + memory_size; /* * Control information should be page-aligned - * TODO: Should I use round_up_to_page when setting sandbox_page? Issue #50 */ - assert(round_up_to_page(sandbox_size) == sandbox_size); + assert(round_up_to_page(size_to_alloc) == size_to_alloc); /* At an address of the system's choosing, allocate the memory, marking it as inaccessible */ errno = 0; - void *addr = mmap(NULL, sandbox_size + memory_max + /* guard page */ PAGE_SIZE, PROT_NONE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + void *addr = mmap(NULL, size_to_alloc, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (addr == MAP_FAILED) { error_message = "sandbox_allocate_memory - memory allocation failed"; goto alloc_failed; @@ -44,8 +47,8 @@ sandbox_allocate_memory(struct module *module) /* Set the struct sandbox, HTTP Req/Resp buffer, and the initial Wasm Pages as read/write */ errno = 0; - void *addr_rw = mmap(addr, sandbox_size + memory_size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); + void *addr_rw = mmap(addr, size_to_read_write, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, + -1, 0); if (addr_rw == MAP_FAILED) { error_message = "set to r/w"; goto set_rw_failed; @@ -54,20 +57,27 @@ sandbox_allocate_memory(struct module *module) sandbox = (struct sandbox *)addr_rw; /* Populate Sandbox members */ - sandbox->state = SANDBOX_UNINITIALIZED; - sandbox->memory.start = (char *)addr + sandbox_size; - sandbox->memory.size = memory_size; - sandbox->memory.max = memory_max; - sandbox->module = module; - sandbox->sandbox_size = sandbox_size; + sandbox->state = SANDBOX_UNINITIALIZED; + sandbox->module = module; module_acquire(module); + sandbox->request.base = (char *)addr + page_aligned_sandbox_size; + sandbox->request.length = 0; + + sandbox->response.base = (char *)addr + page_aligned_sandbox_size + module->max_request_size; + sandbox->request.length = 0; + + sandbox->memory.start = (char *)addr + page_aligned_sandbox_size + module->max_request_size + + module->max_request_size; + sandbox->memory.size = memory_size; + sandbox->memory.max = memory_max; + done: return sandbox; set_rw_failed: sandbox = NULL; errno = 0; - int rc = munmap(addr, sandbox_size + memory_size + PAGE_SIZE); + int rc = munmap(addr, size_to_alloc); if (rc == -1) perror("Failed to munmap after fail to set r/w"); alloc_failed: err: @@ -185,17 +195,19 @@ sandbox_free(struct sandbox *sandbox) }; - /* Free Remaining Sandbox Linear Address Space - * sandbox_size includes the struct and HTTP buffer + /* Free Sandbox Struct and HTTP Request and Response Buffers * The linear memory was already freed during the transition from running to error|complete - * struct sandbox | HTTP Buffer | 4GB of Wasm Linear Memory | Guard Page - * Allocated | Allocated | Freed | Freed + * struct sandbox | HTTP Request Buffer | HTTP Response Buffer | 4GB of Wasm Linear Memory | Guard Page + * Allocated | Allocated | Allocated | Freed | Freed */ /* Linear Memory and Guard Page should already have been munmaped and set to NULL */ assert(sandbox->memory.start == NULL); errno = 0; - rc = munmap(sandbox, sandbox->sandbox_size); + + unsigned long size_to_unmap = round_up_to_page(sizeof(struct sandbox)) + sandbox->module->max_request_size + + sandbox->module->max_response_size; + munmap(sandbox, size_to_unmap); if (rc == -1) { debuglog("Failed to unmap Sandbox %lu\n", sandbox->id); goto err_free_sandbox_failed; diff --git a/runtime/tests/Makefile b/runtime/tests/Makefile index 61aa2c0..14388e6 100644 --- a/runtime/tests/Makefile +++ b/runtime/tests/Makefile @@ -13,12 +13,21 @@ rttests: $(TESTSRT) clean: @echo "Cleaning Test Applications" - @rm -rf ${TMP_DIR} - @rm -rf ${SLEDGE_BIN_DIR}/*_wasm.so - @make clean -C ./TinyEKF/extras/c/ -f wasm.mk - @make clean -C ./CMSIS_5_NN/ -f Makefile - @make clean -C ./gocr/src/ -f wasm.mk - @make clean -C ./sod/ + @make clean -C ./empty/ + @rm -f wasm/empty.wasm bc/empty.bc so/empty.so + @rm -rf ${SLEDGE_BIN_DIR}/empty.so ${SLEDGE_BIN_DIR}/test_empty.json + + @make clean -C ./echo/ + @rm -f wasm/echo.wasm bc/echo.bc so/echo.so + @rm -rf ${SLEDGE_BIN_DIR}/echo.so ${SLEDGE_BIN_DIR}/test_echo.json + + @make clean -C ./fibonacci/ + @rm -f wasm/fibonacci.wasm bc/fibonacci.bc so/fibonacci.so + @rm -rf ${SLEDGE_BIN_DIR}/fibonacci.so ${SLEDGE_BIN_DIR}/test_fibonacci.json + + @make clean -C ./TinyEKF/ -f wasm.mk + @rm -f wasm/gps_ekf.wasm bc/gps_ekf.bc so/gps_ekf.so + @rm -rf ${SLEDGE_BIN_DIR}/gps_ekf.so ${SLEDGE_BIN_DIR}/test_gps_ekf.json tinyekf: @echo "Making and Installing tinyekf"