diff --git a/include/jemalloc/internal/safety_check.h b/include/jemalloc/internal/safety_check.h index 2b4b2d0e..360e4aa9 100644 --- a/include/jemalloc/internal/safety_check.h +++ b/include/jemalloc/internal/safety_check.h @@ -11,11 +11,6 @@ void safety_check_fail_sized_dealloc( bool current_dealloc, const void *ptr, size_t true_size, size_t input_size); void safety_check_fail(const char *format, ...); -typedef void (*safety_check_abort_hook_t)(const char *message); - -/* Can set to NULL for a default. */ -void safety_check_set_abort(safety_check_abort_hook_t abort_fn); - #define REDZONE_SIZE ((size_t)32) #define REDZONE_FILL_VALUE 0xBC diff --git a/include/jemalloc/internal/test_hooks.h b/include/jemalloc/internal/test_hooks.h index 35f3a211..9df15383 100644 --- a/include/jemalloc/internal/test_hooks.h +++ b/include/jemalloc/internal/test_hooks.h @@ -5,6 +5,7 @@ extern JEMALLOC_EXPORT void (*test_hooks_arena_new_hook)(void); extern JEMALLOC_EXPORT void (*test_hooks_libc_hook)(void); +extern JEMALLOC_EXPORT void (*test_hooks_safety_check_abort)(const char *); #if defined(JEMALLOC_JET) || defined(JEMALLOC_UNIT_TEST) # define JEMALLOC_TEST_HOOK(fn, hook) \ diff --git a/src/ctl.c b/src/ctl.c index 132d0503..f522b3bd 100644 --- a/src/ctl.c +++ b/src/ctl.c @@ -372,7 +372,6 @@ CTL_PROTO(experimental_hooks_prof_dump) CTL_PROTO(experimental_hooks_prof_sample) CTL_PROTO(experimental_hooks_prof_sample_free) CTL_PROTO(experimental_hooks_thread_event) -CTL_PROTO(experimental_hooks_safety_check_abort) CTL_PROTO(experimental_utilization_query) CTL_PROTO(experimental_utilization_batch_query) CTL_PROTO(experimental_arenas_i_pactivep) @@ -910,7 +909,6 @@ static const ctl_named_node_t experimental_hooks_node[] = { {NAME("prof_dump"), CTL(experimental_hooks_prof_dump)}, {NAME("prof_sample"), CTL(experimental_hooks_prof_sample)}, {NAME("prof_sample_free"), CTL(experimental_hooks_prof_sample_free)}, - {NAME("safety_check_abort"), CTL(experimental_hooks_safety_check_abort)}, {NAME("thread_event"), CTL(experimental_hooks_thread_event)}, }; @@ -3676,27 +3674,6 @@ label_return: return ret; } -/* For integration test purpose only. No plan to move out of experimental. */ -static int -experimental_hooks_safety_check_abort_ctl(tsd_t *tsd, const size_t *mib, - size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { - int ret; - - WRITEONLY(); - if (newp != NULL) { - if (newlen != sizeof(safety_check_abort_hook_t)) { - ret = EINVAL; - goto label_return; - } - safety_check_abort_hook_t hook JEMALLOC_CC_SILENCE_INIT(NULL); - WRITE(hook, safety_check_abort_hook_t); - safety_check_set_abort(hook); - } - ret = 0; -label_return: - return ret; -} - /******************************************************************************/ CTL_RO_CGEN(config_stats, stats_allocated, ctl_stats->allocated, size_t) diff --git a/src/safety_check.c b/src/safety_check.c index d052718d..cdb6f79e 100644 --- a/src/safety_check.c +++ b/src/safety_check.c @@ -1,8 +1,6 @@ #include "jemalloc/internal/jemalloc_preamble.h" #include "jemalloc/internal/jemalloc_internal_includes.h" -static safety_check_abort_hook_t safety_check_abort; - void safety_check_fail_sized_dealloc(bool current_dealloc, const void *ptr, size_t true_size, size_t input_size) { @@ -19,23 +17,18 @@ safety_check_fail_sized_dealloc(bool current_dealloc, const void *ptr, true_size, input_size, ptr, src, suggest_debug_build); } -void -safety_check_set_abort(safety_check_abort_hook_t abort_fn) { - safety_check_abort = abort_fn; -} - /* * In addition to malloc_write, also embed hint msg in the abort function name * because there are cases only logging crash stack traces. */ static void safety_check_detected_heap_corruption___run_address_sanitizer_build_to_debug( - const char *buf) { - if (safety_check_abort == NULL) { + const char *buf) { + if (test_hooks_safety_check_abort == NULL) { malloc_write(buf); abort(); } else { - safety_check_abort(buf); + test_hooks_safety_check_abort(buf); } } diff --git a/src/test_hooks.c b/src/test_hooks.c index 40621199..0f4c4cf7 100644 --- a/src/test_hooks.c +++ b/src/test_hooks.c @@ -10,3 +10,6 @@ void (*test_hooks_arena_new_hook)(void) = NULL; JEMALLOC_EXPORT void (*test_hooks_libc_hook)(void) = NULL; + +JEMALLOC_EXPORT +void (*test_hooks_safety_check_abort)(const char *) = NULL; diff --git a/test/integration/cpp/infallible_new_true.cpp b/test/integration/cpp/infallible_new_true.cpp index 300bdd85..8c011b8f 100644 --- a/test/integration/cpp/infallible_new_true.cpp +++ b/test/integration/cpp/infallible_new_true.cpp @@ -3,10 +3,9 @@ #include "test/jemalloc_test.h" /* - * We can't test C++ in unit tests. In order to intercept abort, use a secret - * safety check abort hook in integration tests. + * We can't test C++ in unit tests. In order to intercept abort, use the + * internal test hook in integration tests. */ -typedef void (*abort_hook_t)(const char *message); bool fake_abort_called; void fake_abort(const char *message) { @@ -34,10 +33,7 @@ own_operator_new(void) { } TEST_BEGIN(test_failing_alloc) { - abort_hook_t abort_hook = &fake_abort; - expect_d_eq(mallctl("experimental.hooks.safety_check_abort", NULL, NULL, - (void *)&abort_hook, sizeof(abort_hook)), - 0, "Unexpected mallctl failure setting abort hook"); + test_hooks_safety_check_abort = &fake_abort; /* * Not owning operator new is only expected to happen on MinGW which @@ -57,6 +53,7 @@ TEST_BEGIN(test_failing_alloc) { } expect_ptr_null(ptr, "Allocation should have failed"); expect_b_eq(fake_abort_called, true, "Abort hook not invoked"); + test_hooks_safety_check_abort = NULL; } TEST_END diff --git a/test/src/test.c b/test/src/test.c index c048a541..443a9ac3 100644 --- a/test/src/test.c +++ b/test/src/test.c @@ -150,6 +150,7 @@ p_test_impl(bool do_malloc_init, bool do_reentrant, test_t *t, va_list ap) { /* Non-reentrant run. */ reentrancy = non_reentrant; test_hooks_arena_new_hook = test_hooks_libc_hook = NULL; + test_hooks_safety_check_abort = NULL; t(); if (test_status > ret) { ret = test_status; @@ -158,6 +159,7 @@ p_test_impl(bool do_malloc_init, bool do_reentrant, test_t *t, va_list ap) { if (do_reentrant) { reentrancy = libc_reentrant; test_hooks_arena_new_hook = NULL; + test_hooks_safety_check_abort = NULL; test_hooks_libc_hook = &libc_reentrancy_hook; t(); if (test_status > ret) { @@ -166,6 +168,7 @@ p_test_impl(bool do_malloc_init, bool do_reentrant, test_t *t, va_list ap) { reentrancy = arena_new_reentrant; test_hooks_libc_hook = NULL; + test_hooks_safety_check_abort = NULL; test_hooks_arena_new_hook = &arena_new_reentrancy_hook; t(); if (test_status > ret) { diff --git a/test/unit/double_free.c b/test/unit/double_free.c index 4bd6ab73..07f28dfe 100644 --- a/test/unit/double_free.c +++ b/test/unit/double_free.c @@ -12,14 +12,14 @@ fake_abort(const char *message) { static void test_double_free_pre(void) { - safety_check_set_abort(&fake_abort); + test_hooks_safety_check_abort = &fake_abort; fake_abort_called = false; } static void test_double_free_post(void) { expect_b_eq(fake_abort_called, true, "Double-free check didn't fire."); - safety_check_set_abort(NULL); + test_hooks_safety_check_abort = NULL; } static bool diff --git a/test/unit/safety_check.c b/test/unit/safety_check.c index 558797c0..24dd3fd8 100644 --- a/test/unit/safety_check.c +++ b/test/unit/safety_check.c @@ -25,12 +25,12 @@ TEST_BEGIN(test_malloc_free_overflow) { test_skip_if(!config_prof); test_skip_if(!config_opt_safety_checks); - safety_check_set_abort(&fake_abort); + test_hooks_safety_check_abort = &fake_abort; /* Buffer overflow! */ char *ptr = malloc(128); buffer_overflow_write(ptr, 128); free(ptr); - safety_check_set_abort(NULL); + test_hooks_safety_check_abort = NULL; expect_b_eq(fake_abort_called, true, "Redzone check didn't fire."); fake_abort_called = false; @@ -41,12 +41,12 @@ TEST_BEGIN(test_mallocx_dallocx_overflow) { test_skip_if(!config_prof); test_skip_if(!config_opt_safety_checks); - safety_check_set_abort(&fake_abort); + test_hooks_safety_check_abort = &fake_abort; /* Buffer overflow! */ char *ptr = mallocx(128, 0); buffer_overflow_write(ptr, 128); dallocx(ptr, 0); - safety_check_set_abort(NULL); + test_hooks_safety_check_abort = NULL; expect_b_eq(fake_abort_called, true, "Redzone check didn't fire."); fake_abort_called = false; @@ -57,12 +57,12 @@ TEST_BEGIN(test_malloc_sdallocx_overflow) { test_skip_if(!config_prof); test_skip_if(!config_opt_safety_checks); - safety_check_set_abort(&fake_abort); + test_hooks_safety_check_abort = &fake_abort; /* Buffer overflow! */ char *ptr = malloc(128); buffer_overflow_write(ptr, 128); sdallocx(ptr, 128, 0); - safety_check_set_abort(NULL); + test_hooks_safety_check_abort = NULL; expect_b_eq(fake_abort_called, true, "Redzone check didn't fire."); fake_abort_called = false; @@ -73,12 +73,12 @@ TEST_BEGIN(test_realloc_overflow) { test_skip_if(!config_prof); test_skip_if(!config_opt_safety_checks); - safety_check_set_abort(&fake_abort); + test_hooks_safety_check_abort = &fake_abort; /* Buffer overflow! */ char *ptr = malloc(128); buffer_overflow_write(ptr, 128); ptr = realloc(ptr, 129); - safety_check_set_abort(NULL); + test_hooks_safety_check_abort = NULL; free(ptr); expect_b_eq(fake_abort_called, true, "Redzone check didn't fire."); @@ -90,12 +90,12 @@ TEST_BEGIN(test_rallocx_overflow) { test_skip_if(!config_prof); test_skip_if(!config_opt_safety_checks); - safety_check_set_abort(&fake_abort); + test_hooks_safety_check_abort = &fake_abort; /* Buffer overflow! */ char *ptr = malloc(128); buffer_overflow_write(ptr, 128); ptr = rallocx(ptr, 129, 0); - safety_check_set_abort(NULL); + test_hooks_safety_check_abort = NULL; free(ptr); expect_b_eq(fake_abort_called, true, "Redzone check didn't fire."); @@ -107,7 +107,7 @@ TEST_BEGIN(test_xallocx_overflow) { test_skip_if(!config_prof); test_skip_if(!config_opt_safety_checks); - safety_check_set_abort(&fake_abort); + test_hooks_safety_check_abort = &fake_abort; /* Buffer overflow! */ char *ptr = malloc(128); buffer_overflow_write(ptr, 128); @@ -116,7 +116,7 @@ TEST_BEGIN(test_xallocx_overflow) { free(ptr); expect_b_eq(fake_abort_called, true, "Redzone check didn't fire."); fake_abort_called = false; - safety_check_set_abort(NULL); + test_hooks_safety_check_abort = NULL; } TEST_END diff --git a/test/unit/size_check.c b/test/unit/size_check.c index a31578bf..2fe3733b 100644 --- a/test/unit/size_check.c +++ b/test/unit/size_check.c @@ -17,7 +17,7 @@ fake_abort(const char *message) { static void * test_invalid_size_pre(size_t sz) { - safety_check_set_abort(&fake_abort); + test_hooks_safety_check_abort = &fake_abort; fake_abort_called = false; void *ptr = malloc(sz); @@ -29,7 +29,7 @@ test_invalid_size_pre(size_t sz) { static void test_invalid_size_post(void) { expect_true(fake_abort_called, "Safety check didn't fire"); - safety_check_set_abort(NULL); + test_hooks_safety_check_abort = NULL; } TEST_BEGIN(test_invalid_size_sdallocx) { diff --git a/test/unit/uaf.c b/test/unit/uaf.c index 25399ed0..b9d98803 100644 --- a/test/unit/uaf.c +++ b/test/unit/uaf.c @@ -19,7 +19,7 @@ fake_abort(const char *message) { static void test_write_after_free_pre(void) { - safety_check_set_abort(&fake_abort); + test_hooks_safety_check_abort = &fake_abort; fake_abort_called = false; } @@ -28,7 +28,7 @@ test_write_after_free_post(void) { assert_d_eq(mallctl("thread.tcache.flush", NULL, NULL, NULL, 0), 0, "Unexpected tcache flush failure"); expect_true(fake_abort_called, "Use-after-free check didn't fire."); - safety_check_set_abort(NULL); + test_hooks_safety_check_abort = NULL; } static bool diff --git a/test/unit/zero_realloc_abort.c b/test/unit/zero_realloc_abort.c index 1d8bf9c3..03cbe16e 100644 --- a/test/unit/zero_realloc_abort.c +++ b/test/unit/zero_realloc_abort.c @@ -12,7 +12,7 @@ set_abort_called(const char *message) { TEST_BEGIN(test_realloc_abort) { abort_called = false; - safety_check_set_abort(&set_abort_called); + test_hooks_safety_check_abort = &set_abort_called; void *ptr = mallocx(42, 0); expect_ptr_not_null(ptr, "Unexpected mallocx error"); ptr = realloc(ptr, 0);