diff options
author | KJ Tsanaktsidis <ktsanaktsidis@zendesk.com> | 2024-01-17 11:45:33 +1100 |
---|---|---|
committer | KJ Tsanaktsidis <kj@kjtsanaktsidis.id.au> | 2024-01-19 09:55:12 +1100 |
commit | 61da90c1b8d5c9a62d429ef66f000117eca675b3 (patch) | |
tree | e93ec1511a30b1c5ce2d4569e8f293ee67678b48 /gc.c | |
parent | 3cfcb45ecfb8dde9920220ae65ea6040e456bbd1 (diff) |
Mark asan fake stacks during machine stack marking
ASAN leaves a pointer to the fake frame on the stack; we can use the
__asan_addr_is_in_fake_stack API to work out the extent of the fake
stack and thus mark any VALUEs contained therein.
[Bug #20001]
Diffstat (limited to 'gc.c')
-rw-r--r-- | gc.c | 36 |
1 files changed, 34 insertions, 2 deletions
@@ -953,6 +953,11 @@ typedef struct rb_objspace { rb_darray(VALUE *) weak_references; rb_postponed_job_handle_t finalize_deferred_pjob; + +#ifdef RUBY_ASAN_ENABLED + rb_execution_context_t *marking_machine_context_ec; +#endif + } rb_objspace_t; @@ -6821,6 +6826,26 @@ mark_const_tbl(rb_objspace_t *objspace, struct rb_id_table *tbl) static void each_stack_location(rb_objspace_t *objspace, const rb_execution_context_t *ec, const VALUE *stack_start, const VALUE *stack_end, void (*cb)(rb_objspace_t *, VALUE)); +static void +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; + void *fake_frame_start; + void *fake_frame_end; + bool is_fake_frame = asan_get_fake_stack_extents( + ec->thread_ptr->asan_fake_stack_handle, obj, + ec->machine.stack_start, ec->machine.stack_end, + &fake_frame_start, &fake_frame_end + ); + if (is_fake_frame) { + each_stack_location(objspace, ec, fake_frame_start, fake_frame_end, gc_mark_maybe); + } +#endif +} + #if defined(__wasm__) @@ -6882,9 +6907,16 @@ mark_current_machine_context(rb_objspace_t *objspace, rb_execution_context_t *ec SET_STACK_END; GET_STACK_BOUNDS(stack_start, stack_end, 1); - each_location(objspace, save_regs_gc_mark.v, numberof(save_regs_gc_mark.v), gc_mark_maybe); +#ifdef RUBY_ASAN_ENABLED + objspace->marking_machine_context_ec = ec; +#endif - each_stack_location(objspace, ec, stack_start, stack_end, gc_mark_maybe); + each_location(objspace, save_regs_gc_mark.v, numberof(save_regs_gc_mark.v), gc_mark_machine_stack_location_maybe); + each_stack_location(objspace, ec, stack_start, stack_end, gc_mark_machine_stack_location_maybe); + +#ifdef RUBY_ASAN_ENABLED + objspace->marking_machine_context_ec = NULL; +#endif } #endif |