From d5efa5f11f38d4ca6c64374f848055611d4f315c Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Thu, 14 Sep 2023 00:37:28 +0100 Subject: Wasm: Fix multiple successive calls to the request_handler. When trying to upload files to the luw-upload-reflector demo[0] above a certain size that would mean Unit would need to make more than two calls to the request_handler function in the Wasm module we would get the following error from wasmtime and the upload would stall on the third call to the request_handler WASMTIME ERROR: failed to call function [->wasm_request_handler] error while executing at wasm backtrace: 0: 0x5ce2 - !memcpy 1: 0x7df - luw_req_buf_append at /home/andrew/src/unit-wasm/src/c/libunit-wasm.c:308:14 2: 0x3a1 - luw_request_handler at /home/andrew/src/unit-wasm/examples/c/luw-upload-reflector.c:110:3 Caused by: wasm trap: out of bounds memory access This was due to ->content_off (the offset of where the actual body content starts in the request structure/memory) being some overly large value. This was largely down to me being an idiot! Before calling the loop that makes the calls to the request_handler we would calculate the new offset, which is now just the size of the request structure as we don't re-send all the HTTP meta data and headers etc. However because this value is in the request structure which is in the shared memory and we use this same memory for requests and responses, when we make a response we overwrite this request structure with the response structure, so our ->content_off is now some wacked out value when we make the next call to the request_handler. To fix this we just need to reset ->content_off each time round the loop. There's also no point in setting ->nfields to 0, it has the same issue as above, but doesn't get re-used by the Wasm module anyway. [0]: Signed-off-by: Andrew Clayton --- src/wasm/nxt_wasm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wasm/nxt_wasm.c b/src/wasm/nxt_wasm.c index 796ea847..92ed57ab 100644 --- a/src/wasm/nxt_wasm.c +++ b/src/wasm/nxt_wasm.c @@ -166,8 +166,7 @@ nxt_wasm_request_handler(nxt_unit_request_info_t *req) goto request_done; } - wr->nfields = 0; - wr->content_off = offset = sizeof(nxt_wasm_request_t); + offset = sizeof(nxt_wasm_request_t); do { read_bytes = nxt_min(content_len - content_sent, NXT_WASM_MEM_SIZE - offset); @@ -177,6 +176,7 @@ nxt_wasm_request_handler(nxt_unit_request_info_t *req) content_sent += bytes_read; wr->request_size = wr->content_sent = bytes_read; wr->total_content_sent = content_sent; + wr->content_off = offset; err = nxt_wops->exec_request(&nxt_wasm_ctx); if (err) { -- cgit