Home | History | Annotate | Download | only in Darwin
      1 // Regression test for a bug in malloc_create_zone()
      2 // (https://code.google.com/p/address-sanitizer/issues/detail?id=203)
      3 // The old implementation of malloc_create_zone() didn't always return a
      4 // page-aligned address, so we can only test on a best-effort basis.
      5 
      6 // RUN: %clangxx_asan %s -o %t
      7 // RUN: %run %t 2>&1
      8 
      9 #include <malloc/malloc.h>
     10 #include <stdlib.h>
     11 #include <string.h>
     12 #include <stdio.h>
     13 
     14 const int kNumIter = 4096;
     15 const int kNumZones = 100;
     16 int main() {
     17   char *mem[kNumIter * 2];
     18   // Allocate memory chunks from different size classes up to 1 page.
     19   // (For the case malloc() returns memory chunks in descending order)
     20   for (int i = 0; i < kNumIter; i++) {
     21     mem[i] = (char*)malloc(8 * i);
     22   }
     23   // Try to allocate a page-aligned malloc zone. Otherwise the mprotect() call
     24   // in malloc_set_zone_name() will silently fail.
     25   malloc_zone_t *zone = NULL;
     26   bool aligned = false;
     27   for (int i = 0; i < kNumZones; i++) {
     28     zone = malloc_create_zone(0, 0);
     29     if (((uintptr_t)zone & (~0xfff)) == (uintptr_t)zone) {
     30       aligned = true;
     31       break;
     32     }
     33   }
     34   if (!aligned) {
     35     printf("Warning: couldn't allocate a page-aligned zone.");
     36     return 0;
     37   }
     38   // malloc_set_zone_name() calls mprotect(zone, 4096, PROT_READ | PROT_WRITE),
     39   // modifies the zone contents and then calls mprotect(zone, 4096, PROT_READ).
     40   malloc_set_zone_name(zone, "foobar");
     41   // Allocate memory chunks from different size classes again.
     42   for (int i = 0; i < kNumIter; i++) {
     43     mem[i + kNumIter] = (char*)malloc(8 * i);
     44   }
     45   // Access the allocated memory chunks and free them.
     46   for (int i = 0; i < kNumIter * 2; i++) {
     47     memset(mem[i], 'a', 8 * (i % kNumIter));
     48     free(mem[i]);
     49   }
     50   return 0;
     51 }
     52