diff options
author | KJ Tsanaktsidis <[email protected]> | 2023-11-12 13:34:43 +1100 |
---|---|---|
committer | KJ Tsanaktsidis <[email protected]> | 2024-01-12 17:29:48 +1100 |
commit | 6185cfdf38e26026c6d38220eeca48689e54cdcf (patch) | |
tree | f3d4af0fc1949270206a97217e844f1d8f5ea895 /thread_pthread.c | |
parent | 4ba8f0dc993953d3ddda6328e3ef17a2fc2cbde5 (diff) |
Make stack bounds detection work with ASAN
Where a local variable is used as part of the stack bounds detection, it
has to actually be on the stack. ASAN can put local variable on "fake
stacks", however, with addresses in different memory mappings. This
completely destroys the stack bounds calculation, and can lead to e.g.
things not getting GC marked on the machine stack or stackoverflow
checks that always fail.
The __asan_addr_is_in_fake_stack helper can be used to get the _real_
stack address of such variables, and thus perform the stack size
calculation properly
[Bug #20001]
Diffstat (limited to 'thread_pthread.c')
-rw-r--r-- | thread_pthread.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/thread_pthread.c b/thread_pthread.c index a6a6c9d127..af50d50699 100644 --- a/thread_pthread.c +++ b/thread_pthread.c @@ -12,6 +12,7 @@ #ifdef THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION #include "internal/gc.h" +#include "internal/sanitizers.h" #include "rjit.h" #ifdef HAVE_SYS_RESOURCE_H @@ -1967,6 +1968,7 @@ void ruby_init_stack(volatile void *addr) { native_main_thread.id = pthread_self(); + addr = asan_get_real_stack_addr((void *)addr); #if MAINSTACKADDR_AVAILABLE if (native_main_thread.stack_maxsize) return; @@ -2065,7 +2067,7 @@ native_thread_init_stack(rb_thread_t *th, void *local_in_parent_frame) if (get_stack(&start, &size) == 0) { uintptr_t diff = (uintptr_t)start - (uintptr_t)local_in_parent_frame; - th->ec->machine.stack_start = (uintptr_t)local_in_parent_frame; + th->ec->machine.stack_start = asan_get_real_stack_addr(local_in_parent_frame); th->ec->machine.stack_maxsize = size - diff; } } @@ -2192,12 +2194,10 @@ call_thread_start_func_2(rb_thread_t *th) on a new thread, and replacing that data on fiber-switch would break it (see bug #13887) */ VALUE stack_start = 0; - VALUE *stack_start_addr = &stack_start; + VALUE *stack_start_addr = asan_get_real_stack_addr(&stack_start); + native_thread_init_stack(th, stack_start_addr); thread_start_func_2(th, th->ec->machine.stack_start); - - /* Ensure that stack_start really was spilled to the stack */ - RB_GC_GUARD(stack_start) } static void * |