Loading...
--- libmalloc/libmalloc-521.100.59/src/malloc_exclaves.c
+++ libmalloc/libmalloc-657.80.3/src/malloc_exclaves.c
@@ -53,7 +53,7 @@
 malloc_zero_policy_t malloc_zero_policy = MALLOC_ZERO_POLICY_DEFAULT;
 
 static inline malloc_zone_t *
-find_registered_zone(const void * __unsafe_indexable ptr, size_t *returned_size,
+_find_registered_zone(const void * __unsafe_indexable ptr, size_t *returned_size,
 	bool known_non_default)
 {
 	malloc_zone_t *zone;
@@ -87,6 +87,13 @@
 	return zone;
 }
 
+malloc_zone_t *
+find_registered_zone(const void * __unsafe_indexable ptr, size_t *returned_size,
+	bool known_non_default)
+{
+	return _find_registered_zone(ptr, returned_size, known_non_default);
+}
+
 /*********  Creation and destruction    ************/
 
 static void
@@ -154,7 +161,7 @@
 
 /*********  Block creation and manipulation ************/
 
-void *
+void * __sized_by_or_null(size)
 _malloc_zone_malloc(malloc_zone_t *zone, size_t size, malloc_zone_options_t mzo)
 {
 	// This and similar conditionals are commented out to avoid compiler
@@ -169,13 +176,13 @@
 }
 
 MALLOC_NOINLINE
-void *
+void * __sized_by_or_null(size)
 malloc_zone_malloc(malloc_zone_t *zone, size_t size)
 {
 	return _malloc_zone_malloc(zone, size, MZ_NONE);
 }
 
-void *
+void * __sized_by_or_null(num_items * size)
 _malloc_zone_calloc(malloc_zone_t *zone, size_t num_items, size_t size,
 		malloc_zone_options_t mzo)
 {
@@ -191,13 +198,13 @@
 }
 
 MALLOC_NOINLINE
-void *
+void * __sized_by_or_null(num_items * size)
 malloc_zone_calloc(malloc_zone_t *zone, size_t num_items, size_t size)
 {
 	return _malloc_zone_calloc(zone, num_items, size, MZ_NONE);
 }
 
-void *
+void * __sized_by_or_null(size)
 _malloc_zone_valloc(malloc_zone_t *zone, size_t size, malloc_zone_options_t mzo)
 {
 	// if (os_unlikely(malloc_too_large(size))) {
@@ -214,13 +221,13 @@
 }
 
 MALLOC_NOINLINE
-void *
+void * __sized_by_or_null(size)
 malloc_zone_valloc(malloc_zone_t *zone, size_t size)
 {
 	return _malloc_zone_valloc(zone, size, MZ_NONE);
 }
 
-void *
+void * __sized_by_or_null(size)
 _malloc_zone_realloc(malloc_zone_t *zone, void * __unsafe_indexable ptr,
 		size_t size, malloc_type_descriptor_t type_desc)
 {
@@ -232,7 +239,7 @@
 }
 
 MALLOC_NOINLINE
-void *
+void * __sized_by_or_null(size)
 malloc_zone_realloc(malloc_zone_t *zone, void * __unsafe_indexable ptr,
 		size_t size)
 {
@@ -259,11 +266,11 @@
 	if (!ptr) {
 		return NULL;
 	} else {
-		return find_registered_zone(ptr, NULL, false);
-	}
-}
-
-void * __alloc_align(2) __alloc_size(3)
+		return _find_registered_zone(ptr, NULL, false);
+	}
+}
+
+void * __alloc_align(2) __alloc_size(3) __sized_by_or_null(size)
 _malloc_zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size,
 	malloc_zone_options_t mzo, malloc_type_descriptor_t type_desc)
 {
@@ -303,7 +310,7 @@
 }
 
 MALLOC_NOINLINE
-void *
+void * __sized_by_or_null(size)
 malloc_zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size)
 {
 	return _malloc_zone_memalign(zone, alignment, size, MZ_NONE,
@@ -311,7 +318,7 @@
 }
 
 MALLOC_NOINLINE
-void *
+void * __sized_by_or_null(size)
 malloc_zone_malloc_with_options_np(malloc_zone_t *zone, size_t align,
 		size_t size, malloc_options_np_t options)
 {
@@ -324,7 +331,7 @@
 		zone = malloc_zones[0];
 	}
 
-	if (zone->version >= 15) {
+	if (zone->version >= 15 && zone->malloc_with_options) {
 		return zone->malloc_with_options(zone, align, size, options);
 	}
 
@@ -364,7 +371,7 @@
 malloc_set_zone_name(malloc_zone_t *z, const char *name)
 {
 	if (z->zone_name) {
-		malloc_zone_t *old_zone = find_registered_zone(z->zone_name, NULL,
+		malloc_zone_t *old_zone = _find_registered_zone(z->zone_name, NULL,
 			false);
 		if (old_zone) {
 			malloc_zone_free(old_zone, (char *)z->zone_name);
@@ -400,7 +407,7 @@
 		return;
 	}
 
-	zone = find_registered_zone(ptr, &size, known_non_default);
+	zone = _find_registered_zone(ptr, &size, known_non_default);
 	if (!zone) {
 		malloc_report(MALLOC_REPORT_DEBUG | MALLOC_REPORT_NOLOG,
 			"*** error for object %p: pointer being freed was not allocated\n",
@@ -415,27 +422,23 @@
 
 /*********    Generic ANSI callouts    ************/
 
-// FIXME: Return NULL instead but we need bounds checking support
-// rdar://75598414 (Support __counted_by_or_null and __sized_by_or_null)
-#define NONZERO_SZ(sz) ((sz) ? (sz) : 1)
-
-void *
+void * __sized_by_or_null(size)
 malloc(size_t size)
 {
-	return malloc_zone_malloc(_malloc_zones[0], NONZERO_SZ(size));
-}
-
-void *
+	return malloc_zone_malloc(_malloc_zones[0], size);
+}
+
+void * __sized_by_or_null(size)
 aligned_alloc(size_t alignment, size_t size)
 {
-	return _malloc_zone_memalign(_malloc_zones[0], alignment, NONZERO_SZ(size),
+	return _malloc_zone_memalign(_malloc_zones[0], alignment, size,
 		MZ_POSIX | MZ_C11, MALLOC_TYPE_DESCRIPTOR_NONE);
 }
 
-void *
+void * __sized_by_or_null(num_items * size)
 calloc(size_t num_items, size_t size)
 {
-	return malloc_zone_calloc(_malloc_zones[0], num_items, NONZERO_SZ(size));
+	return malloc_zone_calloc(_malloc_zones[0], num_items, size);
 }
 
 void
@@ -459,7 +462,7 @@
 	return _free(ptr);
 }
 
-void *
+void * __sized_by_or_null(new_size)
 _realloc(void * __unsafe_indexable in_ptr, size_t new_size)
 {
 	void * __bidi_indexable retval = NULL;
@@ -476,9 +479,9 @@
 	// size."  So we only free the original memory if the allocation succeeds.
 	old_ptr = (new_size == 0) ? NULL : in_ptr;
 	if (!old_ptr) {
-		retval = malloc_zone_malloc(_malloc_zones[0], NONZERO_SZ(new_size));
-	} else {
-		zone = find_registered_zone(old_ptr, NULL, false);
+		retval = malloc_zone_malloc(_malloc_zones[0], new_size);
+	} else {
+		zone = _find_registered_zone(old_ptr, NULL, false);
 		if (!zone) {
 			malloc_report(MALLOC_REPORT_CRASH,
 				"*** error for object %p: pointer being realloc'd was not allocated\n",
@@ -496,28 +499,33 @@
 	return retval;
 }
 
-void *
+void * __sized_by_or_null(new_size)
 realloc(void * __unsafe_indexable in_ptr, size_t new_size)
 {
 	return _realloc(in_ptr, new_size);
 }
 
-void *
+void * __sized_by_or_null(new_size)
 reallocf(void * __unsafe_indexable in_ptr, size_t new_size)
 {
 	void *ptr = realloc(in_ptr, new_size);
 
 	if (!ptr && in_ptr && new_size != 0) {
+		// Save and restore `errno`, because `realloc` will set it to ENOMEM
+		// on allocation failure, but it could be overwritten if `free` calls
+		// into a library function that also modifies `errno`
+		errno_t error = errno;
 		free(in_ptr);
+		errno = error;
 	}
 
 	return ptr;
 }
 
-void *
+void * __sized_by_or_null(size)
 valloc(size_t size)
 {
-	return _malloc_zone_valloc(_malloc_zones[0], NONZERO_SZ(size), MZ_POSIX);
+	return _malloc_zone_valloc(_malloc_zones[0], size, MZ_POSIX);
 }
 
 size_t
@@ -529,7 +537,7 @@
 		return size;
 	}
 
-	(void)find_registered_zone(ptr, &size, false);
+	(void)_find_registered_zone(ptr, &size, false);
 	return size;
 }
 
@@ -548,7 +556,7 @@
 
 	/* POSIX is silent on NULL == memptr !?! */
 
-	retval = malloc_zone_memalign(_malloc_zones[0], alignment, NONZERO_SZ(size));
+	retval = malloc_zone_memalign(_malloc_zones[0], alignment, size);
 	if (retval == NULL) {
 		// To avoid testing the alignment constraints redundantly, we'll rely on
 		// the test made in malloc_zone_memalign to vet each request. Only if
@@ -591,7 +599,7 @@
 	return false;
 }
 
-void *
+void * __sized_by_or_null(nmemb * size)
 reallocarray(void * in_ptr, size_t nmemb, size_t size)
 {
 	size_t alloc_size;
@@ -602,7 +610,7 @@
 	return realloc(in_ptr, alloc_size);
 }
 
-void *
+void * __sized_by_or_null(nmemb * size)
 reallocarrayf(void * in_ptr, size_t nmemb, size_t size)
 {
 	size_t alloc_size;
@@ -686,5 +694,6 @@
 void
 malloc_zero_on_free_disable(void)
 {
-	malloc_zero_policy = MALLOC_ZERO_NONE;
-}
+	malloc_zone_error(MALLOC_ABORT_ON_ERROR, false,
+			"xzone cannot disable zero on free");
+}