Explorar o código

Merge commit from fork

Zhenwei Jin hai 1 mes
pai
achega
33fdc4a671

+ 19 - 3
core/iwasm/interpreter/wasm_loader.c

@@ -9720,6 +9720,16 @@ preserve_local_for_block(WASMLoaderContext *loader_ctx, uint8 opcode,
 
     /* preserve locals before blocks to ensure that "tee/set_local" inside
         blocks will not influence the value of these locals */
+    uint32 frame_offset_cell =
+        (uint32)(loader_ctx->frame_offset - loader_ctx->frame_offset_bottom);
+    uint32 frame_ref_cell =
+        (uint32)(loader_ctx->frame_ref - loader_ctx->frame_ref_bottom);
+    if (frame_offset_cell < loader_ctx->stack_cell_num
+        || frame_ref_cell < loader_ctx->stack_cell_num) {
+        set_error_buf(error_buf, error_buf_size, "stack cell num error");
+        return false;
+    }
+
     while (i < loader_ctx->stack_cell_num) {
         int16 cur_offset = loader_ctx->frame_offset_bottom[i];
         uint8 cur_type = loader_ctx->frame_ref_bottom[i];
@@ -12106,13 +12116,19 @@ re_scan:
                         }
 #endif
 
+                        uint8 *frame_ref_before_pop = loader_ctx->frame_ref;
                         POP_TYPE(
                             wasm_type->types[wasm_type->param_count - i - 1]);
 #if WASM_ENABLE_FAST_INTERP != 0
                         /* decrease the frame_offset pointer accordingly to keep
-                         * consistent with frame_ref stack */
-                        cell_num = wasm_value_type_cell_num(
-                            wasm_type->types[wasm_type->param_count - i - 1]);
+                         * consistent with frame_ref stack. Use the actual
+                         * popped cell count instead of
+                         * wasm_value_type_cell_num() because when the stack top
+                         * is VALUE_TYPE_ANY, wasm_loader_pop_frame_ref always
+                         * pops exactly 1 cell regardless of the expected type
+                         */
+                        cell_num = (uint32)(frame_ref_before_pop
+                                            - loader_ctx->frame_ref);
                         loader_ctx->frame_offset -= cell_num;
 
                         if (loader_ctx->frame_offset

BIN=BIN
tests/regression/ba-issues/issues/issue-980000/frame_offset_overflow.wasm


+ 70 - 0
tests/regression/ba-issues/issues/issue-980000/frame_offset_overflow.wat

@@ -0,0 +1,70 @@
+(module
+  (global $g0 (mut i32) (i32.const 0))
+  (global $g1 (mut i32) (i32.const 0))
+  (global $g2 (mut i32) (i32.const 0))
+  (global $g3 (mut i32) (i32.const 0))
+  (global $g4 (mut i32) (i32.const 0))
+  (global $g5 (mut i32) (i32.const 0))
+  (global $g6 (mut i32) (i32.const 0))
+  (global $g7 (mut i32) (i32.const 0))
+
+  (export "test" (func $0))
+  (func $0
+    (local i32)
+
+    global.get $g0
+    global.get $g1
+    global.get $g2
+    global.get $g3
+    global.get $g4
+    global.get $g5
+    global.get $g6
+    global.get $g7
+    global.get $g0
+    global.get $g1
+    global.get $g2
+    global.get $g3
+    global.get $g4
+    global.get $g5
+    global.get $g6
+    global.get $g7
+    global.get $g0
+    global.get $g1
+    global.get $g2
+    global.get $g3
+    global.get $g4
+    global.get $g4
+    global.get $g4
+    global.get $g4
+    global.get $g4
+    global.get $g4
+    global.get $g4
+    global.get $g4
+    global.get $g4
+    global.get $g0
+
+    ;; has consumed 30 elements, left 2 elements on stack
+    block
+     block
+        f64.const 3.14
+        ;; RESET current block stack and mark polymorphic
+        unreachable
+        ;; PUSH ANY
+        select
+
+        loop (param i64) (result i32)
+          ;; NOW, unmatched stacks. Enlarge frame_ref stack. Keep frame_offset stack unchanged.
+          global.get $g0
+          i32.eqz
+          ;; OUT-OF-BOUNDS
+          if
+            unreachable
+          end
+          i32.wrap_i64
+        end
+        local.set 0
+      end
+    end 
+    unreachable
+  )
+)

+ 16 - 0
tests/regression/ba-issues/running_config.json

@@ -1786,6 +1786,22 @@
                 "stdout content": "",
                 "description": "load successfully"
             }
+        },
+        {
+            "deprecated": false,
+            "ids": [
+                980000
+            ],
+            "runtime": "iwasm-default",
+            "file": "frame_offset_overflow.wasm",
+            "mode": "fast-interp",
+            "options": "-f test",
+            "argument": "",
+            "expected return": {
+                "ret code": 1,
+                "stdout content": "Exception: unreachable",
+                "description": "no 'frame offset overflow'"
+            }
         }
     ]
 }