Home | History | Annotate | Line # | Download | only in unit
      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