Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Double Free or Corruption Error on Valid WebAssembly Module Load #2586

Closed
khagankhan opened this issue Sep 22, 2023 · 2 comments
Closed

Double Free or Corruption Error on Valid WebAssembly Module Load #2586

khagankhan opened this issue Sep 22, 2023 · 2 comments

Comments

@khagankhan
Copy link

Describe the Bug

When executing a valid WebAssembly module using the iwasm, the program terminates with a "double free or corruption" error, probably originating from the wasm_loader_ctx_destroy function in wasm_loader.c.

iwasm --version: iwasm 1.2.3

uname -a: Linux node0.wamr.randtest-pg0.utah.cloudlab.us 5.15.0-56-generic #62-Ubuntu SMP Tue Nov 22 19:54:14 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

Steps to reproduce:

  1. Save the crash.wat (Remove .txt extension)
  2. Install and build WABT toolkit (wat2wasm from WABT can be used to convert crash.wat into crash.wasm using: wat2wasm crash.wat -o crash.wasm. I have also added crash.wasm that obviates the need to use wat2wasm)
  3. Run iwasm crash.wasm
  4. Observe the abort.

Files that cause the abort:

crash.wat.txt (Remove .txt extension when to save)

crash.wasm.txt (Remove .txt extension when to save)

Observed Behavior:

iwasm crash.wasm 

double free or corruption (out)
Aborted

Expected behavior:

iwasm is supposed to run the module successfully. wasmer and wasmtime run the module successfully.

GDB Backtrace

Program received signal SIGABRT, Aborted.
__pthread_kill_implementation (no_tid=0, signo=6, threadid=140737350600640) at ./nptl/pthread_kill.c:44
44	./nptl/pthread_kill.c: No such file or directory.
(gdb) bt
#0  __pthread_kill_implementation (no_tid=0, signo=6, threadid=140737350600640)
    at ./nptl/pthread_kill.c:44
#1  __pthread_kill_internal (signo=6, threadid=140737350600640) at ./nptl/pthread_kill.c:78
#2  __GI___pthread_kill (threadid=140737350600640, signo=signo@entry=6) at ./nptl/pthread_kill.c:89
#3  0x00007ffff7ce5476 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#4  0x00007ffff7ccb7f3 in __GI_abort () at ./stdlib/abort.c:79
#5  0x00007ffff7d2c6f6 in __libc_message (action=action@entry=do_abort, 
    fmt=fmt@entry=0x7ffff7e7eb8c "%s\n") at ../sysdeps/posix/libc_fatal.c:155
#6  0x00007ffff7d43d7c in malloc_printerr (
    str=str@entry=0x7ffff7e817b0 "double free or corruption (out)") at ./malloc/malloc.c:5664
#7  0x00007ffff7d45ef0 in _int_free (av=0x7ffff7ebcc80 <main_arena>, p=0x55555588a2f0, 
    have_lock=<optimized out>) at ./malloc/malloc.c:4588
#8  0x00007ffff7d484d3 in __GI___libc_free (mem=<optimized out>) at ./malloc/malloc.c:3391
#9  0x000055555557fd09 in wasm_runtime_free_internal (ptr=<optimized out>)
    at /root/wasmoi/wasm-micro-runtime/core/iwasm/common/wasm_memory.c:233
#10 wasm_runtime_free (ptr=<optimized out>)
    at /root/wasmoi/wasm-micro-runtime/core/iwasm/common/wasm_memory.c:265
#11 0x00005555555eb16b in wasm_loader_ctx_destroy (ctx=ctx@entry=0x555555889f50)
    at /root/wasmoi/wasm-micro-runtime/core/iwasm/interpreter/wasm_loader.c:5333
#12 0x0000555555615f95 in wasm_loader_prepare_bytecode (error_buf_size=<optimized out>, 
    error_buf=<optimized out>, cur_func_idx=<optimized out>, func=<optimized out>, 
    module=<optimized out>)
    at /root/wasmoi/wasm-micro-runtime/core/iwasm/interpreter/wasm_loader.c:10129

Reduced code that caused the abort (cat crash.wat):

(module
  (type (;0;) (func (param i64 f32 f32) (result i32)))
  (type (;1;) (func (param i64) (result i32)))
  (func (;0;) (type 0) (param i64 f32 f32) (result i32)
    (local i32 i64 f32 f64)
    global.get 0
    i32.const 0
    if (result i32) ;; label = @1
      i32.const 1
    else
      i32.const 0
      br 0 (;@1;)
      global.get 0
      i32.add
    end
    br_if 0 (;@0;)
    drop
    local.get 4
    i32.const 0
    call_indirect (type 1)
  )
  (table (;0;) 2 funcref)
  (global (;0;) (mut i32) i32.const 0)

Additional information

A combination of AFL++ and Wasmlike, an Xsmith-based random program generator produced the snippet of code that found the issue. Xsmith Project

@wenyongh
Copy link
Contributor

Hi, thanks for reporting the issue! I fixed it with #2590, could you try again?

wenyongh added a commit that referenced this issue Sep 26, 2023
`wasm_loader_push_pop_frame_offset` may pop n operands by using
`loader_ctx->stack_cell_num` to check whether the operand can be
popped or not. While `loader_ctx->stack_cell_num` is updated in the
later `wasm_loader_push_pop_frame_ref`, the check may fail if the stack
is in polymorphic state and lead to `ctx->frame_offset` underflow.

Fix issue #2577 and #2586.
@khagankhan
Copy link
Author

Thank you very much! It appears to be fixed. Thanks for prompt response!

victoryang00 pushed a commit to victoryang00/wamr-aot-gc-checkpoint-restore that referenced this issue May 27, 2024
`wasm_loader_push_pop_frame_offset` may pop n operands by using
`loader_ctx->stack_cell_num` to check whether the operand can be
popped or not. While `loader_ctx->stack_cell_num` is updated in the
later `wasm_loader_push_pop_frame_ref`, the check may fail if the stack
is in polymorphic state and lead to `ctx->frame_offset` underflow.

Fix issue bytecodealliance#2577 and bytecodealliance#2586.
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants