wasm-micro-runtime icon indicating copy to clipboard operation
wasm-micro-runtime copied to clipboard

Use uint32_t for value passed to memmove and memset

Open nchamzn opened this issue 1 year ago • 3 comments
trafficstars

On a 64 bit host the top bits of n here can be garbage (as the value is 32bit in the wasm memory).

I have promised @loganek I'll write some tests for this in tests/wamr-compiler but so far I haven't made a minimal reproduction, will update the PR when I've done that.

nchamzn avatar Apr 29 '24 11:04 nchamzn

@nchamzn thanks for the PR to fix the issue, it is a good catch!

I think we had better fix it by changing the aot compiler since in wasm memory64 spec proposal, when a memory is 64bit, the length for the opcode memory.fill and memory.copy is u64 but not u32, so here changing the argument to uint32 may cause integer truncation and make the memset/memmov failed if the length is larger than UINT32_MAX. Refer to: https://github.com/WebAssembly/memory64/blob/main/proposals/memory64/Overview.md#overview https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/core/iwasm/interpreter/wasm_interp_classic.c#L5651

I uploaded a patch for a reference, could you help check whether it is better (please feel free to change if issue is found):

diff --git a/core/iwasm/compilation/aot_emit_memory.c b/core/iwasm/compilation/aot_emit_memory.c
index eedc5420..caccaef9 100644
--- a/core/iwasm/compilation/aot_emit_memory.c
+++ b/core/iwasm/compilation/aot_emit_memory.c
@@ -1090,6 +1090,14 @@ aot_compile_op_memory_copy(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
     if (!(dst_addr = check_bulk_memory_overflow(comp_ctx, func_ctx, dst, len)))
         return false;

+    if (comp_ctx->pointer_size == sizeof(uint64)) {
+        len = LLVMBuildZExt(comp_ctx->builder, len, I64_TYPE, "len64");
+        if (!len) {
+            aot_set_last_error("llvm build bitcast failed.");
+            return false;
+        }
+    }
+
     call_aot_memmove = comp_ctx->is_indirect_mode || comp_ctx->is_jit_mode;
     if (call_aot_memmove) {
         LLVMTypeRef param_types[3], ret_type, func_type, func_ptr_type;
@@ -1097,7 +1105,7 @@ aot_compile_op_memory_copy(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)

         param_types[0] = INT8_PTR_TYPE;
         param_types[1] = INT8_PTR_TYPE;
-        param_types[2] = I32_TYPE;
+        param_types[2] = INTPTR_T_TYPE;
         ret_type = INT8_PTR_TYPE;

         if (!(func_type = LLVMFunctionType(ret_type, param_types, 3, false))) {
@@ -1172,9 +1180,17 @@ aot_compile_op_memory_fill(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
     if (!(dst_addr = check_bulk_memory_overflow(comp_ctx, func_ctx, dst, len)))
         return false;

+    if (comp_ctx->pointer_size == sizeof(uint64)) {
+        len = LLVMBuildZExt(comp_ctx->builder, len, I64_TYPE, "len64");
+        if (!len) {
+            aot_set_last_error("llvm build bitcast failed.");
+            return false;
+        }
+    }
+
     param_types[0] = INT8_PTR_TYPE;
     param_types[1] = I32_TYPE;
-    param_types[2] = I32_TYPE;
+    param_types[2] = INTPTR_T_TYPE;
     ret_type = INT8_PTR_TYPE;

     if (!(func_type = LLVMFunctionType(ret_type, param_types, 3, false))) {

wenyongh avatar Apr 29 '24 12:04 wenyongh

Hi, thanks for looking - yes your suggestion looks good to me

nchamzn avatar Apr 29 '24 14:04 nchamzn

Hi, thanks for looking - yes your suggestion looks good to me

Welcome, I submitted PR #3378 to fix it with more comments added. Could you help check again? I think maybe we can merge it first if it is good and don't block the AOT memory64 feature (#3362) that @loganek is enabling, and then you can also update the tests in tests/wamr-compiler.

wenyongh avatar Apr 30 '24 00:04 wenyongh

Close this PR since the issue was fixed with https://github.com/bytecodealliance/wasm-micro-runtime/pull/3378.

wenyongh avatar May 10 '24 23:05 wenyongh