Stream: git-wasmtime

Topic: wasmtime / issue #3061 UD2 is executed when a function ca...


view this post on Zulip Wasmtime GitHub notifications bot (Jul 04 2021 at 16:27):

Encrylize opened issue #3061:

Test Case

trap.c:

#include <wasm.h>
#include <wasmtime.h>

int main(void) {
    wasm_engine_t* engine = wasm_engine_new();
    wasm_store_t* store = wasm_store_new(engine);

    wasm_byte_vec_t binary;
    const char* wat = "(module (func (export \"trap\") (unreachable)))";
    wasmtime_wat2wasm(wat, strlen(wat), &binary);
    wasm_module_t* module = wasm_module_new(store, &binary);

    wasm_byte_vec_delete(&binary);

    wasm_extern_vec_t imports = WASM_EMPTY_VEC;
    wasm_instance_t* instance = wasm_instance_new(store, module, &imports, NULL);

    wasm_extern_vec_t exports;
    wasm_instance_exports(instance, &exports);

    const wasm_func_t* func = wasm_extern_as_func(exports.data[0]);

    const wasm_val_vec_t args = WASM_EMPTY_VEC;
    wasm_val_vec_t results = WASM_EMPTY_VEC;
    wasm_trap_t* trap = wasm_func_call(func, &args, &results);
    wasm_trap_delete(trap);

    wasm_extern_vec_delete(&exports);
    wasm_module_delete(module);
    wasm_instance_delete(instance);
    wasm_store_delete(store);
    wasm_engine_delete(engine);

    return 0;
}

Steps to Reproduce

Expected Results

The UD2 instruction should not be executed and no warnings should be emitted by Valgrind.

Actual Results

The UD2 instruction is executed as shown by LLDB:

$ lldb ./trap
(lldb) target create "./trap"
Current executable set to '/home/jfb/projects/wasm/trap' (x86_64).
(lldb) r
Process 301185 launched: '/home/jfb/projects/wasm/trap' (x86_64)
Process 301185 stopped
* thread #1, name = 'trap', stop reason = signal SIGILL: illegal instruction operand
    frame #0: 0x00007ffff7fb7004
->  0x7ffff7fb7004: ud2
    0x7ffff7fb7006: pushq  %rbp
    0x7ffff7fb7007: movq   %rsp, %rbp
    0x7ffff7fb700a: callq  *%rdx
(lldb) c
Process 301185 resuming
Process 301185 exited with status = 0 (0x00000000)
(lldb) exit

Valgrind emits a warning about the client switching stacks:

$ valgrind ./trap
==302700== Memcheck, a memory error detector
==302700== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==302700== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==302700== Command: ./trap
==302700==
==302700== valgrind: Unrecognised instruction at address 0x4850004.
==302700==    at 0x4850004: ???
==302700==    by 0x485000B: ???
==302700==    by 0x4E2548F: wasmtime_setjmp (in /usr/lib/libwasmtime.so)
==302700==    by 0x4980838: wasmtime_runtime::traphandlers::catch_traps (in /usr/lib/libwasmtime.so)
==302700==    by 0x496DE16: wasmtime::func::Func::call (in /usr/lib/libwasmtime.so)
==302700==    by 0x4A22DE3: wasm_func_call (in /usr/lib/libwasmtime.so)
==302700==    by 0x10935D: main (in /home/jfb/projects/wasm/trap)
==302700== Your program just tried to execute an instruction that Valgrind
==302700== did not recognise.  There are two possible reasons for this.
==302700== 1. Your program has a bug and erroneously jumped to a non-code
==302700==    location.  If you are running Memcheck and you just saw a
==302700==    warning about a bad jump, it's probably your program's fault.
==302700== 2. The instruction is legitimate but Valgrind doesn't handle it,
==302700==    i.e. it's Valgrind's fault.  If you think this is the case or
==302700==    you are not sure, please let us know and we'll try to fix it.
==302700== Either way, Valgrind will now raise a SIGILL signal which will
==302700== probably kill your program.
==302700== Warning: client switching stacks?  SP change: 0x5aaa068 --> 0x1ffefffd00
==302700==          to suppress, use: --max-stackframe=137327107224 or greater
==302700==
==302700== HEAP SUMMARY:
==302700==     in use at exit: 920 bytes in 7 blocks
==302700==   total heap usage: 659 allocs, 652 frees, 152,738 bytes allocated
==302700==
==302700== LEAK SUMMARY:
==302700==    definitely lost: 0 bytes in 0 blocks
==302700==    indirectly lost: 0 bytes in 0 blocks
==302700==      possibly lost: 0 bytes in 0 blocks
==302700==    still reachable: 920 bytes in 7 blocks
==302700==         suppressed: 0 bytes in 0 blocks
==302700== Rerun with --leak-check=full to see details of leaked memory
==302700==
==302700== For lists of detected and suppressed errors, rerun with: -s
==302700== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Versions and Environment

Wasmtime version or commit: Commit c71ad9490

Operating system: Arch Linux

Architecture: x86_64

view this post on Zulip Wasmtime GitHub notifications bot (Jul 04 2021 at 16:27):

Encrylize labeled issue #3061:

Test Case

trap.c:

#include <wasm.h>
#include <wasmtime.h>

int main(void) {
    wasm_engine_t* engine = wasm_engine_new();
    wasm_store_t* store = wasm_store_new(engine);

    wasm_byte_vec_t binary;
    const char* wat = "(module (func (export \"trap\") (unreachable)))";
    wasmtime_wat2wasm(wat, strlen(wat), &binary);
    wasm_module_t* module = wasm_module_new(store, &binary);

    wasm_byte_vec_delete(&binary);

    wasm_extern_vec_t imports = WASM_EMPTY_VEC;
    wasm_instance_t* instance = wasm_instance_new(store, module, &imports, NULL);

    wasm_extern_vec_t exports;
    wasm_instance_exports(instance, &exports);

    const wasm_func_t* func = wasm_extern_as_func(exports.data[0]);

    const wasm_val_vec_t args = WASM_EMPTY_VEC;
    wasm_val_vec_t results = WASM_EMPTY_VEC;
    wasm_trap_t* trap = wasm_func_call(func, &args, &results);
    wasm_trap_delete(trap);

    wasm_extern_vec_delete(&exports);
    wasm_module_delete(module);
    wasm_instance_delete(instance);
    wasm_store_delete(store);
    wasm_engine_delete(engine);

    return 0;
}

Steps to Reproduce

Expected Results

The UD2 instruction should not be executed and no warnings should be emitted by Valgrind.

Actual Results

The UD2 instruction is executed as shown by LLDB:

$ lldb ./trap
(lldb) target create "./trap"
Current executable set to '/home/jfb/projects/wasm/trap' (x86_64).
(lldb) r
Process 301185 launched: '/home/jfb/projects/wasm/trap' (x86_64)
Process 301185 stopped
* thread #1, name = 'trap', stop reason = signal SIGILL: illegal instruction operand
    frame #0: 0x00007ffff7fb7004
->  0x7ffff7fb7004: ud2
    0x7ffff7fb7006: pushq  %rbp
    0x7ffff7fb7007: movq   %rsp, %rbp
    0x7ffff7fb700a: callq  *%rdx
(lldb) c
Process 301185 resuming
Process 301185 exited with status = 0 (0x00000000)
(lldb) exit

Valgrind emits a warning about the client switching stacks:

$ valgrind ./trap
==302700== Memcheck, a memory error detector
==302700== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==302700== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==302700== Command: ./trap
==302700==
==302700== valgrind: Unrecognised instruction at address 0x4850004.
==302700==    at 0x4850004: ???
==302700==    by 0x485000B: ???
==302700==    by 0x4E2548F: wasmtime_setjmp (in /usr/lib/libwasmtime.so)
==302700==    by 0x4980838: wasmtime_runtime::traphandlers::catch_traps (in /usr/lib/libwasmtime.so)
==302700==    by 0x496DE16: wasmtime::func::Func::call (in /usr/lib/libwasmtime.so)
==302700==    by 0x4A22DE3: wasm_func_call (in /usr/lib/libwasmtime.so)
==302700==    by 0x10935D: main (in /home/jfb/projects/wasm/trap)
==302700== Your program just tried to execute an instruction that Valgrind
==302700== did not recognise.  There are two possible reasons for this.
==302700== 1. Your program has a bug and erroneously jumped to a non-code
==302700==    location.  If you are running Memcheck and you just saw a
==302700==    warning about a bad jump, it's probably your program's fault.
==302700== 2. The instruction is legitimate but Valgrind doesn't handle it,
==302700==    i.e. it's Valgrind's fault.  If you think this is the case or
==302700==    you are not sure, please let us know and we'll try to fix it.
==302700== Either way, Valgrind will now raise a SIGILL signal which will
==302700== probably kill your program.
==302700== Warning: client switching stacks?  SP change: 0x5aaa068 --> 0x1ffefffd00
==302700==          to suppress, use: --max-stackframe=137327107224 or greater
==302700==
==302700== HEAP SUMMARY:
==302700==     in use at exit: 920 bytes in 7 blocks
==302700==   total heap usage: 659 allocs, 652 frees, 152,738 bytes allocated
==302700==
==302700== LEAK SUMMARY:
==302700==    definitely lost: 0 bytes in 0 blocks
==302700==    indirectly lost: 0 bytes in 0 blocks
==302700==      possibly lost: 0 bytes in 0 blocks
==302700==    still reachable: 920 bytes in 7 blocks
==302700==         suppressed: 0 bytes in 0 blocks
==302700== Rerun with --leak-check=full to see details of leaked memory
==302700==
==302700== For lists of detected and suppressed errors, rerun with: -s
==302700== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Versions and Environment

Wasmtime version or commit: Commit c71ad9490

Operating system: Arch Linux

Architecture: x86_64


Last updated: Dec 23 2024 at 12:05 UTC