Skip to content

wasm_runtime_detect_native_stack_overflow works incorrectly under ASAN #4638

@vchigrin

Description

@vchigrin

wasm_runtime_detect_native_stack_overflow function compares address of local variable with stack boundary here

if ((uint8 *)&boundary < boundary) {

But under ASAN local variables placed on "Fake stack" https://github.com/google/sanitizers/wiki/AddressSanitizerUseAfterReturn#algorithm , so this comparison often produces wrong results, reporting "native stack overflow".

I have no minimal reproducible example for WAMR itself, but here is how that API works under Linux:
Test file

#define _GNU_SOURCE
#include <pthread.h>
#include <stdio.h>

int main(int argc, char* argv[]) {
  int dummy;
  pthread_t self;
  pthread_attr_t attr;
  size_t stack_size;
  void* addr;

  self = pthread_self();
  if (pthread_getattr_np(self, &attr) != 0) {
    printf("Failed get attr\n");
    return 1;
  }
  pthread_attr_getstack(&attr, &addr, &stack_size);
  printf("Stack %p size %zX; Current frame %p\n", addr, stack_size, &dummy);
  pthread_attr_destroy(&attr);
  return 0;
}

Normal run

clang-18 test.c && ./a.out
Stack 0x7ffcc529e000 size 7FF000; Current frame 0x7ffcc5a9ce4c

You see, 0x7ffcc529e000 is less then 0x7ffcc5a9ce4c, so everything works as expected.

ASAN run

clang-18 -fsanitize=address test.c && ./a.out
Stack 0x7fff01009000 size 7FE000; Current frame 0x7fa947d00020

0x7fff01009000 is bigger then 0x7fa947d00020, so check based on this assumption may wrongly decide that "stack already overflown"

Your environment

  • Linux

I suggest disabling all logic in wasm_runtime_detect_native_stack_overflow if condition #if __has_feature(address_sanitizer) is true.

If this is OK, I can provide patch.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions