1 #include "test/jemalloc_test.h" 2 3 #include "jemalloc/internal/safety_check.h" 4 5 /* 6 * Note that we get called through safety_check.sh, which turns on sampling for 7 * everything. 8 */ 9 10 bool fake_abort_called; 11 void fake_abort(const char *message) { 12 (void)message; 13 fake_abort_called = true; 14 } 15 16 static void 17 buffer_overflow_write(char *ptr, size_t size) { 18 /* Avoid overflow warnings. */ 19 volatile size_t idx = size; 20 ptr[idx] = 0; 21 } 22 23 TEST_BEGIN(test_malloc_free_overflow) { 24 test_skip_if(!config_prof); 25 test_skip_if(!config_opt_safety_checks); 26 27 safety_check_set_abort(&fake_abort); 28 /* Buffer overflow! */ 29 char* ptr = malloc(128); 30 buffer_overflow_write(ptr, 128); 31 free(ptr); 32 safety_check_set_abort(NULL); 33 34 expect_b_eq(fake_abort_called, true, "Redzone check didn't fire."); 35 fake_abort_called = false; 36 } 37 TEST_END 38 39 TEST_BEGIN(test_mallocx_dallocx_overflow) { 40 test_skip_if(!config_prof); 41 test_skip_if(!config_opt_safety_checks); 42 43 safety_check_set_abort(&fake_abort); 44 /* Buffer overflow! */ 45 char* ptr = mallocx(128, 0); 46 buffer_overflow_write(ptr, 128); 47 dallocx(ptr, 0); 48 safety_check_set_abort(NULL); 49 50 expect_b_eq(fake_abort_called, true, "Redzone check didn't fire."); 51 fake_abort_called = false; 52 } 53 TEST_END 54 55 TEST_BEGIN(test_malloc_sdallocx_overflow) { 56 test_skip_if(!config_prof); 57 test_skip_if(!config_opt_safety_checks); 58 59 safety_check_set_abort(&fake_abort); 60 /* Buffer overflow! */ 61 char* ptr = malloc(128); 62 buffer_overflow_write(ptr, 128); 63 sdallocx(ptr, 128, 0); 64 safety_check_set_abort(NULL); 65 66 expect_b_eq(fake_abort_called, true, "Redzone check didn't fire."); 67 fake_abort_called = false; 68 } 69 TEST_END 70 71 TEST_BEGIN(test_realloc_overflow) { 72 test_skip_if(!config_prof); 73 test_skip_if(!config_opt_safety_checks); 74 75 safety_check_set_abort(&fake_abort); 76 /* Buffer overflow! */ 77 char* ptr = malloc(128); 78 buffer_overflow_write(ptr, 128); 79 ptr = realloc(ptr, 129); 80 safety_check_set_abort(NULL); 81 free(ptr); 82 83 expect_b_eq(fake_abort_called, true, "Redzone check didn't fire."); 84 fake_abort_called = false; 85 } 86 TEST_END 87 88 TEST_BEGIN(test_rallocx_overflow) { 89 test_skip_if(!config_prof); 90 test_skip_if(!config_opt_safety_checks); 91 92 safety_check_set_abort(&fake_abort); 93 /* Buffer overflow! */ 94 char* ptr = malloc(128); 95 buffer_overflow_write(ptr, 128); 96 ptr = rallocx(ptr, 129, 0); 97 safety_check_set_abort(NULL); 98 free(ptr); 99 100 expect_b_eq(fake_abort_called, true, "Redzone check didn't fire."); 101 fake_abort_called = false; 102 } 103 TEST_END 104 105 TEST_BEGIN(test_xallocx_overflow) { 106 test_skip_if(!config_prof); 107 test_skip_if(!config_opt_safety_checks); 108 109 safety_check_set_abort(&fake_abort); 110 /* Buffer overflow! */ 111 char* ptr = malloc(128); 112 buffer_overflow_write(ptr, 128); 113 size_t result = xallocx(ptr, 129, 0, 0); 114 expect_zu_eq(result, 128, ""); 115 free(ptr); 116 expect_b_eq(fake_abort_called, true, "Redzone check didn't fire."); 117 fake_abort_called = false; 118 safety_check_set_abort(NULL); 119 } 120 TEST_END 121 122 TEST_BEGIN(test_realloc_no_overflow) { 123 char* ptr = malloc(128); 124 ptr = realloc(ptr, 256); 125 ptr[128] = 0; 126 ptr[255] = 0; 127 free(ptr); 128 129 ptr = malloc(128); 130 ptr = realloc(ptr, 64); 131 ptr[63] = 0; 132 ptr[0] = 0; 133 free(ptr); 134 } 135 TEST_END 136 137 TEST_BEGIN(test_rallocx_no_overflow) { 138 char* ptr = malloc(128); 139 ptr = rallocx(ptr, 256, 0); 140 ptr[128] = 0; 141 ptr[255] = 0; 142 free(ptr); 143 144 ptr = malloc(128); 145 ptr = rallocx(ptr, 64, 0); 146 ptr[63] = 0; 147 ptr[0] = 0; 148 free(ptr); 149 } 150 TEST_END 151 152 int 153 main(void) { 154 return test( 155 test_malloc_free_overflow, 156 test_mallocx_dallocx_overflow, 157 test_malloc_sdallocx_overflow, 158 test_realloc_overflow, 159 test_rallocx_overflow, 160 test_xallocx_overflow, 161 test_realloc_no_overflow, 162 test_rallocx_no_overflow); 163 } 164