mirror of
https://github.com/jemalloc/jemalloc.git
synced 2026-07-24 05:33:06 +00:00
Remove safety check abort mallctl
This commit is contained in:
@@ -11,11 +11,6 @@ void safety_check_fail_sized_dealloc(
|
|||||||
bool current_dealloc, const void *ptr, size_t true_size, size_t input_size);
|
bool current_dealloc, const void *ptr, size_t true_size, size_t input_size);
|
||||||
void safety_check_fail(const char *format, ...);
|
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_SIZE ((size_t)32)
|
||||||
#define REDZONE_FILL_VALUE 0xBC
|
#define REDZONE_FILL_VALUE 0xBC
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
extern JEMALLOC_EXPORT void (*test_hooks_arena_new_hook)(void);
|
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_libc_hook)(void);
|
||||||
|
extern JEMALLOC_EXPORT void (*test_hooks_safety_check_abort)(const char *);
|
||||||
|
|
||||||
#if defined(JEMALLOC_JET) || defined(JEMALLOC_UNIT_TEST)
|
#if defined(JEMALLOC_JET) || defined(JEMALLOC_UNIT_TEST)
|
||||||
# define JEMALLOC_TEST_HOOK(fn, hook) \
|
# define JEMALLOC_TEST_HOOK(fn, hook) \
|
||||||
|
|||||||
23
src/ctl.c
23
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)
|
||||||
CTL_PROTO(experimental_hooks_prof_sample_free)
|
CTL_PROTO(experimental_hooks_prof_sample_free)
|
||||||
CTL_PROTO(experimental_hooks_thread_event)
|
CTL_PROTO(experimental_hooks_thread_event)
|
||||||
CTL_PROTO(experimental_hooks_safety_check_abort)
|
|
||||||
CTL_PROTO(experimental_utilization_query)
|
CTL_PROTO(experimental_utilization_query)
|
||||||
CTL_PROTO(experimental_utilization_batch_query)
|
CTL_PROTO(experimental_utilization_batch_query)
|
||||||
CTL_PROTO(experimental_arenas_i_pactivep)
|
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_dump"), CTL(experimental_hooks_prof_dump)},
|
||||||
{NAME("prof_sample"), CTL(experimental_hooks_prof_sample)},
|
{NAME("prof_sample"), CTL(experimental_hooks_prof_sample)},
|
||||||
{NAME("prof_sample_free"), CTL(experimental_hooks_prof_sample_free)},
|
{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)},
|
{NAME("thread_event"), CTL(experimental_hooks_thread_event)},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -3729,27 +3727,6 @@ label_return:
|
|||||||
return ret;
|
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)
|
CTL_RO_CGEN(config_stats, stats_allocated, ctl_stats->allocated, size_t)
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
#include "jemalloc/internal/jemalloc_preamble.h"
|
#include "jemalloc/internal/jemalloc_preamble.h"
|
||||||
#include "jemalloc/internal/jemalloc_internal_includes.h"
|
#include "jemalloc/internal/jemalloc_internal_includes.h"
|
||||||
|
|
||||||
static safety_check_abort_hook_t safety_check_abort;
|
|
||||||
|
|
||||||
void
|
void
|
||||||
safety_check_fail_sized_dealloc(bool current_dealloc, const void *ptr,
|
safety_check_fail_sized_dealloc(bool current_dealloc, const void *ptr,
|
||||||
size_t true_size, size_t input_size) {
|
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);
|
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
|
* In addition to malloc_write, also embed hint msg in the abort function name
|
||||||
* because there are cases only logging crash stack traces.
|
* because there are cases only logging crash stack traces.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
safety_check_detected_heap_corruption___run_address_sanitizer_build_to_debug(
|
safety_check_detected_heap_corruption___run_address_sanitizer_build_to_debug(
|
||||||
const char *buf) {
|
const char *buf) {
|
||||||
if (safety_check_abort == NULL) {
|
if (test_hooks_safety_check_abort == NULL) {
|
||||||
malloc_write(buf);
|
malloc_write(buf);
|
||||||
abort();
|
abort();
|
||||||
} else {
|
} else {
|
||||||
safety_check_abort(buf);
|
test_hooks_safety_check_abort(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,3 +10,6 @@ void (*test_hooks_arena_new_hook)(void) = NULL;
|
|||||||
|
|
||||||
JEMALLOC_EXPORT
|
JEMALLOC_EXPORT
|
||||||
void (*test_hooks_libc_hook)(void) = NULL;
|
void (*test_hooks_libc_hook)(void) = NULL;
|
||||||
|
|
||||||
|
JEMALLOC_EXPORT
|
||||||
|
void (*test_hooks_safety_check_abort)(const char *) = NULL;
|
||||||
|
|||||||
@@ -3,10 +3,9 @@
|
|||||||
#include "test/jemalloc_test.h"
|
#include "test/jemalloc_test.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We can't test C++ in unit tests. In order to intercept abort, use a secret
|
* We can't test C++ in unit tests. In order to intercept abort, use the
|
||||||
* safety check abort hook in integration tests.
|
* internal test hook in integration tests.
|
||||||
*/
|
*/
|
||||||
typedef void (*abort_hook_t)(const char *message);
|
|
||||||
bool fake_abort_called;
|
bool fake_abort_called;
|
||||||
void
|
void
|
||||||
fake_abort(const char *message) {
|
fake_abort(const char *message) {
|
||||||
@@ -34,10 +33,7 @@ own_operator_new(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_BEGIN(test_failing_alloc) {
|
TEST_BEGIN(test_failing_alloc) {
|
||||||
abort_hook_t abort_hook = &fake_abort;
|
test_hooks_safety_check_abort = &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");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Not owning operator new is only expected to happen on MinGW which
|
* 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_ptr_null(ptr, "Allocation should have failed");
|
||||||
expect_b_eq(fake_abort_called, true, "Abort hook not invoked");
|
expect_b_eq(fake_abort_called, true, "Abort hook not invoked");
|
||||||
|
test_hooks_safety_check_abort = NULL;
|
||||||
}
|
}
|
||||||
TEST_END
|
TEST_END
|
||||||
|
|
||||||
|
|||||||
@@ -150,6 +150,7 @@ p_test_impl(bool do_malloc_init, bool do_reentrant, test_t *t, va_list ap) {
|
|||||||
/* Non-reentrant run. */
|
/* Non-reentrant run. */
|
||||||
reentrancy = non_reentrant;
|
reentrancy = non_reentrant;
|
||||||
test_hooks_arena_new_hook = test_hooks_libc_hook = NULL;
|
test_hooks_arena_new_hook = test_hooks_libc_hook = NULL;
|
||||||
|
test_hooks_safety_check_abort = NULL;
|
||||||
t();
|
t();
|
||||||
if (test_status > ret) {
|
if (test_status > ret) {
|
||||||
ret = test_status;
|
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) {
|
if (do_reentrant) {
|
||||||
reentrancy = libc_reentrant;
|
reentrancy = libc_reentrant;
|
||||||
test_hooks_arena_new_hook = NULL;
|
test_hooks_arena_new_hook = NULL;
|
||||||
|
test_hooks_safety_check_abort = NULL;
|
||||||
test_hooks_libc_hook = &libc_reentrancy_hook;
|
test_hooks_libc_hook = &libc_reentrancy_hook;
|
||||||
t();
|
t();
|
||||||
if (test_status > ret) {
|
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;
|
reentrancy = arena_new_reentrant;
|
||||||
test_hooks_libc_hook = NULL;
|
test_hooks_libc_hook = NULL;
|
||||||
|
test_hooks_safety_check_abort = NULL;
|
||||||
test_hooks_arena_new_hook = &arena_new_reentrancy_hook;
|
test_hooks_arena_new_hook = &arena_new_reentrancy_hook;
|
||||||
t();
|
t();
|
||||||
if (test_status > ret) {
|
if (test_status > ret) {
|
||||||
|
|||||||
@@ -12,14 +12,14 @@ fake_abort(const char *message) {
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
test_double_free_pre(void) {
|
test_double_free_pre(void) {
|
||||||
safety_check_set_abort(&fake_abort);
|
test_hooks_safety_check_abort = &fake_abort;
|
||||||
fake_abort_called = false;
|
fake_abort_called = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_double_free_post(void) {
|
test_double_free_post(void) {
|
||||||
expect_b_eq(fake_abort_called, true, "Double-free check didn't fire.");
|
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
|
static bool
|
||||||
|
|||||||
@@ -25,12 +25,12 @@ TEST_BEGIN(test_malloc_free_overflow) {
|
|||||||
test_skip_if(!config_prof);
|
test_skip_if(!config_prof);
|
||||||
test_skip_if(!config_opt_safety_checks);
|
test_skip_if(!config_opt_safety_checks);
|
||||||
|
|
||||||
safety_check_set_abort(&fake_abort);
|
test_hooks_safety_check_abort = &fake_abort;
|
||||||
/* Buffer overflow! */
|
/* Buffer overflow! */
|
||||||
char *ptr = malloc(128);
|
char *ptr = malloc(128);
|
||||||
buffer_overflow_write(ptr, 128);
|
buffer_overflow_write(ptr, 128);
|
||||||
free(ptr);
|
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.");
|
expect_b_eq(fake_abort_called, true, "Redzone check didn't fire.");
|
||||||
fake_abort_called = false;
|
fake_abort_called = false;
|
||||||
@@ -41,12 +41,12 @@ TEST_BEGIN(test_mallocx_dallocx_overflow) {
|
|||||||
test_skip_if(!config_prof);
|
test_skip_if(!config_prof);
|
||||||
test_skip_if(!config_opt_safety_checks);
|
test_skip_if(!config_opt_safety_checks);
|
||||||
|
|
||||||
safety_check_set_abort(&fake_abort);
|
test_hooks_safety_check_abort = &fake_abort;
|
||||||
/* Buffer overflow! */
|
/* Buffer overflow! */
|
||||||
char *ptr = mallocx(128, 0);
|
char *ptr = mallocx(128, 0);
|
||||||
buffer_overflow_write(ptr, 128);
|
buffer_overflow_write(ptr, 128);
|
||||||
dallocx(ptr, 0);
|
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.");
|
expect_b_eq(fake_abort_called, true, "Redzone check didn't fire.");
|
||||||
fake_abort_called = false;
|
fake_abort_called = false;
|
||||||
@@ -57,12 +57,12 @@ TEST_BEGIN(test_malloc_sdallocx_overflow) {
|
|||||||
test_skip_if(!config_prof);
|
test_skip_if(!config_prof);
|
||||||
test_skip_if(!config_opt_safety_checks);
|
test_skip_if(!config_opt_safety_checks);
|
||||||
|
|
||||||
safety_check_set_abort(&fake_abort);
|
test_hooks_safety_check_abort = &fake_abort;
|
||||||
/* Buffer overflow! */
|
/* Buffer overflow! */
|
||||||
char *ptr = malloc(128);
|
char *ptr = malloc(128);
|
||||||
buffer_overflow_write(ptr, 128);
|
buffer_overflow_write(ptr, 128);
|
||||||
sdallocx(ptr, 128, 0);
|
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.");
|
expect_b_eq(fake_abort_called, true, "Redzone check didn't fire.");
|
||||||
fake_abort_called = false;
|
fake_abort_called = false;
|
||||||
@@ -73,12 +73,12 @@ TEST_BEGIN(test_realloc_overflow) {
|
|||||||
test_skip_if(!config_prof);
|
test_skip_if(!config_prof);
|
||||||
test_skip_if(!config_opt_safety_checks);
|
test_skip_if(!config_opt_safety_checks);
|
||||||
|
|
||||||
safety_check_set_abort(&fake_abort);
|
test_hooks_safety_check_abort = &fake_abort;
|
||||||
/* Buffer overflow! */
|
/* Buffer overflow! */
|
||||||
char *ptr = malloc(128);
|
char *ptr = malloc(128);
|
||||||
buffer_overflow_write(ptr, 128);
|
buffer_overflow_write(ptr, 128);
|
||||||
ptr = realloc(ptr, 129);
|
ptr = realloc(ptr, 129);
|
||||||
safety_check_set_abort(NULL);
|
test_hooks_safety_check_abort = NULL;
|
||||||
free(ptr);
|
free(ptr);
|
||||||
|
|
||||||
expect_b_eq(fake_abort_called, true, "Redzone check didn't fire.");
|
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_prof);
|
||||||
test_skip_if(!config_opt_safety_checks);
|
test_skip_if(!config_opt_safety_checks);
|
||||||
|
|
||||||
safety_check_set_abort(&fake_abort);
|
test_hooks_safety_check_abort = &fake_abort;
|
||||||
/* Buffer overflow! */
|
/* Buffer overflow! */
|
||||||
char *ptr = malloc(128);
|
char *ptr = malloc(128);
|
||||||
buffer_overflow_write(ptr, 128);
|
buffer_overflow_write(ptr, 128);
|
||||||
ptr = rallocx(ptr, 129, 0);
|
ptr = rallocx(ptr, 129, 0);
|
||||||
safety_check_set_abort(NULL);
|
test_hooks_safety_check_abort = NULL;
|
||||||
free(ptr);
|
free(ptr);
|
||||||
|
|
||||||
expect_b_eq(fake_abort_called, true, "Redzone check didn't fire.");
|
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_prof);
|
||||||
test_skip_if(!config_opt_safety_checks);
|
test_skip_if(!config_opt_safety_checks);
|
||||||
|
|
||||||
safety_check_set_abort(&fake_abort);
|
test_hooks_safety_check_abort = &fake_abort;
|
||||||
/* Buffer overflow! */
|
/* Buffer overflow! */
|
||||||
char *ptr = malloc(128);
|
char *ptr = malloc(128);
|
||||||
buffer_overflow_write(ptr, 128);
|
buffer_overflow_write(ptr, 128);
|
||||||
@@ -116,7 +116,7 @@ TEST_BEGIN(test_xallocx_overflow) {
|
|||||||
free(ptr);
|
free(ptr);
|
||||||
expect_b_eq(fake_abort_called, true, "Redzone check didn't fire.");
|
expect_b_eq(fake_abort_called, true, "Redzone check didn't fire.");
|
||||||
fake_abort_called = false;
|
fake_abort_called = false;
|
||||||
safety_check_set_abort(NULL);
|
test_hooks_safety_check_abort = NULL;
|
||||||
}
|
}
|
||||||
TEST_END
|
TEST_END
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ fake_abort(const char *message) {
|
|||||||
|
|
||||||
static void *
|
static void *
|
||||||
test_invalid_size_pre(size_t sz) {
|
test_invalid_size_pre(size_t sz) {
|
||||||
safety_check_set_abort(&fake_abort);
|
test_hooks_safety_check_abort = &fake_abort;
|
||||||
|
|
||||||
fake_abort_called = false;
|
fake_abort_called = false;
|
||||||
void *ptr = malloc(sz);
|
void *ptr = malloc(sz);
|
||||||
@@ -29,7 +29,7 @@ test_invalid_size_pre(size_t sz) {
|
|||||||
static void
|
static void
|
||||||
test_invalid_size_post(void) {
|
test_invalid_size_post(void) {
|
||||||
expect_true(fake_abort_called, "Safety check didn't fire");
|
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) {
|
TEST_BEGIN(test_invalid_size_sdallocx) {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ fake_abort(const char *message) {
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
test_write_after_free_pre(void) {
|
test_write_after_free_pre(void) {
|
||||||
safety_check_set_abort(&fake_abort);
|
test_hooks_safety_check_abort = &fake_abort;
|
||||||
fake_abort_called = false;
|
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,
|
assert_d_eq(mallctl("thread.tcache.flush", NULL, NULL, NULL, 0), 0,
|
||||||
"Unexpected tcache flush failure");
|
"Unexpected tcache flush failure");
|
||||||
expect_true(fake_abort_called, "Use-after-free check didn't fire.");
|
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
|
static bool
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ set_abort_called(const char *message) {
|
|||||||
|
|
||||||
TEST_BEGIN(test_realloc_abort) {
|
TEST_BEGIN(test_realloc_abort) {
|
||||||
abort_called = false;
|
abort_called = false;
|
||||||
safety_check_set_abort(&set_abort_called);
|
test_hooks_safety_check_abort = &set_abort_called;
|
||||||
void *ptr = mallocx(42, 0);
|
void *ptr = mallocx(42, 0);
|
||||||
expect_ptr_not_null(ptr, "Unexpected mallocx error");
|
expect_ptr_not_null(ptr, "Unexpected mallocx error");
|
||||||
ptr = realloc(ptr, 0);
|
ptr = realloc(ptr, 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user