summaryrefslogtreecommitdiff
path: root/gc.c
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2021-12-07 19:44:02 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2021-12-07 21:55:41 +0900
commita2d4e1cda68a49980a4f9f353f400efbde7e7884 (patch)
treea04bedbfabd58408be79effe3719ec608e6f85c9 /gc.c
parentd6c5a30cfdf658280338dbb8c8b17fab3190b928 (diff)
Fixed the check order in wmap_live_p [Bug #18392]
Check if the object is a pointer to heap before check the flag in that object.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/5224
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c35
1 files changed, 22 insertions, 13 deletions
diff --git a/gc.c b/gc.c
index 2687dbb5a6..c3ecb385dd 100644
--- a/gc.c
+++ b/gc.c
@@ -1320,6 +1320,14 @@ tick(void)
#define MEASURE_LINE(expr) expr
#endif /* USE_TICK_T */
+static inline void *
+asan_unpoison_object_temporary(VALUE obj)
+{
+ void *ptr = asan_poisoned_object_p(obj);
+ asan_unpoison_object(obj, false);
+ return ptr;
+}
+
#define FL_CHECK2(name, x, pred) \
((RGENGC_CHECK_MODE && SPECIAL_CONST_P(x)) ? \
(rb_bug(name": SPECIAL_CONST (%p)", (void *)(x)), 0) : (pred))
@@ -4206,16 +4214,6 @@ rb_objspace_call_finalizer(rb_objspace_t *objspace)
ATOMIC_SET(finalizing, 0);
}
-PUREFUNC(static inline int is_id_value(rb_objspace_t *objspace, VALUE ptr));
-static inline int
-is_id_value(rb_objspace_t *objspace, VALUE ptr)
-{
- if (!is_pointer_to_heap(objspace, (void *)ptr)) return FALSE;
- if (BUILTIN_TYPE(ptr) > T_FIXNUM) return FALSE;
- if (BUILTIN_TYPE(ptr) == T_ICLASS) return FALSE;
- return TRUE;
-}
-
static inline int
is_swept_object(rb_objspace_t *objspace, VALUE ptr)
{
@@ -12049,9 +12047,20 @@ wmap_allocate(VALUE klass)
static int
wmap_live_p(rb_objspace_t *objspace, VALUE obj)
{
- if (!FL_ABLE(obj)) return TRUE;
- if (!is_id_value(objspace, obj)) return FALSE;
- if (!is_live_object(objspace, obj)) return FALSE;
+ if (SPECIAL_CONST_P(obj)) return TRUE;
+ if (is_pointer_to_heap(objspace, (void *)obj)) {
+ void *poisoned = asan_unpoison_object_temporary(obj);
+
+ enum ruby_value_type t = BUILTIN_TYPE(obj);
+ int ret = (!(t == T_NONE || t >= T_FIXNUM || t == T_ICLASS) &&
+ is_live_object(objspace, obj));
+
+ if (poisoned) {
+ asan_poison_object(obj);
+ }
+
+ return ret;
+ }
return TRUE;
}