1 #include "test/jemalloc_test.h" 2 3 #define QUARANTINE_SIZE 8192 4 #define STRINGIFY_HELPER(x) #x 5 #define STRINGIFY(x) STRINGIFY_HELPER(x) 6 7 #ifdef JEMALLOC_FILL 8 const char *malloc_conf = "abort:false,junk:true,redzone:true,quarantine:" 9 STRINGIFY(QUARANTINE_SIZE); 10 #endif 11 12 void 13 quarantine_clear(void) 14 { 15 void *p; 16 17 p = mallocx(QUARANTINE_SIZE*2, 0); 18 assert_ptr_not_null(p, "Unexpected mallocx() failure"); 19 dallocx(p, 0); 20 } 21 22 TEST_BEGIN(test_quarantine) 23 { 24 #define SZ ZU(256) 25 #define NQUARANTINED (QUARANTINE_SIZE/SZ) 26 void *quarantined[NQUARANTINED+1]; 27 size_t i, j; 28 29 test_skip_if(!config_fill); 30 31 assert_zu_eq(nallocx(SZ, 0), SZ, 32 "SZ=%zu does not precisely equal a size class", SZ); 33 34 quarantine_clear(); 35 36 /* 37 * Allocate enough regions to completely fill the quarantine, plus one 38 * more. The last iteration occurs with a completely full quarantine, 39 * but no regions should be drained from the quarantine until the last 40 * deallocation occurs. Therefore no region recycling should occur 41 * until after this loop completes. 42 */ 43 for (i = 0; i < NQUARANTINED+1; i++) { 44 void *p = mallocx(SZ, 0); 45 assert_ptr_not_null(p, "Unexpected mallocx() failure"); 46 quarantined[i] = p; 47 dallocx(p, 0); 48 for (j = 0; j < i; j++) { 49 assert_ptr_ne(p, quarantined[j], 50 "Quarantined region recycled too early; " 51 "i=%zu, j=%zu", i, j); 52 } 53 } 54 #undef NQUARANTINED 55 #undef SZ 56 } 57 TEST_END 58 59 static bool detected_redzone_corruption; 60 61 static void 62 arena_redzone_corruption_replacement(void *ptr, size_t usize, bool after, 63 size_t offset, uint8_t byte) 64 { 65 66 detected_redzone_corruption = true; 67 } 68 69 TEST_BEGIN(test_quarantine_redzone) 70 { 71 char *s; 72 arena_redzone_corruption_t *arena_redzone_corruption_orig; 73 74 test_skip_if(!config_fill); 75 76 arena_redzone_corruption_orig = arena_redzone_corruption; 77 arena_redzone_corruption = arena_redzone_corruption_replacement; 78 79 /* Test underflow. */ 80 detected_redzone_corruption = false; 81 s = (char *)mallocx(1, 0); 82 assert_ptr_not_null((void *)s, "Unexpected mallocx() failure"); 83 s[-1] = 0xbb; 84 dallocx(s, 0); 85 assert_true(detected_redzone_corruption, 86 "Did not detect redzone corruption"); 87 88 /* Test overflow. */ 89 detected_redzone_corruption = false; 90 s = (char *)mallocx(1, 0); 91 assert_ptr_not_null((void *)s, "Unexpected mallocx() failure"); 92 s[sallocx(s, 0)] = 0xbb; 93 dallocx(s, 0); 94 assert_true(detected_redzone_corruption, 95 "Did not detect redzone corruption"); 96 97 arena_redzone_corruption = arena_redzone_corruption_orig; 98 } 99 TEST_END 100 101 int 102 main(void) 103 { 104 105 return (test( 106 test_quarantine, 107 test_quarantine_redzone)); 108 } 109