From c37bdfa5311be0aa8503b995299fb9547cede0a6 Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Wed, 11 Dec 2024 12:18:00 -0500 Subject: [PATCH] Make asan_poison_object poison the whole slot This change poisons the whole slot of the object rather than just the flags. This allows ASAN to find any reads/writes into the slot after it has been freed. --- gc.c | 21 +++++++++++++++++++++ internal/sanitizers.h | 21 +++------------------ 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/gc.c b/gc.c index 4c32c5a1ed..82bef38bf9 100644 --- a/gc.c +++ b/gc.c @@ -4309,6 +4309,27 @@ rb_raw_obj_info_buitin_type(char *const buff, const size_t buff_size, const VALU #undef C +void +asan_poison_object(VALUE obj) +{ + MAYBE_UNUSED(struct RVALUE *) ptr = (void *)obj; + asan_poison_memory_region(ptr, rb_gc_obj_slot_size(obj)); +} + +void +asan_unpoison_object(VALUE obj, bool newobj_p) +{ + MAYBE_UNUSED(struct RVALUE *) ptr = (void *)obj; + asan_unpoison_memory_region(ptr, rb_gc_obj_slot_size(obj), newobj_p); +} + +void * +asan_poisoned_object_p(VALUE obj) +{ + MAYBE_UNUSED(struct RVALUE *) ptr = (void *)obj; + return __asan_region_is_poisoned(ptr, rb_gc_obj_slot_size(obj)); +} + #define asan_unpoisoning_object(obj) \ for (void *poisoned = asan_unpoison_object_temporary(obj), \ *unpoisoning = &poisoned; /* flag to loop just once */ \ diff --git a/internal/sanitizers.h b/internal/sanitizers.h index becf60bac2..3dc4019aca 100644 --- a/internal/sanitizers.h +++ b/internal/sanitizers.h @@ -124,12 +124,7 @@ asan_poison_memory_region(const volatile void *ptr, size_t size) * * @param[in] obj target object. */ -static inline void -asan_poison_object(VALUE obj) -{ - MAYBE_UNUSED(struct RVALUE *) ptr = (void *)obj; - asan_poison_memory_region(ptr, SIZEOF_VALUE); -} +void asan_poison_object(VALUE obj); #ifdef RUBY_ASAN_ENABLED #define asan_poison_object_if(ptr, obj) do { \ @@ -146,12 +141,7 @@ asan_poison_object(VALUE obj) * @retval 0 the given object is fully addressable. * @retval otherwise pointer to first such byte who is poisoned. */ -static inline void * -asan_poisoned_object_p(VALUE obj) -{ - MAYBE_UNUSED(struct RVALUE *) ptr = (void *)obj; - return __asan_region_is_poisoned(ptr, SIZEOF_VALUE); -} +void *asan_poisoned_object_p(VALUE obj); /** * This function asserts that a (formally poisoned) memory region from ptr to @@ -186,12 +176,7 @@ asan_unpoison_memory_region(const volatile void *ptr, size_t size, bool malloc_p * @param[in] obj target object. * @param[in] malloc_p if the memory region is like a malloc's return value or not. */ -static inline void -asan_unpoison_object(VALUE obj, bool newobj_p) -{ - MAYBE_UNUSED(struct RVALUE *) ptr = (void *)obj; - asan_unpoison_memory_region(ptr, SIZEOF_VALUE, newobj_p); -} +void asan_unpoison_object(VALUE obj, bool newobj_p); static inline void * asan_unpoison_object_temporary(VALUE obj)