Loading...
--- libmalloc/libmalloc-792.41.1/tests/pgm_integration.c
+++ libmalloc/libmalloc-409.40.6/tests/pgm_integration.c
@@ -6,18 +6,15 @@
//
#include <darwintest.h>
-#include <MallocStackLogging/MallocStackLogging.h>
-
-T_GLOBAL_META(T_META_RUN_CONCURRENTLY(TRUE), T_META_NAMESPACE("pgm"),
- T_META_TAG_ALL_ALLOCATORS);
-
-#include <mach/mach_vm.h> // mach_vm_map()
-#include <mach/mach.h> // mach_task_self()
+
+T_GLOBAL_META(T_META_RUN_CONCURRENTLY(TRUE), T_META_NAMESPACE("pgm"));
+
#include <mach/vm_page_size.h>
-#include <malloc_private.h>
#include <malloc/malloc.h>
#include <stdlib.h>
#include <unistd.h>
+
+#include "../src/platform.h" // CONFIG_PGM_WRAP_CUSTOM_ZONES
T_GLOBAL_META(
T_META_ENVVAR("MallocProbGuard=1"),
@@ -26,28 +23,12 @@
T_META_ENVVAR("MallocProbGuardAllocations=300")
);
-static malloc_zone_t *
-get_wrapped_zone(malloc_zone_t *zone)
-{
- malloc_zone_t *wrapped_zone;
- kern_return_t kr = malloc_get_wrapped_zone(mach_task_self(),
- /*memory_reader=*/NULL, (vm_address_t)zone, (vm_address_t *)&wrapped_zone);
- T_QUIET; T_ASSERT_EQ(kr, KERN_SUCCESS, "malloc_get_wrapped_zone() failed");
- T_EXPECT_NOTNULL(wrapped_zone, "Wrapped zone");
- return wrapped_zone;
-}
-
extern int32_t malloc_num_zones;
extern malloc_zone_t **malloc_zones;
-T_DECL(zone_setup, "ProbGuard zone is default zone and not full", T_META_TAG_VM_PREFERRED)
-{
- // malloc_default_zone() returns virtual zone, which delegates to zone 0.
- malloc_zone_t *zone0 = malloc_zones[0];
- T_EXPECT_EQ_STR(malloc_get_zone_name(zone0), "ProbGuardMallocZone",
- "ProbGuard zone is default zone");
- T_EXPECT_EQ(zone0->introspect->zone_type, 2, "MALLOC_ZONE_TYPE_PGM");
- T_EXPECT_EQ(get_wrapped_zone(zone0), malloc_zones[1],
- "Wrapped zone is registered");
+T_DECL(zone_setup, "ProbGuard zone is default zone and not full")
+{
+ const char *default_zone_name = malloc_get_zone_name(malloc_zones[0]);
+ T_EXPECT_EQ_STR(default_zone_name, "ProbGuardMallocZone", "ProbGuard zone is default zone");
void *ptr = malloc(5);
malloc_zone_t *zone = malloc_zone_from_ptr(ptr);
@@ -96,56 +77,40 @@
touch_memory(ptr + 17);
}
+static void
+out_of_bounds_within_block(void)
+{
+ uint8_t *ptr = malloc(5);
+ T_ASSERT_EQ(malloc_size(ptr), 5ul, "strict alignment");
+
+ touch_memory(ptr - 1); // left-alignment is always perfect
+ touch_memory(ptr + 5);
+}
+
T_DECL(uaf_detection, "Use-after-free detection",
+ T_META_IGNORECRASHES("pgm_integration"))
+{
+ assert_crash(use_after_free);
+}
+
+T_DECL(oob_detection, "Out-of-bounds detection",
+ T_META_IGNORECRASHES("pgm_integration"))
+{
+ assert_crash(out_of_bounds);
+}
+
+T_DECL(oob_detection_within_block, "Intra-block out-of-bounds detection",
T_META_IGNORECRASHES("pgm_integration"),
- T_META_TAG_VM_PREFERRED)
-{
- assert_crash(use_after_free);
-}
-
-T_DECL(oob_detection, "Out-of-bounds detection",
- T_META_IGNORECRASHES("pgm_integration"),
- T_META_TAG_VM_PREFERRED)
-{
- assert_crash(out_of_bounds);
-}
-
-static void
-access_in_bogus_pgm_region(void)
-{
- mach_vm_address_t vm_addr = 0;
- kern_return_t kr = mach_vm_map(mach_task_self(), &vm_addr, PAGE_SIZE, 0,
- VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_MEMORY_MALLOC_PROB_GUARD),
- MEMORY_OBJECT_NULL, 0, FALSE, VM_PROT_NONE, VM_PROT_NONE,
- VM_INHERIT_DEFAULT);
- T_ASSERT_MACH_SUCCESS(kr, "allocated bogus PGM region");
- touch_memory((uint8_t *)vm_addr);
-}
-
-T_DECL(bogus_pgm_region, "Handle crashes in bogus PGM regions",
- T_META_IGNORECRASHES("pgm_integration"), T_META_TAG_VM_PREFERRED)
-{
- // What we're really testing here is the code that runs in ReportCrash to
- // generate the PGM report - it needs to gracefully handle unexpected PGM
- // state in a crashing process
- assert_crash(access_in_bogus_pgm_region);
-}
-
-static void
-non_default_zone_use_after_free(void)
-{
- malloc_zone_t *zone = malloc_create_zone(0, 0);
- void *ptr = malloc_zone_malloc(zone, 1);
- free(ptr);
- touch_memory(ptr);
-}
-
-T_DECL(non_default_zone_uaf_detection,
- "Use-after-free detection in a wrapped non-default zone",
- T_META_IGNORECRASHES("pgm_integration"),
- T_META_TAG_VM_PREFERRED)
-{
- assert_crash(non_default_zone_use_after_free);
+ T_META_ENVVAR("MallocProbGuard=1"),
+ T_META_ENVVAR("MallocProbGuardSampleRate=1"),
+ T_META_ENVVAR("MallocProbGuardAllocations=300"),
+ T_META_ENVVAR("MallocProbGuardStrictAlignment=1"))
+{
+#if __LP64__ // MALLOC_TARGET_64BIT
+ assert_crash(out_of_bounds_within_block);
+#else
+ T_SKIP("ARM (32 bit) crashes on misaligned memory accesses: EXC_ARM_DA_ALIGN");
+#endif
}
static boolean_t
@@ -206,14 +171,14 @@
}
}
-T_DECL(allocation_sample_all, "Smoke test, sample 1/1", T_META_TAG_VM_PREFERRED)
+T_DECL(allocation_sample_all, "Smoke test, sample 1/1")
{
smoke_test_100();
T_PASS("Smoke test, sample all");
}
T_DECL(allocation_sample_half, "Smoke test, sample 1/2",
- T_META_ENVVAR("MallocProbGuard=1"), T_META_TAG_VM_PREFERRED,
+ T_META_ENVVAR("MallocProbGuard=1"),
T_META_ENVVAR("MallocProbGuardSampleRate=2"))
{
smoke_test_100();
@@ -249,7 +214,7 @@
malloc_zone_statistics(zone, &stats_after);
}
-T_DECL(introspection_statistics, "Zone statistics", T_META_TAG_VM_PREFERRED)
+T_DECL(introspection_statistics, "Zone statistics")
{
setup_introspection_scenario();
@@ -331,53 +296,32 @@
free_read_memory();
}
-T_DECL(introspection_enumerate_regions, "Region enumeration", T_META_TAG_VM_PREFERRED)
+T_DECL(introspection_enumerate_regions, "Region enumeration")
{
setup_introspection_scenario();
check_enumerator(MALLOC_PTR_REGION_RANGE_TYPE);
}
-T_DECL(introspection_enumerate_blocks, "Block enumeration", T_META_TAG_VM_PREFERRED)
+T_DECL(introspection_enumerate_blocks, "Block enumeration")
{
setup_introspection_scenario();
check_enumerator(MALLOC_PTR_IN_USE_RANGE_TYPE);
}
-T_DECL(wrap_malloc_create_zone, "Wrap malloc_create_zone()", T_META_TAG_VM_PREFERRED)
-{
- // Make sure we only query the environment during process launch.
- setenv("MallocProbGuard", "0", /*overwrite=*/true);
-
+T_DECL(wrap_malloc_create_zone, "Wrap malloc_create_zone()")
+{
uint32_t num_zones = malloc_num_zones;
+
malloc_zone_t *zone = malloc_create_zone(0, 0);
-
- T_EXPECT_EQ_STR(malloc_get_zone_name(zone), "ProbGuardMallocZone", "PGM zone");
- T_EXPECT_EQ(zone->introspect->zone_type, 2, "MALLOC_ZONE_TYPE_PGM");
-
+#if CONFIG_PGM_WRAP_CUSTOM_ZONES
+ T_EXPECT_EQ_STR(malloc_get_zone_name(zone), "ProbGuardMallocZone", "PGM-wrapped zone");
T_EXPECT_EQ(malloc_num_zones, num_zones + 2, "registered both zones");
- T_EXPECT_EQ(malloc_zones[num_zones], zone, "PGM zone is registered");
- T_EXPECT_EQ(malloc_zones[num_zones + 1], get_wrapped_zone(zone),
- "Wrapped zone is registered");
malloc_destroy_zone(zone);
T_EXPECT_EQ(malloc_num_zones, num_zones, "unregistered both zones");
-}
-
-T_DECL(disable_pgm_on_lite_zone,
- "The lite zone's helper zone shouldn't be wrapped by PGM",
- T_META_TAG_VM_PREFERRED)
-{
- // Enabling MSL Lite will register the lite zone (via malloc_zone_register)
- // and a helper zone (via malloc_create_zone). The latter needs to not
- // insert PGM to avoid extra allocations in the underlying zone that don't
- // have MSL metadata
- uint32_t num_zones = malloc_num_zones;
-
- bool enable = msl_turn_on_stack_logging(msl_mode_lite);
- T_ASSERT_TRUE(enable, "Enabled MSL Lite");
-
- T_EXPECT_EQ(malloc_num_zones, num_zones + 2,
- "Enabling MSL generated 2 new zones");
-}
+#else
+ T_EXPECT_EQ(malloc_num_zones, num_zones + 1, "no PGM wrapper zone");
+#endif
+}