Unpoison page->freelist before trying to assert on it
Otherwise trying to deref the pointer can cause an ASAN crash, even though the only reason we're dereferencing it is so that we can assert on it.
This commit is contained in:
parent
95d26ee41e
commit
02b36f7572
Notes:
git
2024-09-23 00:12:11 +00:00
10
gc/default.c
10
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))
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user