diff options
author | KJ Tsanaktsidis <kj@kjtsanaktsidis.id.au> | 2024-02-24 19:32:17 +1100 |
---|---|---|
committer | KJ Tsanaktsidis <kj@kjtsanaktsidis.id.au> | 2024-03-25 14:57:04 +1100 |
commit | 2535a09e85dd68249d9f390db32313ddd482480e (patch) | |
tree | f9290f950abf34a82382ecbae8f92fa663deea4a /gc.c | |
parent | 48d3bdddbaeabed5fb6a97bfbe65e250d1383a9c (diff) | |
download | ruby-2535a09e85dd68249d9f390db32313ddd482480e.tar.gz |
Check ASAN fake stacks when marking non-current threads
Currently, we check the values on the machine stack & register state to
see if they're actually a pointer to an ASAN fake stack, and mark the
values on the fake stack too if required. However, we are only doing
that for the _current_ thread (the one actually running the GC), not for
any other thread in the program.
Make rb_gc_mark_machine_context (which is called for marking non-current
threads) perform the same ASAN fake stack handling that
mark_current_machine_context performs.
[Bug #20310]
Diffstat (limited to 'gc.c')
-rw-r--r-- | gc.c | 20 |
1 files changed, 16 insertions, 4 deletions
@@ -949,7 +949,7 @@ typedef struct rb_objspace { rb_postponed_job_handle_t finalize_deferred_pjob; #ifdef RUBY_ASAN_ENABLED - rb_execution_context_t *marking_machine_context_ec; + const rb_execution_context_t *marking_machine_context_ec; #endif } rb_objspace_t; @@ -6406,7 +6406,7 @@ gc_mark_machine_stack_location_maybe(rb_objspace_t *objspace, VALUE obj) gc_mark_maybe(objspace, obj); #ifdef RUBY_ASAN_ENABLED - rb_execution_context_t *ec = objspace->marking_machine_context_ec; + const rb_execution_context_t *ec = objspace->marking_machine_context_ec; void *fake_frame_start; void *fake_frame_end; bool is_fake_frame = asan_get_fake_stack_extents( @@ -6495,13 +6495,25 @@ mark_current_machine_context(rb_objspace_t *objspace, rb_execution_context_t *ec #endif void -rb_gc_mark_machine_stack(const rb_execution_context_t *ec) +rb_gc_mark_machine_context(const rb_execution_context_t *ec) { + rb_objspace_t *objspace = &rb_objspace; +#ifdef RUBY_ASAN_ENABLED + objspace->marking_machine_context_ec = ec; +#endif + VALUE *stack_start, *stack_end; + GET_STACK_BOUNDS(stack_start, stack_end, 0); RUBY_DEBUG_LOG("ec->th:%u stack_start:%p stack_end:%p", rb_ec_thread_ptr(ec)->serial, stack_start, stack_end); - rb_gc_mark_locations(stack_start, stack_end); + each_stack_location(objspace, ec, stack_start, stack_end, gc_mark_machine_stack_location_maybe); + int num_regs = sizeof(ec->machine.regs)/(sizeof(VALUE)); + each_location(objspace, (VALUE*)&ec->machine.regs, num_regs, gc_mark_machine_stack_location_maybe); + +#ifdef RUBY_ASAN_ENABLED + objspace->marking_machine_context_ec = NULL; +#endif } static void |