diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2022-09-17 15:58:17 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2022-09-17 15:58:17 -0700 |
commit | a6b80a09c364c59340d5a6b08d02ab33f085498b (patch) | |
tree | efc2d06a062d9541d70e27ee08680a657b05caf7 /gc.c | |
parent | e0e1f72e64812cc8df910ec5de92f319b4578c8b (diff) | |
download | txr-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.c | 17 |
1 files changed, 17 insertions, 0 deletions
@@ -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; |