diff --git a/gc/default.c b/gc/default.c index d60fba3ff0..addaf01fc2 100644 --- a/gc/default.c +++ b/gc/default.c @@ -788,7 +788,9 @@ heap_page_in_global_empty_pages_pool(rb_objspace_t *objspace, struct heap_page * GC_ASSERT(page->slot_size == 0); GC_ASSERT(page->size_pool == NULL); GC_ASSERT(page->free_slots == 0); - GC_ASSERT(page->freelist == NULL); + asan_unpoisoning_memory_region(&page->freelist, sizeof(&page->freelist)) { + GC_ASSERT(page->freelist == NULL); + } return true; } @@ -1177,12 +1179,6 @@ tick(void) #define MEASURE_LINE(expr) expr #endif /* USE_TICK_T */ -#define asan_unpoisoning_object(obj) \ - for (void *poisoned = asan_unpoison_object_temporary(obj), \ - *unpoisoning = &poisoned; /* flag to loop just once */ \ - unpoisoning; \ - unpoisoning = asan_poison_object_restore(obj, poisoned)) - #define FL_CHECK2(name, x, pred) \ ((RGENGC_CHECK_MODE && SPECIAL_CONST_P(x)) ? \ (rb_bug(name": SPECIAL_CONST (%p)", (void *)(x)), 0) : (pred)) diff --git a/internal/sanitizers.h b/internal/sanitizers.h index b0eb1fc851..94f4e4165a 100644 --- a/internal/sanitizers.h +++ b/internal/sanitizers.h @@ -206,6 +206,35 @@ asan_poison_object_restore(VALUE obj, void *ptr) return NULL; } +#define asan_unpoisoning_object(obj) \ + for (void *poisoned = asan_unpoison_object_temporary(obj), \ + *unpoisoning = &poisoned; /* flag to loop just once */ \ + unpoisoning; \ + unpoisoning = asan_poison_object_restore(obj, poisoned)) + + +static inline void * +asan_unpoison_memory_region_temporary(void *ptr, size_t len) +{ + void *poisoned_ptr = __asan_region_is_poisoned(ptr, len); + asan_unpoison_memory_region(ptr, len, false); + return poisoned_ptr; +} + +static inline void * +asan_poison_memory_region_restore(void *ptr, size_t len, void *poisoned_ptr) +{ + if (poisoned_ptr) { + asan_poison_memory_region(ptr, len); + } + return NULL; +} + +#define asan_unpoisoning_memory_region(ptr, len) \ + for (void *poisoned = asan_unpoison_memory_region_temporary(ptr, len), \ + *unpoisoning = &poisoned; /* flag to loop just once */ \ + unpoisoning; \ + unpoisoning = asan_poison_memory_region_restore(ptr, len, poisoned)) /** * Checks if the given pointer is on an ASAN fake stack. If so, it returns the