summaryrefslogtreecommitdiffstats
path: root/gc.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-09-17 15:58:17 -0700
committerKaz Kylheku <kaz@kylheku.com>2022-09-17 15:58:17 -0700
commita6b80a09c364c59340d5a6b08d02ab33f085498b (patch)
treeefc2d06a062d9541d70e27ee08680a657b05caf7 /gc.c
parente0e1f72e64812cc8df910ec5de92f319b4578c8b (diff)
downloadtxr-a6b80a09c364c59340d5a6b08d02ab33f085498b.tar.gz
txr-a6b80a09c364c59340d5a6b08d02ab33f085498b.tar.bz2
txr-a6b80a09c364c59340d5a6b08d02ab33f085498b.zip
android: pointer tagging countermeasure.
We strip Android's pointer tag from our heap pointer while we own it, then put it back at free time. * configure (android_target): New variable. Set this to y in the test where we detect Android. When setting CONFIG_NAN_BOXING, also set CONFIG_NAN_BOXING_STRIP_TAG if on Android. * gc.c (struct heap): New member, tag. (more): When tag stripping is enabled, clear the top 16 bits of the pointer coming from malloc, and keep those bits in heap->tag. This gets rid of Android's tag. (sweep): When releasing a heap block with free, we must put the tag back into the pointer, from heap->tag.
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/gc.c b/gc.c
index 1f0d0e9f..0c518658 100644
--- a/gc.c
+++ b/gc.c
@@ -81,6 +81,9 @@
typedef struct heap {
obj_t block[HEAP_SIZE];
struct heap *next;
+#if CONFIG_NAN_BOXING_STRIP_TAG
+ ucnum tag;
+#endif
} heap_t;
typedef struct mach_context {
@@ -157,9 +160,18 @@ void protect(val *first, ...)
static void more(void)
{
+#if CONFIG_NAN_BOXING_STRIP_TAG
+ ucnum tagged_ptr = coerce(cnum, chk_malloc_gc_more(sizeof (heap_t)));
+ heap_t *heap = coerce(heap_t *, tagged_ptr & ~TAG_BIGMASK);
+#else
heap_t *heap = coerce(heap_t *, chk_malloc_gc_more(sizeof *heap));
+#endif
obj_t *block = heap->block, *end = heap->block + HEAP_SIZE;
+#if CONFIG_NAN_BOXING_STRIP_TAG
+ heap->tag = tagged_ptr >> TAG_BIGSHIFT;
+#endif
+
if (free_list == 0)
free_tail = &heap->block[0].t.next;
@@ -720,7 +732,12 @@ NOINLINE static int_ptr_t sweep(void)
}
}
*pph = heap->next;
+#if CONFIG_NAN_BOXING_STRIP_TAG
+ free(coerce(heap_t *, coerce(ucnum, heap) | (heap->tag << TAG_BIGSHIFT)));
+#else
free(heap);
+#endif
+
#if HAVE_VALGRIND
if (vg_dbg) {
val iter, next;