bytecodealliance / wasm-micro-runtime

WebAssembly Micro Runtime (WAMR)
Apache License 2.0
4.99k stars 628 forks source link

Stack-buffer-overflow in wasm-micro-runtime/core/iwasm/interpreter/wasm_interp_classic.c #3561

Open Messi-Q opened 5 months ago

Messi-Q commented 5 months ago

Version

commit 0418041 Author: Peng Qian messi.qp711@gmail.com Date: Fri Jun 21:11:08 2024

Compile

cd wasm-micro-runtime/product-mini/platforms/linux
mkdir build
cd build 
cmake -DCMAKE_CXX_FLAGS="-fsanitize=address -fno-omit-frame-pointer" -DCMAKE_C_FLAGS="-fsanitize=address -fno-omit-frame-pointer" -DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address" -DCMAKE_SHARED_LINKER_FLAGS="-fsanitize=address" -DWAMR_BUILD_INTERP=1 -DWAMR_BUILD_FAST_INTERP=0 ..
make

Reproduce

./iwasm id:000071,sig:06,src:000585,op:python,pos:0

ASAN Log

================================================================= ==534898==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffe820f6400 at pc 0x7fdc0905ca6a bp 0x7ffe820f63c0 sp 0x7ffe820f5b68 WRITE of size 128 at 0x7ffe820f6400 thread T0

0 0x7fdc0905ca69 in __interceptor_sigemptyset ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:3959

#1 0x56475fb4299b in mask_signals /home/peng/Documents/all_wasm_vm/new_version_test/wasm-micro-runtime/core/shared/platform/common/posix/posix_thread.c:580
#2 0x56475faf637d in call_wasm_with_hw_bound_check /home/peng/Documents/all_wasm_vm/new_version_test/wasm-micro-runtime/core/iwasm/interpreter/wasm_runtime.c:3353
#3 0x56475faf8ba2 in wasm_call_function /home/peng/Documents/all_wasm_vm/new_version_test/wasm-micro-runtime/core/iwasm/interpreter/wasm_runtime.c:3380
#4 0x56475fae9a50 in wasm_runtime_call_wasm /home/peng/Documents/all_wasm_vm/new_version_test/wasm-micro-runtime/core/iwasm/common/wasm_runtime_common.c:2423
#5 0x56475fae0e53 in execute_main /home/peng/Documents/all_wasm_vm/new_version_test/wasm-micro-runtime/core/iwasm/common/wasm_application.c:126
#6 0x56475fae0e53 in wasm_application_execute_main /home/peng/Documents/all_wasm_vm/new_version_test/wasm-micro-runtime/core/iwasm/common/wasm_application.c:285
#7 0x56475fada8e6 in app_instance_main /home/peng/Documents/all_wasm_vm/new_version_test/wasm-micro-runtime/product-mini/platforms/linux/../posix/main.c:119
#8 0x56475fada8e6 in main /home/peng/Documents/all_wasm_vm/new_version_test/wasm-micro-runtime/product-mini/platforms/linux/../posix/main.c:995
#9 0x7fdc08cdc082 in __libc_start_main ../csu/libc-start.c:308
#10 0x56475fadbffd in _start (/home/peng/Documents/all_wasm_vm/new_version_test/wasm-micro-runtime/product-mini/platforms/linux/build/iwasm+0x22ffd)

Address 0x7ffe820f6400 is located in stack of thread T0 at offset 160 in frame

0 0x56475fbbc94f in wasm_interp_call_wasm /home/peng/Documents/all_wasm_vm/new_version_test/wasm-micro-runtime/core/iwasm/interpreter/wasm_interp_classic.c:7121

This frame has 1 object(s): [32, 160) 'buf' (line 7129) <== Memory access at offset 160 overflows this variable HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork (longjmp and C++ exceptions are supported) SUMMARY: AddressSanitizer: stack-buffer-overflow ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:3959 in __interceptor_sigemptyset Shadow bytes around the buggy address: 0x100050416c30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100050416c40: 00 00 00 00 00 00 f1 f1 f1 f1 f1 f1 01 f2 00 f2 0x100050416c50: f2 f2 00 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 0x100050416c60: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 0x100050416c70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x100050416c80:[f3]f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00 0x100050416c90: 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 f1 f1 0x100050416ca0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100050416cb0: 00 00 00 00 00 00 00 00 00 00 f3 f3 f3 f3 f3 f3 0x100050416cc0: f3 f3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100050416cd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb Shadow gap: cc ==534898==ABORTING

PoC

PoC

wenyongh commented 5 months ago

@Messi-Q thanks for spotting the issue, from the call stack dumped, the stack-buffer-overflow occurs in function mask_signals in file posix_thread.c, L580: https://github.com/bytecodealliance/wasm-micro-runtime/blob/4c2af25aff9de6df2c23083840f1ff783e7ebbcb/core/shared/platform/common/posix/posix_thread.c#L572-L580

But as you see, this function is set with __attribute__((no_sanitize_address)) which means address sanitizer should not be applied for it since it does some low-level magic (e.g. stack, signal related operations), but I am not sure why __attribute__((no_sanitize_address)) doesn't take effect in you environment. What is the compiler you used, is it clang or gcc? Could you modify the function to be like below:

#if defined(__GNUC__)
__attribute__((no_sanitize_address))
#elif defined(__clang__)
__attribute__((no_sanitize("address")))
#endif
static void
mask_signals(int how)
{
    ...
}

and try again? Thanks.