summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorAaron Patterson <tenderlove@ruby-lang.org>2020-09-25 14:50:54 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2020-09-28 08:20:23 -0700
commit18b3f0f54c66632b1039a27634a8a449a7812e34 (patch)
tree3e5cb32306bb810c0e89221c2ff4f1fe62826b18 /ext
parentac414139ec0fc5626902231c4d45fffeb347263e (diff)
Make ext/objspace ASAN friendly
ext/objspace iterates over the heap, but some slots in the heap are poisoned, so we need to take care of that when running with ASAN
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/3592
Diffstat (limited to 'ext')
-rw-r--r--ext/objspace/objspace.c36
-rw-r--r--ext/objspace/objspace_dump.c8
2 files changed, 44 insertions, 0 deletions
diff --git a/ext/objspace/objspace.c b/ext/objspace/objspace.c
index 3bfb79dc1f..074dfbdc95 100644
--- a/ext/objspace/objspace.c
+++ b/ext/objspace/objspace.c
@@ -18,6 +18,7 @@
#include "internal/compilers.h"
#include "internal/hash.h"
#include "internal/imemo.h"
+#include "internal/sanitizers.h"
#include "node.h"
#include "ruby/io.h"
#include "ruby/re.h"
@@ -58,6 +59,9 @@ total_i(void *vstart, void *vend, size_t stride, void *ptr)
struct total_data *data = (struct total_data *)ptr;
for (v = (VALUE)vstart; v != (VALUE)vend; v += stride) {
+ void *ptr = asan_poisoned_object_p(v);
+ asan_unpoison_object(v, false);
+
if (RBASIC(v)->flags) {
switch (BUILTIN_TYPE(v)) {
case T_NONE:
@@ -72,6 +76,10 @@ total_i(void *vstart, void *vend, size_t stride, void *ptr)
}
}
}
+
+ if (ptr) {
+ asan_poison_object(v);
+ }
}
return 0;
@@ -155,9 +163,16 @@ cos_i(void *vstart, void *vend, size_t stride, void *data)
VALUE v = (VALUE)vstart;
for (;v != (VALUE)vend; v += stride) {
+ void *ptr = asan_poisoned_object_p(v);
+ asan_unpoison_object(v, false);
+
if (RBASIC(v)->flags) {
counts[BUILTIN_TYPE(v)] += rb_obj_memsize_of(v);
}
+
+ if (ptr) {
+ asan_poison_object(v);
+ }
}
return 0;
}
@@ -261,6 +276,9 @@ cs_i(void *vstart, void *vend, size_t stride, void *n)
VALUE v = (VALUE)vstart;
for (; v != (VALUE)vend; v += stride) {
+ void *ptr = asan_poisoned_object_p(v);
+ asan_unpoison_object(v, false);
+
if (RBASIC(v)->flags && BUILTIN_TYPE(v) == T_SYMBOL) {
ID id = RSYMBOL(v)->id;
if ((id & ~ID_SCOPE_MASK) == 0) {
@@ -270,6 +288,10 @@ cs_i(void *vstart, void *vend, size_t stride, void *n)
counts->immortal++;
}
}
+
+ if (ptr) {
+ asan_poison_object(v);
+ }
}
return 0;
@@ -500,6 +522,9 @@ cto_i(void *vstart, void *vend, size_t stride, void *data)
VALUE v = (VALUE)vstart;
for (; v != (VALUE)vend; v += stride) {
+ void *ptr = asan_poisoned_object_p(v);
+ asan_unpoison_object(v, false);
+
if (RBASIC(v)->flags && BUILTIN_TYPE(v) == T_DATA) {
VALUE counter;
VALUE key = RBASIC(v)->klass;
@@ -520,6 +545,10 @@ cto_i(void *vstart, void *vend, size_t stride, void *data)
rb_hash_aset(hash, key, counter);
}
+
+ if (ptr) {
+ asan_poison_object(v);
+ }
}
return 0;
@@ -574,6 +603,9 @@ count_imemo_objects_i(void *vstart, void *vend, size_t stride, void *data)
VALUE v = (VALUE)vstart;
for (; v != (VALUE)vend; v += stride) {
+ void *ptr = asan_poisoned_object_p(v);
+ asan_unpoison_object(v, false);
+
if (RBASIC(v)->flags && BUILTIN_TYPE(v) == T_IMEMO) {
VALUE counter;
VALUE key = ID2SYM(imemo_type_ids[imemo_type(v)]);
@@ -589,6 +621,10 @@ count_imemo_objects_i(void *vstart, void *vend, size_t stride, void *data)
rb_hash_aset(hash, key, counter);
}
+
+ if (ptr) {
+ asan_poison_object(v);
+ }
}
return 0;
diff --git a/ext/objspace/objspace_dump.c b/ext/objspace/objspace_dump.c
index e12b553794..7a5f44aaad 100644
--- a/ext/objspace/objspace_dump.c
+++ b/ext/objspace/objspace_dump.c
@@ -16,6 +16,7 @@
#include "internal.h"
#include "internal/hash.h"
#include "internal/string.h"
+#include "internal/sanitizers.h"
#include "node.h"
#include "objspace.h"
#include "ruby/debug.h"
@@ -508,8 +509,15 @@ heap_i(void *vstart, void *vend, size_t stride, void *data)
struct dump_config *dc = (struct dump_config *)data;
VALUE v = (VALUE)vstart;
for (; v != (VALUE)vend; v += stride) {
+ void *ptr = asan_poisoned_object_p(v);
+ asan_unpoison_object(v, false);
+
if (dc->full_heap || RBASIC(v)->flags)
dump_object(v, dc);
+
+ if (ptr) {
+ asan_poison_object(v);
+ }
}
return 0;
}