Report the offending pointer on sized dealloc bug detection.

This commit is contained in:
Qi Wang
2021-02-05 16:47:09 -08:00
committed by Qi Wang
parent edbfe6912c
commit f3b2668b32
5 changed files with 31 additions and 14 deletions

View File

@@ -2751,7 +2751,7 @@ maybe_check_alloc_ctx(tsd_t *tsd, void *ptr, emap_alloc_ctx_t *alloc_ctx) {
&dbg_ctx);
if (alloc_ctx->szind != dbg_ctx.szind) {
safety_check_fail_sized_dealloc(
/* current_dealloc */ true);
/* current_dealloc */ true, ptr);
return true;
}
if (alloc_ctx->slab != dbg_ctx.slab) {
@@ -2801,7 +2801,8 @@ isfree(tsd_t *tsd, void *ptr, size_t usize, tcache_t *tcache, bool slow_path) {
if (config_opt_safety_checks) {
/* Small alloc may have !slab (sampled). */
if (alloc_ctx.szind != sz_size2index(usize)) {
safety_check_fail_sized_dealloc(true);
safety_check_fail_sized_dealloc(true,
ptr);
}
}
} else {

View File

@@ -3,14 +3,14 @@
static void (*safety_check_abort)(const char *message);
void safety_check_fail_sized_dealloc(bool current_dealloc) {
void safety_check_fail_sized_dealloc(bool current_dealloc, const void *ptr) {
char *src = current_dealloc ? "the current pointer being freed" :
"in thread cache, possibly from previous deallocations";
safety_check_fail("<jemalloc>: size mismatch detected, likely caused by"
" application sized deallocation bugs (source: %s). Suggest building"
"with --enable-debug or address sanitizer for debugging. Abort.\n",
src);
" application sized deallocation bugs (source address: %p, %s). "
"Suggest building with --enable-debug or address sanitizer for "
"debugging. Abort.\n", ptr, src);
}
void safety_check_set_abort(void (*abort_fn)(const char *)) {

View File

@@ -250,6 +250,20 @@ tcache_bin_flush_metadata_visitor(void *szind_sum_ctx,
util_prefetch_write_range(alloc_ctx->edata, sizeof(edata_t));
}
JEMALLOC_NOINLINE static void
tcache_bin_flush_size_check_fail(cache_bin_ptr_array_t *arr, szind_t szind,
size_t nptrs, emap_batch_lookup_result_t *edatas) {
bool found_mismatch = false;
for (size_t i = 0; i < nptrs; i++) {
if (edata_szind_get(edatas[i].edata) != szind) {
found_mismatch = true;
safety_check_fail_sized_dealloc(false,
tcache_bin_flush_ptr_getter(arr, i));
}
}
assert(found_mismatch);
}
static void
tcache_bin_flush_edatas_lookup(tsd_t *tsd, cache_bin_ptr_array_t *arr,
szind_t binind, size_t nflush, emap_batch_lookup_result_t *edatas) {
@@ -264,8 +278,8 @@ tcache_bin_flush_edatas_lookup(tsd_t *tsd, cache_bin_ptr_array_t *arr,
&tcache_bin_flush_ptr_getter, (void *)arr,
&tcache_bin_flush_metadata_visitor, (void *)&szind_sum,
edatas);
if (config_opt_safety_checks && szind_sum != 0) {
safety_check_fail_sized_dealloc(false);
if (config_opt_safety_checks && unlikely(szind_sum != 0)) {
tcache_bin_flush_size_check_fail(arr, binind, nflush, edatas);
}
}
@@ -435,7 +449,8 @@ tcache_bin_flush_impl(tsd_t *tsd, tcache_t *tcache, cache_bin_t *cache_bin,
dalloc_count++;
}
} else {
if (large_dalloc_safety_checks(edata, binind)) {
if (large_dalloc_safety_checks(edata, ptr,
binind)) {
/* See the comment in isfree. */
continue;
}