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 | |
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.
-rwxr-xr-x | configure | 5 | ||||
-rw-r--r-- | gc.c | 17 |
2 files changed, 22 insertions, 0 deletions
@@ -218,6 +218,7 @@ libffi_cflags= darwin_target= solaris_target= build_id= +android_target= nan_boxing= nan_boxing_given= @@ -1269,6 +1270,7 @@ if ! [ $darwin_target ] ; then if [ "$($make conftest.android)" = "yes" ] ; then printf "yes\n" + android_target=y lang_flags="$lang_flags -U__ANDROID_API__ -D__ANDROID_API__=65535 -D_BSD_SOURCE" printf "Regenerating config.make ..." gen_config_make @@ -1599,6 +1601,9 @@ if [ -n "$nan_boxing" ] ; then printf "Warning: NaN boxing disabled: it requires 64 bit pointers\n" else printf "#define CONFIG_NAN_BOXING 1\n" >> config.h + if [ -n "$android_target" ] ; then + printf "#define CONFIG_NAN_BOXING_STRIP_TAG 1\n" >> config.h + fi fi fi @@ -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; |