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 8const char *malloc_conf = "abort:false,junk:true,redzone:true,quarantine:" 9 STRINGIFY(QUARANTINE_SIZE); 10#endif 11 12void 13quarantine_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 22TEST_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} 57TEST_END 58 59static bool detected_redzone_corruption; 60 61static void 62arena_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 69TEST_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} 99TEST_END 100 101int 102main(void) 103{ 104 105 return (test( 106 test_quarantine, 107 test_quarantine_redzone)); 108} 109