Loading...
src/sanitizer_malloc.c libmalloc-792.80.2 libmalloc-474.0.13
--- libmalloc/libmalloc-792.80.2/src/sanitizer_malloc.c
+++ libmalloc/libmalloc-474.0.13/src/sanitizer_malloc.c
@@ -40,13 +40,11 @@
 	size_t max_items_in_quarantine; // 0 means unlimited
 	size_t max_bytes_in_quarantine; // 0 means unlimited
 
-#if !MALLOC_TARGET_EXCLAVES
 	// Stacktrace tracking data structures
 	struct stacktrace_depo_t *depo;
 	struct pointer_map_t *map;
 
 	uint8_t padding[PAGE_MAX_SIZE];
-#endif /* !MALLOC_TARGET_EXCLAVES */
 
 	// Mutable state
 	_malloc_lock_s lock;
@@ -56,28 +54,20 @@
 	size_t bytes_in_quarantine;
 } sanitizer_zone_t;
 
-ASSERT_WRAPPER_ZONE(sanitizer_zone_t);
-
-#if !MALLOC_TARGET_EXCLAVES
-MALLOC_STATIC_ASSERT(offsetof(sanitizer_zone_t, padding) < PAGE_MAX_SIZE,
+MALLOC_STATIC_ASSERT(__offsetof(sanitizer_zone_t, malloc_zone) == 0,
+		"sanitizer_zone_t instances must be usable as regular zones");
+MALLOC_STATIC_ASSERT(__offsetof(sanitizer_zone_t, padding) < PAGE_MAX_SIZE,
 		"First page is mapped read-only");
-MALLOC_STATIC_ASSERT(offsetof(sanitizer_zone_t, lock) >= PAGE_MAX_SIZE,
+MALLOC_STATIC_ASSERT(__offsetof(sanitizer_zone_t, lock) >= PAGE_MAX_SIZE,
 		"Mutable state is on separate page");
 MALLOC_STATIC_ASSERT(sizeof(sanitizer_zone_t) < (2 * PAGE_MAX_SIZE),
 		"Zone fits on 2 pages");
-#endif /* !MALLOC_TARGET_EXCLAVES */
-
-#ifndef ASAN_SHADOW_ALIGNMENT
+
 #define ASAN_SHADOW_ALIGNMENT 8
-#endif /* ASAN_SHADOW_ALIGNMENT */
 
 #define DELEGATE(function, args...) \
 	zone->wrapped_zone->function(zone->wrapped_zone, args)
 
-#if MALLOC_TARGET_EXCLAVES
-static sanitizer_zone_t sanitizer_zone;
-#endif /* MALLOC_TARGET_EXCLAVES */
-
 // Lock helpers
 static void
 init_lock(sanitizer_zone_t *zone)
@@ -104,7 +94,6 @@
 }
 
 // VM allocation/deallocate helpers
-#if !MALLOC_TARGET_EXCLAVES
 static vm_address_t
 sanitizer_vm_map(size_t size, vm_prot_t protection, int tag)
 {
@@ -123,7 +112,7 @@
 	kern_return_t kr = mach_vm_map(target, &address, size_rounded, mask, flags,
 		object, offset, copy, cur_protection, max_protection, inheritance);
 	MALLOC_ASSERT(kr == KERN_SUCCESS);
-	return (vm_address_t)address;
+	return address;
 }
 
 static void
@@ -172,7 +161,7 @@
 }
 
 static uint32_t
-stacktrace_depo_insert(struct stacktrace_depo_t *depo, uintptr_t * __counted_by(count) pcs, size_t count);
+stacktrace_depo_insert(struct stacktrace_depo_t *depo, vm_address_t *pcs, size_t count);
 
 static bool
 pointer_map_find(struct pointer_map_t *map, uintptr_t ptr, uint64_t *word_out);
@@ -180,23 +169,21 @@
 static void
 pointer_map_insert(struct pointer_map_t *map, uintptr_t ptr, uint64_t word);
 
+static void
+unpoison(sanitizer_zone_t *zone, void *ptr, size_t size);
+
 #define wrap(index, container) ((index) & (countof(container) - 1))
 
 static uint32_t OS_ALWAYS_INLINE
 insert_current_stacktrace_into_depo(struct stacktrace_depo_t *depo, uint32_t top_frames_to_ignore)
 {
-	void * __unsafe_indexable pcs[16 + top_frames_to_ignore];
-#if MALLOC_TARGET_EXCLAVES
-	ssize_t num_pcs = backtrace(pcs, countof(pcs));
-#else
+	vm_address_t pcs[16 + top_frames_to_ignore];
 	uint32_t num_pcs;
-	thread_stack_pcs((vm_address_t *)pcs, (unsigned)countof(pcs), &num_pcs);
-#endif // MALLOC_TARGET_EXCLAVES
+	thread_stack_pcs(pcs, (unsigned)countof(pcs), &num_pcs);
 	if (num_pcs <= top_frames_to_ignore) {
 		return 0;
 	}
-	const size_t num_frames = (size_t)num_pcs - top_frames_to_ignore;
-	return stacktrace_depo_insert(depo, (uintptr_t * __counted_by(num_frames))&pcs[top_frames_to_ignore], num_frames);
+	return stacktrace_depo_insert(depo, &pcs[top_frames_to_ignore], num_pcs - top_frames_to_ignore);
 }
 
 static void OS_ALWAYS_INLINE
@@ -208,22 +195,17 @@
 	uint32_t alloc_hash = insert_current_stacktrace_into_depo(depo, 1);
 	pointer_map_insert(map, (uintptr_t)ptr, alloc_hash);
 }
-#endif /* !MALLOC_TARGET_EXCLAVES */
-
-static void
-unpoison(sanitizer_zone_t *zone, void * __sized_by(size) ptr, size_t size);
+
 
 #pragma mark -
 #pragma mark Quarantine Logic
 
 typedef struct quarantined_chunk {
 	uint64_t next_and_size;
-#if !MALLOC_TARGET_EXCLAVES
 	uint64_t stacktrace_hashes;
-#endif /* !MALLOC_TARGET_EXCLAVES */
 } quarantined_chunk_t;
 
-MALLOC_STATIC_ASSERT(sizeof(quarantined_chunk_t) <= 16,
+MALLOC_STATIC_ASSERT(sizeof(quarantined_chunk_t) == 16,
 		"quarantined_chunk_t must be 16 bytes to fit in all allocations");
 
 typedef union {
@@ -238,18 +220,17 @@
 		"next_and_size must be 8 bytes");
 
 static void OS_NOINLINE
-place_into_quarantine(sanitizer_zone_t *zone, void * __unsafe_indexable _ptr, size_t size)
-{
-	if (_ptr == NULL) {
+place_into_quarantine(sanitizer_zone_t *zone, void *ptr, size_t size)
+{
+	if (ptr == NULL) {
 		return;
 	}
 
 	// We need to know the size of the chunk, for quarantine bookkeeping
 	if (size == 0) {
-		size = DELEGATE(size, _ptr);
-	}
-
-	void *ptr = __unsafe_forge_bidi_indexable(void *, _ptr, size);
+		size = DELEGATE(size, ptr);
+	}
+
 	// Don't quarantine large allocations to avoid one single huge allocation
 	// evicting the whole quarantine.
 	if (size > PAGE_SIZE) {
@@ -263,13 +244,11 @@
 		return DELEGATE(free, ptr);
 	}
 
-#if !MALLOC_TARGET_EXCLAVES
 	uint32_t dealloc_stack_hash = insert_current_stacktrace_into_depo(zone->depo, 2);
 	uint64_t stored_word = 0;
 	pointer_map_find(zone->map, (uintptr_t)ptr, &stored_word);
 	uint32_t alloc_stack_hash = (uint32_t)stored_word;
 	uint64_t hashes = alloc_stack_hash | (((uint64_t)dealloc_stack_hash) << 32);
-#endif
 
 	lock(zone);
 
@@ -285,9 +264,7 @@
 	}
 	next_and_size n = { .parts = { .next_ptr = 0, .size = size } };
 	_malloc_write_uint64_via_rsp(&zone->quarantine_tail->next_and_size, n.i);
-#if !MALLOC_TARGET_EXCLAVES
 	_malloc_write_uint64_via_rsp(&zone->quarantine_tail->stacktrace_hashes, hashes);
-#endif
 
 	zone->items_in_quarantine += 1;
 	zone->bytes_in_quarantine += size;
@@ -312,7 +289,7 @@
 	while (items_over_limit > 0 || bytes_over_limit > 0) {
 		next_and_size n;
 		n.i = _malloc_read_uint64_via_rsp(&iterator->next_and_size);
-		quarantined_chunk_t *next = __unsafe_forge_single(quarantined_chunk_t *, n.parts.next_ptr);
+		quarantined_chunk_t *next = (void *)n.parts.next_ptr;
 		size_t iterator_size = n.parts.size;
 
 		items_to_free_count += 1;
@@ -335,27 +312,22 @@
 	for (size_t i = 0; i < items_to_free_count; i++) {
 		next_and_size n;
 		n.i = _malloc_read_uint64_via_rsp(&iterator->next_and_size);
-		quarantined_chunk_t *next = __unsafe_forge_single(quarantined_chunk_t *, n.parts.next_ptr);
+		quarantined_chunk_t *next = (void *)n.parts.next_ptr;
 		size_t iterator_size = n.parts.size;
 
 		if (zone->debug) malloc_report(ASL_LEVEL_INFO, "evicting %p from quarantine, size = 0x%lx\n", iterator, iterator_size);
-
-		// Forge the pointer because it is only sized for quarantined_chunk_t
-		void *iterator_ptr = __unsafe_forge_bidi_indexable(void *, iterator,
-				iterator_size);
 
 		// Same as above, perform actual unpoisoning
 		if (zone->do_poisoning) {
-			unpoison(zone, iterator_ptr, iterator_size);
+			unpoison(zone, iterator, iterator_size);
 		}
 
-		DELEGATE(free_definite_size, iterator_ptr, iterator_size);
+		DELEGATE(free_definite_size, iterator, iterator_size);
 
 		iterator = next;
 	}
 }
 
-#if !MALLOC_TARGET_EXCLAVES
 #pragma mark -
 #pragma mark MurmurHash2
 
@@ -385,9 +357,7 @@
 murmur2_add_uintptr(uint32_t *hstate, uintptr_t ptr)
 {
 	murmur2_add_uint32(hstate, (uint32_t)ptr);
-#if MALLOC_TARGET_64BIT
 	murmur2_add_uint32(hstate, (uint32_t)(ptr >> 32));
-#endif
 }
 
 static uint32_t
@@ -409,7 +379,7 @@
 }
 
 static uint32_t
-murmur2_hash_backtrace(uintptr_t * __counted_by(count) pcs, size_t count)
+murmur2_hash_backtrace(uintptr_t *pcs, size_t count)
 {
 	uint32_t hstate = murmur2_init();
 	for (int i = 0; i < count; i++) {
@@ -460,7 +430,7 @@
 static stacktrace_depo_t *
 stacktrace_depo_create()
 {
-	return mvm_allocate_pages(sizeof(stacktrace_depo_t), PAGE_SHIFT, 0, VM_MEMORY_ANALYSIS_TOOL);
+	return mvm_allocate_pages(sizeof(stacktrace_depo_t), PAGE_SIZE, 0, VM_MEMORY_ANALYSIS_TOOL);
 }
 
 static void
@@ -470,14 +440,14 @@
 }
 
 static uint32_t
-stacktrace_depo_insert(stacktrace_depo_t *depo, uintptr_t * __counted_by(count) pcs, size_t count)
+stacktrace_depo_insert(stacktrace_depo_t *depo, vm_address_t *pcs, size_t count)
 {
 	MALLOC_ASSERT(count < 256);
 	uint32_t hash = murmur2_hash_backtrace(pcs, count);
 	uint32_t index_pos = wrap(hash, depo->index);
 
 	index_entry entry;
-	entry.i = os_atomic_load_wide(&depo->index[index_pos], relaxed);
+	entry.i = os_atomic_load(&depo->index[index_pos], relaxed);
 	if (entry.parts.count == count && entry.parts.hash == hash) {
 		return hash;
 	}
@@ -487,10 +457,10 @@
 	entry.parts.hash = hash;
 	entry.parts.pos = (uint32_t)old_storage_pos;
 	entry.parts.count = (uint32_t)count;
-	os_atomic_store_wide(&depo->index[index_pos], entry.i, relaxed);
+	os_atomic_store(&depo->index[index_pos], entry.i, relaxed);
 	for (int i = 0; i < count; i++) {
 		uint32_t pos = wrap(old_storage_pos + i, depo->storage);
-		os_atomic_store_wide(&depo->storage[pos], pcs[i], relaxed);
+		os_atomic_store(&depo->storage[pos], pcs[i], relaxed);
 	}
 	return hash;
 }
@@ -498,7 +468,7 @@
 // Doesn't need to use atomics or be thread-safe against insertion because
 // look-up is only used from ReportCrash against a corpse.
 static size_t
-stacktrace_depo_find(stacktrace_depo_t *depo, uint32_t hash, uintptr_t * __counted_by(max_size) pcs, size_t max_size)
+stacktrace_depo_find(stacktrace_depo_t *depo, uint32_t hash, vm_address_t *pcs, size_t max_size)
 {
 	uint32_t index_pos = wrap(hash, depo->index);
 
@@ -512,8 +482,7 @@
 	for (int i = 0; i < entry.parts.count; i++) {
 		uint32_t pos = wrap(entry.parts.pos + i, depo->storage);
 		if (i < max_size) {
-		    // Explicit cast as it doesn't otherwise compile on watchOS (error: implicit conversion loses integer precision)
-			pcs[i] = (uintptr_t)depo->storage[pos];
+			pcs[i] = depo->storage[pos];
 		}
 		murmur2_add_uintptr(&hstate, pcs[i]);
 	}
@@ -558,7 +527,7 @@
 static pointer_map_t *
 pointer_map_create()
 {
-	return mvm_allocate_pages(sizeof(pointer_map_t), PAGE_SHIFT, 0, VM_MEMORY_ANALYSIS_TOOL);
+	return mvm_allocate_pages(sizeof(pointer_map_t), PAGE_SIZE, 0, VM_MEMORY_ANALYSIS_TOOL);
 }
 
 static void
@@ -591,65 +560,55 @@
 	*word_out = entry.parts.word;
 	return true;
 }
-#endif /* !MALLOC_TARGET_EXCLAVES */
 
 #pragma mark -
 #pragma mark Poisoning Functions
 
-// Size of redzone is stored in the last aligned size_t at the end of the allocation
-static size_t get_redzone_size(sanitizer_zone_t *zone, const void * __sized_by(size) ptr, size_t size)
+static size_t get_redzone_size(sanitizer_zone_t *zone, const void *ptr, size_t size)
 {
 	MALLOC_ASSERT(zone->do_poisoning);
 	// Size of redzone is stored in the last aligned size_t at the end of the allocation
 	const size_t offset = sizeof(size_t) + size % sizeof(size_t);
-	const size_t *redzone_size_ptr =
-			__unsafe_forge_single(size_t *, ((uintptr_t)ptr + size - offset));
+	const size_t *redzone_size_ptr = (size_t *)((uintptr_t)ptr + size - offset);
 	// When executing under instrumentation, the translation layer automatically
 	// checks against the shadow map, instead of letting the compiled program's
 	// instrumentation handle it. This means we need to bypass it since the size
 	// is stored within the allocation redzone
-    // Explicit cast as it doesn't otherwise compile on watchOS (error: implicit conversion loses integer precision)
-#if MALLOC_TARGET_64BIT
-	const size_t redzone_size = (size_t)_malloc_read_uint64_via_rsp(redzone_size_ptr);
-#else
-	const size_t redzone_size = (size_t)*(uint32_t *)redzone_size_ptr;
-#endif
+	const size_t redzone_size = _malloc_read_uint64_via_rsp(redzone_size_ptr);
 	MALLOC_ASSERT(redzone_size >= zone->redzone_size && redzone_size < size);
 	return redzone_size;
 }
 
-static void set_redzone_size(sanitizer_zone_t *zone, void * __sized_by(usr_size + redzone_size) ptr, size_t usr_size, size_t redzone_size)
+static void set_redzone_size(sanitizer_zone_t *zone, void *ptr, size_t size, size_t redzone_size)
 {
 	MALLOC_ASSERT(zone->do_poisoning);
-	const size_t offset =
-			sizeof(size_t) + (usr_size + redzone_size) % sizeof(size_t);
-	size_t *redzone_size_ptr = ptr + (usr_size + redzone_size - offset);
+	const size_t offset = sizeof(size_t) + size % sizeof(size_t);
+	MALLOC_ASSERT(redzone_size < size);
+	size_t *redzone_size_ptr = (size_t *)((uintptr_t)ptr + size - offset);
 	// Same as above, this may be a reallocation that has not yet been unpoisoned
-#if MALLOC_TARGET_64BIT
 	_malloc_write_uint64_via_rsp(redzone_size_ptr, redzone_size);
-#else
-	*(uint32_t *)redzone_size_ptr = redzone_size;
-#endif
-}
-
-static void poison_alloc(sanitizer_zone_t *zone, void * __sized_by(usr_size + redzone_size) ptr, size_t usr_size, size_t redzone_size)
-{
-	if (zone->debug) malloc_report(ASL_LEVEL_INFO, "poison_alloc(%p, 0x%lx, 0x%lx)\n", ptr, usr_size, redzone_size);
-
-	MALLOC_ASSERT(ptr);
+}
+
+static void poison_alloc(sanitizer_zone_t *zone, void *ptr, size_t size, size_t redzone_size)
+{
+	if (zone->debug) malloc_report(ASL_LEVEL_INFO, "poison_alloc(%p, 0x%lx, 0x%lx)\n", ptr, size, redzone_size);
+
+	if (!ptr) {
+		return;
+	}
 
 	// Always set the redzone size, even if we can't actually poison allocations
-	set_redzone_size(zone, ptr, usr_size, redzone_size);
+	set_redzone_size(zone, ptr, size + redzone_size, redzone_size);
 
 	const struct malloc_sanitizer_poison *sanitizer = malloc_sanitizer_get_functions();
 	if (sanitizer && sanitizer->heap_allocate_poison) {
-		(*sanitizer->heap_allocate_poison)((uintptr_t)ptr, 0, usr_size, redzone_size);
+		(*sanitizer->heap_allocate_poison)((uintptr_t)ptr, 0, size, redzone_size);
 	} else if (zone->debug) {
-		malloc_report(ASL_LEVEL_WARNING, "MallocSanitizerZone: Not poisoning allocation %p of size %lu with redzone size %lu due to missing pointers!\n", ptr, usr_size, redzone_size);
-	}
-}
-
-static void poison_free(sanitizer_zone_t *zone, void * __sized_by(size) ptr, size_t size)
+		malloc_report(ASL_LEVEL_WARNING, "MallocSanitizerZone: Not poisoning allocation %p of size %lu with redzone size %lu due to missing pointers!\n", ptr, size, redzone_size);
+	}
+}
+
+static void poison_free(sanitizer_zone_t *zone, void *ptr, size_t size)
 {
 	if (zone->debug) malloc_report(ASL_LEVEL_INFO, "poison_free(%p, 0x%lx)\n", ptr, size);
 
@@ -663,7 +622,7 @@
 	}
 }
 
-static void unpoison(sanitizer_zone_t *zone, void * __sized_by(size) ptr, size_t size)
+static void unpoison(sanitizer_zone_t *zone, void *ptr, size_t size)
 {
 	if (zone->debug) malloc_report(ASL_LEVEL_INFO, "unpoison(%p, 0x%lx)\n", ptr, size);
 
@@ -681,15 +640,11 @@
 #pragma mark Zone Functions
 
 static size_t
-sanitizer_size(sanitizer_zone_t *zone, const void * __unsafe_indexable ptr)
+sanitizer_size(sanitizer_zone_t *zone, const void *ptr)
 {
 	size_t size = DELEGATE(size, ptr);
-	if (!size) {
-		return 0;
-	}
-
-	if (zone->do_poisoning) {
-		const size_t redzone_size = get_redzone_size(zone, __unsafe_forge_bidi_indexable(void *, ptr, size), size);
+	if (zone->do_poisoning) {
+		const size_t redzone_size = get_redzone_size(zone, ptr, size);
 		if (zone->debug) malloc_report(ASL_LEVEL_INFO, "size(%p) = 0x%lx - redzone 0x%lx\n", ptr, size, redzone_size);
 
 		MALLOC_ASSERT(size > redzone_size);
@@ -700,122 +655,39 @@
 	return size;
 }
 
-static void * __alloc_size(2) __sized_by_or_null(size)
-sanitizer_malloc_type_malloc_noalign_with_options(sanitizer_zone_t *zone,
-		size_t size, malloc_zone_malloc_options_t options,
-		malloc_type_id_t type_id)
-{
-	if (!size) {
-		size = 1;
-	}
+static void *
+sanitizer_malloc(sanitizer_zone_t *zone, size_t size)
+{
 	size_t redzone_size = zone->redzone_size;
 	const size_t usr_size = size;
 	if (zone->do_poisoning) {
-		const size_t mask = ASAN_SHADOW_ALIGNMENT - 1;
 		// Round up redzone so that allocation is padded to shadow alignment
-		redzone_size += (ASAN_SHADOW_ALIGNMENT - (usr_size & mask)) & mask;
+		redzone_size += ASAN_SHADOW_ALIGNMENT - (usr_size & (ASAN_SHADOW_ALIGNMENT - 1));
+		// Round up redzone so that allocation includes allocator padding
+		const size_t padded_sz = DELEGATE(introspect->good_size, usr_size + redzone_size);
+		MALLOC_ASSERT(padded_sz >= usr_size + redzone_size);
+		redzone_size += padded_sz - (usr_size + redzone_size);
 		// Recalculate the total allocation size
 		size = usr_size + redzone_size;
 		// Check for overflow once at the end
 		if (size < usr_size) {
-			malloc_set_errno_fast(MZ_POSIX, ENOMEM);
 			return NULL;
 		}
 	}
-
-	void *ptr;
-#if MALLOC_TARGET_64BIT
-	malloc_type_descriptor_t type_desc = { .type_id = type_id };
-#endif // MALLOC_TARGET_64BIT
-	if (zone->wrapped_zone->version >= 16) {
-		if (zone->wrapped_zone->malloc_type_malloc_with_options) {
-			// Dispatch directly with pass-thru options
-			ptr = DELEGATE(malloc_type_malloc_with_options, 0, size, options,
-					type_id);
-		} else if (options & MALLOC_ZONE_MALLOC_OPTION_CLEAR) {
-			// Need fallback for this option
-			ptr = DELEGATE(malloc_type_calloc, 1, size, type_id);
-		} else {
-			// Remaining options already handled in parent, ignore them
-			ptr = DELEGATE(malloc_type_malloc, size, type_id);
-		}
-	} else if (zone->wrapped_zone->version >= 15 &&
-			zone->wrapped_zone->malloc_with_options) {
-		// Dispatch directly with type TSD and pass-thru options
-#if MALLOC_TARGET_64BIT
-		malloc_set_tsd_type_descriptor(type_desc);
-#endif // MALLOC_TARGET_64BIT
-		ptr = DELEGATE(malloc_with_options, 0, size, options);
-#if MALLOC_TARGET_64BIT
-		malloc_set_tsd_type_descriptor(MALLOC_TYPE_DESCRIPTOR_NONE);
-#endif // MALLOC_TARGET_64BIT
-	} else {
-		const malloc_zone_malloc_options_t known_options =
-				MALLOC_ZONE_MALLOC_OPTION_CLEAR
-				;
-		if (options & ~known_options) {
-			malloc_zone_error(MALLOC_ABORT_ON_ERROR, true,
-					"sanitizer_malloc_with_options: unsupported options 0x%llx\n",
-					options);
-			__builtin_trap();
-		}
-
-		// Set the type TSD and check the options
-#if MALLOC_TARGET_64BIT
-		malloc_set_tsd_type_descriptor(type_desc);
-#endif // MALLOC_TARGET_64BIT
-		if (options & MALLOC_ZONE_MALLOC_OPTION_CLEAR) {
-			// Need fallback for this option
-			ptr = DELEGATE(calloc, 1, size);
-		} else {
-			// Remaining options already handled in parent, ignore them
-			ptr = DELEGATE(malloc, size);
-		}
-#if MALLOC_TARGET_64BIT
-		malloc_set_tsd_type_descriptor(MALLOC_TYPE_DESCRIPTOR_NONE);
-#endif // MALLOC_TARGET_64BIT
-	}
-
-#if !MALLOC_TARGET_EXCLAVES
+	void *ptr = DELEGATE(malloc, size);
 	record_alloc_stacktrace(zone->depo, zone->map, ptr, usr_size);
-#endif /* !MALLOC_TARGET_EXCLAVES */
 	if (zone->debug) malloc_report(ASL_LEVEL_INFO, "malloc(0x%lx) = %p\n", size, ptr);
-	if (ptr && zone->do_poisoning) {
-		// Recalculate the redzone size to include allocator padding
-		size_t actual_size = DELEGATE(size, ptr);
-		MALLOC_ASSERT(actual_size >= size);
-		redzone_size += actual_size - size;
-		ptr = __unsafe_forge_bidi_indexable(void *, ptr,
-				usr_size + redzone_size);
+	if (zone->do_poisoning) {
 		poison_alloc(zone, ptr, usr_size, redzone_size);
 	}
 	return ptr;
 }
 
-static void * __alloc_size(2) __sized_by_or_null(size)
-sanitizer_malloc(sanitizer_zone_t *zone, size_t size)
-{
-	return sanitizer_malloc_type_malloc_noalign_with_options(zone, size, 0,
-			malloc_get_tsd_type_id());
-}
-
-static void * __alloc_size(2) __sized_by_or_null(size)
-sanitizer_malloc_type_malloc(sanitizer_zone_t *zone, size_t size,
-		malloc_type_id_t type_id)
-{
-	return sanitizer_malloc_type_malloc_noalign_with_options(zone, size, 0,
-			type_id);
-}
-
-static void * __alloc_size(2,3) __sized_by_or_null(num_items * size)
-sanitizer_malloc_type_calloc(sanitizer_zone_t *zone, size_t num_items,
-		size_t size, malloc_type_id_t type_id)
+static void *
+sanitizer_calloc(sanitizer_zone_t *zone, size_t num_items, size_t size)
 {
 	size_t usr_size;
-	if (!size || !num_items) {
-		usr_size = 1;
-	} else if (calloc_get_size(num_items, size, 0, &usr_size)) {
-		malloc_set_errno_fast(MZ_POSIX, ENOMEM);
+	if (calloc_get_size(num_items, size, 0, &usr_size)) {
 		return NULL;
 	}
 
@@ -823,62 +695,30 @@
 	if (zone->do_poisoning) {
 		// Round up redzone so that allocation is padded to shadow alignment
 		redzone_size += ASAN_SHADOW_ALIGNMENT - (usr_size & (ASAN_SHADOW_ALIGNMENT - 1));
+		// Round up redzone so that allocation includes allocator padding
+		const size_t padded_sz = DELEGATE(introspect->good_size, usr_size + redzone_size);
+		MALLOC_ASSERT(padded_sz >= usr_size + redzone_size);
+		redzone_size += padded_sz - (usr_size + redzone_size);
 		// Recalculate the total allocation size
 		num_items = 1;
 		size = usr_size + redzone_size;
 		// Check for overflow once at the end
 		if (size < usr_size) {
-			malloc_set_errno_fast(MZ_POSIX, ENOMEM);
 			return NULL;
 		}
 	}
-
-	void *ptr;
-	if (zone->wrapped_zone->version >= 16) {
-		ptr = __unsafe_forge_bidi_indexable(void *,
-				DELEGATE(malloc_type_calloc, num_items, size, type_id), usr_size);
-	} else {
-#if MALLOC_TARGET_64BIT
-		malloc_set_tsd_type_descriptor(
-				(malloc_type_descriptor_t){ .type_id = type_id });
-#endif // MALLOC_TARGET_64BIT
-		ptr = __unsafe_forge_bidi_indexable(void *,
-				DELEGATE(calloc, num_items, size), usr_size);
-#if MALLOC_TARGET_64BIT
-		malloc_set_tsd_type_descriptor(MALLOC_TYPE_DESCRIPTOR_NONE);
-#endif // MALLOC_TARGET_64BIT
-	}
-
+	void *ptr = DELEGATE(calloc, num_items, size);
 	if (zone->debug) malloc_report(ASL_LEVEL_INFO, "calloc(0x%lx, 0x%lx) = %p\n", num_items, size, ptr);
-#if !MALLOC_TARGET_EXCLAVES
 	record_alloc_stacktrace(zone->depo, zone->map, ptr, usr_size);
-#endif /* !MALLOC_TARGET_EXCLAVES */
-	if (ptr && zone->do_poisoning) {
-		// Recalculate the redzone size to include allocator padding
-		size_t actual_size = DELEGATE(size, ptr);
-		MALLOC_ASSERT(actual_size >= size);
-		redzone_size += actual_size - size;
-		ptr = __unsafe_forge_bidi_indexable(void *, ptr,
-				usr_size + redzone_size);
+	if (zone->do_poisoning) {
 		poison_alloc(zone, ptr, usr_size, redzone_size);
 	}
 	return ptr;
 }
 
-
-static void * __alloc_size(2,3) __sized_by_or_null(num_items * size)
-sanitizer_calloc(sanitizer_zone_t *zone, size_t num_items, size_t size)
-{
-	return sanitizer_malloc_type_calloc(zone, num_items, size,
-			malloc_get_tsd_type_id());
-}
-
-static void * __alloc_size(2) __sized_by_or_null(size)
+static void *
 sanitizer_valloc(sanitizer_zone_t *zone, size_t size)
 {
-	if (!size) {
-		size = 1;
-	}
 	size_t redzone_size = zone->redzone_size;
 	const size_t usr_size = size;
 	if (zone->do_poisoning) {
@@ -892,42 +732,32 @@
 		}
 	}
 	void *ptr = DELEGATE(valloc, size);
-#if !MALLOC_TARGET_EXCLAVES
 	record_alloc_stacktrace(zone->depo, zone->map, ptr, usr_size);
-#endif /* !MALLOC_TARGET_EXCLAVES */
 	if (zone->debug) malloc_report(ASL_LEVEL_INFO, "valloc(0x%lx) = %p\n", size, ptr);
-	if (ptr && zone->do_poisoning) {
-		// Recalculate the redzone size to include allocator padding
-		size_t actual_size = DELEGATE(size, ptr);
-		MALLOC_ASSERT(actual_size >= size);
-		redzone_size += actual_size - size;
-		ptr = __unsafe_forge_bidi_indexable(void *, ptr,
-				usr_size + redzone_size);
+	if (zone->do_poisoning) {
+		// Recalculate the redzone size due to allocator padding
+		size = DELEGATE(size, ptr);
+		MALLOC_ASSERT(size >= usr_size && size - usr_size >= redzone_size);
+		redzone_size = size - usr_size;
 		poison_alloc(zone, ptr, usr_size, redzone_size);
 	}
 	return ptr;
 }
 
 static void
-sanitizer_free(sanitizer_zone_t *zone, void * __unsafe_indexable ptr)
-{
-	if (os_unlikely(!ptr)) {
-		return;
-	}
-
+sanitizer_free(sanitizer_zone_t *zone, void *ptr)
+{
 	size_t size = 0;
 	if (zone->do_poisoning) {
 		size = DELEGATE(size, ptr);
-		poison_free(zone, __unsafe_forge_bidi_indexable(void *, ptr, size), size);
+		poison_free(zone, ptr, size);
 	}
 	if (zone->debug) malloc_report(ASL_LEVEL_INFO, "free(%p)\n", ptr);
 	place_into_quarantine(zone, ptr, size);
 }
 
-static void * __alloc_size(3) __sized_by_or_null(new_size)
-sanitizer_malloc_type_realloc(sanitizer_zone_t *zone,
-		void * __unsafe_indexable ptr, size_t new_size,
-		malloc_type_id_t type_id)
+static void *
+sanitizer_realloc(sanitizer_zone_t *zone, void *ptr, size_t new_size)
 {
 	if (new_size == 0) {
 		new_size = 1;
@@ -938,6 +768,10 @@
 	if (zone->do_poisoning) {
 		// Round up redzone so that allocation is padded to shadow alignment
 		redzone_size += ASAN_SHADOW_ALIGNMENT - (new_size & (ASAN_SHADOW_ALIGNMENT - 1));
+		// Round up redzone so that allocation includes allocator padding
+		const size_t padded_sz = DELEGATE(introspect->good_size, new_size + redzone_size);
+		MALLOC_ASSERT(padded_sz >= new_size + redzone_size);
+		redzone_size += padded_sz - (new_size + redzone_size);
 		// Recalculate the total allocation size
 		new_size = usr_new_size + redzone_size;
 		// Check for overflow once at the end
@@ -946,35 +780,19 @@
 		}
 	}
 
-	void *new_ptr;
-	if (zone->wrapped_zone->version >= 16) {
-		new_ptr = DELEGATE(malloc_type_malloc, new_size, type_id);
-	} else {
-#if MALLOC_TARGET_64BIT
-		malloc_set_tsd_type_descriptor(
-				(malloc_type_descriptor_t){ .type_id = type_id });
-#endif // MALLOC_TARGET_64BIT
-		new_ptr = DELEGATE(malloc, new_size);
-#if MALLOC_TARGET_64BIT
-		malloc_set_tsd_type_descriptor(MALLOC_TYPE_DESCRIPTOR_NONE);
-#endif // MALLOC_TARGET_64BIT
-	}
-
-#if !MALLOC_TARGET_EXCLAVES
+	void *new_ptr = DELEGATE(malloc, new_size);
 	record_alloc_stacktrace(zone->depo, zone->map, new_ptr, usr_new_size);
-#endif /* !MALLOC_TARGET_EXCLAVES */
 	if (zone->debug) malloc_report(ASL_LEVEL_INFO, "realloc(%p, 0x%lx) = %p\n", ptr, new_size, new_ptr);
 
 	if (ptr != NULL) {
 		size_t old_redzone_size = 0;
 		const size_t old_size = DELEGATE(size, ptr);
-		void *old_ptr = __unsafe_forge_bidi_indexable(void *, ptr, old_size);
 		if (zone->do_poisoning) {
-			old_redzone_size = get_redzone_size(zone, old_ptr, old_size);
+			old_redzone_size = get_redzone_size(zone, ptr, old_size);
 			MALLOC_ASSERT(old_size > old_redzone_size);
 		}
 
-		if (zone->debug) malloc_report(ASL_LEVEL_INFO, "realloc(%p, 0x%lx): size(%p) = 0x%lx - redzone 0x%lx)\n", ptr, new_size, old_ptr, old_size, old_redzone_size);
+		if (zone->debug) malloc_report(ASL_LEVEL_INFO, "realloc(%p, 0x%lx): size(%p) = 0x%lx - redzone 0x%lx)\n", ptr, new_size, ptr, old_size, old_redzone_size);
 
 		// Don't free/quarantine the old pointer if allocation failed. Per man page:
 		// > For realloc(), the input pointer is still valid if reallocation failed.
@@ -983,55 +801,37 @@
 		}
 
 		const size_t usr_old_size = old_size - old_redzone_size;
-		memcpy(new_ptr, old_ptr, MIN(usr_old_size, usr_new_size));
+		memcpy(new_ptr, ptr, MIN(usr_old_size, usr_new_size));
 		if (zone->do_poisoning) {
-			poison_free(zone, old_ptr, old_size);
+			poison_free(zone, ptr, old_size);
 		}
 		place_into_quarantine(zone, ptr, old_size);
 	}
 
-	if (new_ptr && zone->do_poisoning) {
-		// Recalculate the redzone size to include allocator padding
-		size_t actual_size = DELEGATE(size, new_ptr);
-		MALLOC_ASSERT(actual_size >= new_size);
-		redzone_size += actual_size - new_size;
-		new_ptr = __unsafe_forge_bidi_indexable(void *, new_ptr,
-				usr_new_size + redzone_size);
+	if (zone->do_poisoning) {
 		poison_alloc(zone, new_ptr, usr_new_size, redzone_size);
 	}
 	return new_ptr;
 }
 
-static void * __alloc_size(3) __sized_by_or_null(new_size)
-sanitizer_realloc(sanitizer_zone_t *zone, void * __unsafe_indexable ptr, size_t new_size)
-{
-	return sanitizer_malloc_type_realloc(zone, ptr, new_size,
-			malloc_get_tsd_type_id());
-}
-
 static void
 sanitizer_destroy(sanitizer_zone_t *zone)
 {
-#if !MALLOC_TARGET_EXCLAVES
 	stacktrace_depo_destroy(zone->depo);
 	pointer_map_destroy(zone->map);
 	malloc_destroy_zone(zone->wrapped_zone);
 	sanitizer_vm_deallocate((vm_address_t)zone, sizeof(sanitizer_zone_t));
-#else
-	(void)zone;
-#endif /* !MALLOC_TARGET_EXCLAVES */
-}
-
-static void * __alloc_align(2) __alloc_size(3) __sized_by_or_null(size)
-sanitizer_malloc_type_memalign(sanitizer_zone_t *zone, size_t align,
-		size_t size, malloc_type_id_t type_id)
-{
-	if (!size) {
-		size = 1;
-	}
+}
+
+static void *
+sanitizer_memalign(sanitizer_zone_t *zone, size_t alignment, size_t size)
+{
 	size_t redzone_size = zone->redzone_size;
 	const size_t usr_size = size;
 	if (zone->do_poisoning) {
+		// Round up redzone so that allocation is padded to shadow alignment
+		const size_t padded_sz = roundup(usr_size + redzone_size, ASAN_SHADOW_ALIGNMENT);
+		redzone_size += padded_sz - (usr_size + redzone_size);
 		// Recalculate the total allocation size
 		size = usr_size + redzone_size;
 		// Check for overflow once at the end
@@ -1039,118 +839,55 @@
 			return NULL;
 		}
 	}
-
-	void *ptr;
-	if (zone->wrapped_zone->version >= 16) {
-		ptr = DELEGATE(malloc_type_memalign, align, size, type_id);
-	} else {
-#if MALLOC_TARGET_64BIT
-		malloc_set_tsd_type_descriptor(
-				(malloc_type_descriptor_t){ .type_id = type_id });
-#endif // MALLOC_TARGET_64BIT
-		ptr = DELEGATE(memalign, align, size);
-#if MALLOC_TARGET_64BIT
-		malloc_set_tsd_type_descriptor(MALLOC_TYPE_DESCRIPTOR_NONE);
-#endif // MALLOC_TARGET_64BIT
-	}
-
-#if !MALLOC_TARGET_EXCLAVES
+	void *ptr = DELEGATE(memalign, alignment, size);
 	record_alloc_stacktrace(zone->depo, zone->map, ptr, usr_size);
-#endif /* !MALLOC_TARGET_EXCLAVES */
-	if (zone->debug) malloc_report(ASL_LEVEL_INFO, "memalign(0x%lx, 0x%lx)\n", align, size);
-	if (ptr && zone->do_poisoning) {
-		// Recalculate the redzone size to include allocator padding
-		size_t actual_size = DELEGATE(size, ptr);
-		MALLOC_ASSERT(actual_size >= size);
-		redzone_size += actual_size - size;
-		ptr = __unsafe_forge_bidi_indexable(void *, ptr,
-				usr_size + redzone_size);
+	if (zone->debug) malloc_report(ASL_LEVEL_INFO, "memalign(0x%lx, 0x%lx)\n", alignment, size);
+	if (zone->do_poisoning) {
+		// Recalculate the redzone size due to allocator padding
+		size = DELEGATE(size, ptr);
+		MALLOC_ASSERT(size >= usr_size && size - usr_size >= redzone_size);
+		redzone_size = size - usr_size;
 		poison_alloc(zone, ptr, usr_size, redzone_size);
 	}
 	return ptr;
 }
 
-static void * __alloc_align(2) __alloc_size(3) __sized_by_or_null(size)
-sanitizer_memalign(sanitizer_zone_t *zone, size_t align, size_t size)
-{
-	return sanitizer_malloc_type_memalign(zone, align, size,
-			malloc_get_tsd_type_id());
-}
-
-static void * __alloc_align(2) __alloc_size(3) __sized_by_or_null(size)
-sanitizer_malloc_type_malloc_with_options(sanitizer_zone_t *zone, size_t align,
-		size_t size, malloc_zone_malloc_options_t options,
-		malloc_type_id_t type_id)
-{
-#if CONFIG_MTE
-	// rdar://140822174
-	// When dyld interposition or a wrapper zone that does not support
-	// forwarding malloc options is enabled, we need to set a flag in
-	// the TSD to preserve the semantics of canonical tagging.
-	bool use_tsd_fallback =
-			(options & MALLOC_ZONE_MALLOC_OPTION_CANONICAL_TAG) &&
-			(zone->wrapped_zone->version < 15 ||
-			!zone->wrapped_zone->malloc_with_options);
-#if !MALLOC_TARGET_EXCLAVES
-	malloc_thread_options_t opts;
-	if (use_tsd_fallback) {
-		opts = malloc_get_thread_options();
-		malloc_thread_options_t newopts = opts;
-		newopts.ReservedFlag = true;
-		_malloc_set_thread_options(newopts);
-	}
-#else
-	MALLOC_ASSERT(!use_tsd_fallback);
-#endif // MALLOC_TARGET_EXCLAVES
-#endif // CONFIG_MTE
-
-	void *ptr;
-	if (!align) {
-		ptr = sanitizer_malloc_type_malloc_noalign_with_options(zone, size,
-			options, type_id);
-	} else {
-		ptr = sanitizer_malloc_type_memalign(zone, align, size, type_id);
-		if (ptr && (options & MALLOC_ZONE_MALLOC_OPTION_CLEAR)) {
-			bzero(ptr, size);
-		}
-	}
-
-#if CONFIG_MTE
-#if !MALLOC_TARGET_EXCLAVES
-	// Restore the saved TSD flags
-	if (use_tsd_fallback) {
-		_malloc_set_thread_options(opts);
-	}
-#endif // MALLOC_TARGET_EXCLAVES
-#endif // CONFIG_MTE
-
-	return ptr;
-}
-
-static void * __alloc_align(2) __alloc_size(3) __sized_by_or_null(size)
-sanitizer_malloc_with_options(sanitizer_zone_t *zone, size_t align, size_t size,
-		malloc_zone_malloc_options_t options)
-{
-	return sanitizer_malloc_type_malloc_with_options(zone, align, size, options,
-			malloc_get_tsd_type_id());
-}
-
-static void
-sanitizer_free_definite_size(sanitizer_zone_t *zone, void * __sized_by(size) ptr, size_t size)
+static void
+sanitizer_free_definite_size(sanitizer_zone_t *zone, void *ptr, size_t size)
 {
 	if (zone->debug) malloc_report(ASL_LEVEL_INFO, "free_definite_size(%p, 0x%lx)\n", ptr, size);
 	if (zone->do_poisoning) {
 		// Provided size is the user accessible size, but we need the total size
-		const size_t actual_size = DELEGATE(size, ptr);
-		ptr = __unsafe_forge_bidi_indexable(void *, ptr, actual_size);
-		size = actual_size;
+		size = DELEGATE(size, ptr);
 		poison_free(zone, ptr, size);
 	}
 	place_into_quarantine(zone, ptr, size);
 }
 
+static unsigned
+sanitizer_batch_malloc(sanitizer_zone_t *zone, size_t size, void **results, unsigned count)
+{
+	if (zone->debug) malloc_report(ASL_LEVEL_INFO, "batch_malloc(0x%lx, %p, 0x%x)\n", size, results, count);
+	return 0;
+}
+
+static void
+sanitizer_batch_free(sanitizer_zone_t *zone, void **to_be_freed, unsigned count)
+{
+	if (zone->debug) malloc_report(ASL_LEVEL_INFO, "batch_free(%p, 0x%x)\n", to_be_freed, count);
+	for (long i = 0; i < count; i++) {
+		place_into_quarantine(zone, to_be_freed[i], 0);
+	}
+}
+
+static size_t
+sanitizer_pressure_relief(sanitizer_zone_t *zone, size_t goal)
+{
+	return DELEGATE(pressure_relief, goal);
+}
+
 static bool
-sanitizer_claimed_address(sanitizer_zone_t *zone, void * __unsafe_indexable ptr)
+sanitizer_claimed_address(sanitizer_zone_t *zone, void *ptr)
 {
 	return DELEGATE(claimed_address, ptr);
 }
@@ -1230,7 +967,7 @@
 	return !lock_taken;
 }
 
-#if !MALLOC_TARGET_EXCLAVES
+
 #pragma mark -
 #pragma mark Crash Reporter API
 
@@ -1257,7 +994,7 @@
 } enumeration_context;
 
 static void
-pointer_recorder(task_t task, void *context, unsigned type, vm_range_t * __counted_by(count) ranges, unsigned count)
+pointer_recorder(task_t task, void *context, unsigned type, vm_range_t *ranges, unsigned count)
 {
 	vm_address_t a = enumeration_context.address_to_lookup;
 	for (int i = 0; i < count; i++) {
@@ -1293,11 +1030,11 @@
 	szone_introspect.enumerator(task, NULL, MALLOC_PTR_IN_USE_RANGE_TYPE, (vm_address_t)remote_zone->wrapped_zone,
 								memory_reader_adapter, pointer_recorder);
 	for (uint32_t i = 0; i < num_read_memory; i++) {
-		_free(read_memory[i]);
+		free(read_memory[i]);
 	}
 	g_crm_reader = NULL;
 
-	bzero(report, sizeof(*report));
+	memset(report, 0, sizeof(*report));
 	report->fault_address = fault_address;
 
 	if (enumeration_context.found_range.address != 0) {
@@ -1309,26 +1046,24 @@
 		uint32_t dealloc_handle = (uint32_t)(chunk->stacktrace_hashes >> 32);
 
 		report->alloc_trace.thread_id = 0;
-		// Explicit cast (report->alloc_trace.frames) as it doesn't otherwise compile on watchOS (error: implicit conversion loses integer precision)
 		report->alloc_trace.num_frames = (uint32_t)stacktrace_depo_find(remote_depo, alloc_handle,
-				(uintptr_t *)report->alloc_trace.frames, countof(report->alloc_trace.frames));
+				report->alloc_trace.frames, countof(report->alloc_trace.frames));
 
 		report->dealloc_trace.thread_id = 0;
-		// Explicit cast (report->dealloc_trace.frames) as it doesn't otherwise compile on watchOS (error: implicit conversion loses integer precision)
 		report->dealloc_trace.num_frames = (uint32_t)stacktrace_depo_find(remote_depo, dealloc_handle,
-				(uintptr_t *)report->dealloc_trace.frames, countof(report->dealloc_trace.frames));
-
-		_free(chunk);
-	}
-
-	_free(remote_depo);
-	_free(remote_pointer_map);
-	_free(remote_zone);
+				report->dealloc_trace.frames, countof(report->dealloc_trace.frames));
+
+		free(chunk);
+	}
+
+	free(remote_depo);
+	free(remote_pointer_map);
+	free(remote_zone);
 
 	_malloc_lock_unlock(&crash_reporter_lock);
 	return KERN_SUCCESS;
 }
-#endif /* !MALLOC_TARGET_EXCLAVES */
+
 
 #pragma mark -
 #pragma mark Zone Templates
@@ -1368,9 +1103,6 @@
 #else
 	.enumerate_unavailable_without_blocks = NULL,
 #endif
-
-	// Zone type
-	.zone_type = MALLOC_ZONE_TYPE_SANITIZER,
 };
 
 static const malloc_zone_t malloc_zone_template = {
@@ -1388,29 +1120,19 @@
 	.destroy = FN_PTR(sanitizer_destroy),
 
 	// Batch operations
-	.batch_malloc = malloc_zone_batch_malloc_fallback,
-	.batch_free = malloc_zone_batch_free_fallback,
+	.batch_malloc = FN_PTR(sanitizer_batch_malloc),
+	.batch_free = FN_PTR(sanitizer_batch_free),
 
 	// Introspection
 	.zone_name = "SanitizerMallocZone",
-	.version = 16,
+	.version = 12,
 	.introspect = &sanitizer_zone_introspect_template,
 
 	// Specialized operations
 	.memalign = FN_PTR(sanitizer_memalign),
 	.free_definite_size = FN_PTR(sanitizer_free_definite_size),
-	.pressure_relief = malloc_zone_pressure_relief_fallback,
-	.claimed_address = FN_PTR(sanitizer_claimed_address),
-	.try_free_default = NULL,
-	.malloc_with_options = FN_PTR(sanitizer_malloc_with_options),
-
-	// Typed operations
-	.malloc_type_malloc = FN_PTR(sanitizer_malloc_type_malloc),
-	.malloc_type_calloc = FN_PTR(sanitizer_malloc_type_calloc),
-	.malloc_type_realloc = FN_PTR(sanitizer_malloc_type_realloc),
-	.malloc_type_memalign = FN_PTR(sanitizer_malloc_type_memalign),
-	.malloc_type_malloc_with_options =
-			FN_PTR(sanitizer_malloc_type_malloc_with_options),
+	.pressure_relief = FN_PTR(sanitizer_pressure_relief),
+	.claimed_address = FN_PTR(sanitizer_claimed_address)
 };
 
 
@@ -1420,80 +1142,48 @@
 bool
 sanitizer_should_enable(void)
 {
-#if !MALLOC_TARGET_EXCLAVES
 	return env_bool("MallocSanitizerZone") || env_bool("MallocQuarantineZone");
-#elif __LIBLIBC_F_ASAN_INSTRUMENTATION
-	return true;
-#else
-	return false;
-#endif /* !MALLOC_TARGET_EXCLAVES */
 }
 
 void
 sanitizer_reset_environment(void)
 {
-#if !MALLOC_TARGET_EXCLAVES
 	// Unset MallocSanitizerZone from the environment to avoid propagating it
 	// to any child processes (posix_spawn, exec, fork).
 	unsetenv("MallocSanitizerZone");
 	unsetenv("MallocQuarantineZone");
-#endif /* !MALLOC_TARGET_EXCLAVES */
 }
 
 malloc_zone_t *
 sanitizer_create_zone(malloc_zone_t *wrapped_zone)
 {
-#if !MALLOC_TARGET_EXCLAVES
-	sanitizer_zone_t *zone = __unsafe_forge_single(sanitizer_zone_t *,
-		sanitizer_vm_map(sizeof(sanitizer_zone_t), VM_PROT_READ | VM_PROT_WRITE,
-			VM_MEMORY_MALLOC));
-#else
-	sanitizer_zone_t *zone = &sanitizer_zone;
-#endif /* !MALLOC_TARGET_EXCLAVES */
+	sanitizer_zone_t *zone = (sanitizer_zone_t *)sanitizer_vm_map(sizeof(sanitizer_zone_t),
+		VM_PROT_READ | VM_PROT_WRITE, VM_MEMORY_MALLOC);
 	zone->malloc_zone = malloc_zone_template;
 
-#if !MALLOC_TARGET_EXCLAVES
 	// Since we are calling szone_introspect.enumerator directly, see
 	// sanitizer_diagnose_fault_from_crash_reporter.
 	MALLOC_ASSERT(wrapped_zone->introspect == &szone_introspect);
-#endif /* !MALLOC_TARGET_EXCLAVES */
 	zone->wrapped_zone = wrapped_zone;
 
-	if (wrapped_zone->version < 13) {
-		malloc_report(MALLOC_REPORT_CRASH,
-				"Unsupported wrapped zone version: %u\n",
-				wrapped_zone->version);
-	}
-
-#if !MALLOC_TARGET_EXCLAVES
 	zone->debug = env_bool("MallocSanitizerZoneDebug");
+#if TARGET_OS_EXCLAVECORE || TARGET_OS_EXCLAVEKIT
+	zone->do_poisoning = true;
+#else
 	zone->do_poisoning = !env_bool("MallocSanitizerNoPoisoning");
+#endif
 	zone->redzone_size = env_uint("MallocSanitizerRedzoneSize", 16); // default is 16 bytes
-#else
-	zone->debug = false;
-	zone->do_poisoning = true;
-	zone->redzone_size = 16;
-#endif /* !MALLOC_TARGET_EXCLAVES */
 	MALLOC_ASSERT((zone->redzone_size % ASAN_SHADOW_ALIGNMENT) == 0);
-#if !MALLOC_TARGET_EXCLAVES
 	zone->max_items_in_quarantine = env_uint("MallocQuarantineMaxItems", 0); // default is 0 = unlimited
 	zone->max_bytes_in_quarantine = (size_t)env_uint("MallocQuarantineMaxSizeInMB", 256) << 20; // 256 MB is default
-#else
-	zone->max_items_in_quarantine = 0;
-	zone->max_bytes_in_quarantine = 256 << 20;
-#endif /* !MALLOC_TARGET_EXCLAVES */
-
-#if !MALLOC_TARGET_EXCLAVES
+
 	zone->depo = stacktrace_depo_create();
 	zone->map = pointer_map_create();
-#endif /* !MALLOC_TARGET_EXCLAVES */
 
 	// Init mutable state
 	init_lock(zone);
-#if !MALLOC_TARGET_EXCLAVES
 	sanitizer_vm_protect((vm_address_t)zone, PAGE_MAX_SIZE, VM_PROT_READ);
-#endif /* !MALLOC_TARGET_EXCLAVES */
-	return __unsafe_forge_single(malloc_zone_t *, zone);
+	return (malloc_zone_t *)zone;
 }
 
 #else // CONFIG_SANITIZER