summaryrefslogtreecommitdiffstats
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
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.
-rwxr-xr-xconfigure5
-rw-r--r--gc.c17
2 files changed, 22 insertions, 0 deletions
diff --git a/configure b/configure
index d388f1e8..edf82828 100755
--- a/configure
+++ b/configure
@@ -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
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;