From eda9c2858f267961d7e88cb3f3e841f197372125 Mon Sep 17 00:00:00 2001 From: David Goldblatt Date: Wed, 13 May 2020 12:42:04 -0700 Subject: [PATCH] Edata: zero stack edatas before initializing. This avoids some UB. No compilers take advantage of it for now, but no sense in tempting fate. --- include/jemalloc/internal/edata.h | 7 +++++++ src/emap.c | 2 +- src/extent_dss.c | 2 +- test/unit/rtree.c | 6 +++--- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/include/jemalloc/internal/edata.h b/include/jemalloc/internal/edata.h index 3a9ebc81..ac8d647e 100644 --- a/include/jemalloc/internal/edata.h +++ b/include/jemalloc/internal/edata.h @@ -507,6 +507,13 @@ edata_is_head_set(edata_t *edata, bool is_head) { ((uint64_t)is_head << EDATA_BITS_IS_HEAD_SHIFT); } +/* + * Because this function is implemented as a sequence of bitfield modifications, + * even though each individual bit is properly initialized, we technically read + * uninitialized data within it. This is mostly fine, since most callers get + * their edatas from zeroing sources, but callers who make stack edata_ts need + * to manually zero them. + */ static inline void edata_init(edata_t *edata, unsigned arena_ind, void *addr, size_t size, bool slab, szind_t szind, size_t sn, extent_state_t state, bool zeroed, diff --git a/src/emap.c b/src/emap.c index 637d332b..ec1b4cdb 100644 --- a/src/emap.c +++ b/src/emap.c @@ -247,7 +247,7 @@ emap_split_prepare(tsdn_t *tsdn, emap_t *emap, emap_prepare_t *prepare, * and commit state, and head status. This is a fake edata_t, used to * facilitate a lookup. */ - edata_t lead; + edata_t lead = {0}; edata_init(&lead, 0U, edata_addr_get(edata), size_a, false, 0, 0, extent_state_active, false, false, false, EXTENT_NOT_HEAD); diff --git a/src/extent_dss.c b/src/extent_dss.c index 18b68952..17a08227 100644 --- a/src/extent_dss.c +++ b/src/extent_dss.c @@ -198,7 +198,7 @@ extent_alloc_dss(tsdn_t *tsdn, arena_t *arena, void *new_addr, size_t size, *commit = pages_decommit(ret, size); } if (*zero && *commit) { - edata_t edata; + edata_t edata = {0}; ehooks_t *ehooks = arena_get_ehooks( arena); diff --git a/test/unit/rtree.c b/test/unit/rtree.c index 28029665..63d6e37b 100644 --- a/test/unit/rtree.c +++ b/test/unit/rtree.c @@ -33,7 +33,7 @@ TEST_END #undef SEED TEST_BEGIN(test_rtree_extrema) { - edata_t edata_a, edata_b; + edata_t edata_a = {0}, edata_b = {0}; edata_init(&edata_a, INVALID_ARENA_IND, NULL, SC_LARGE_MINCLASS, false, sz_size2index(SC_LARGE_MINCLASS), 0, extent_state_active, false, false, false, EXTENT_NOT_HEAD); @@ -91,7 +91,7 @@ TEST_BEGIN(test_rtree_bits) { uintptr_t keys[] = {PAGE, PAGE + 1, PAGE + (((uintptr_t)1) << LG_PAGE) - 1}; - edata_t edata; + edata_t edata = {0}; edata_init(&edata, INVALID_ARENA_IND, NULL, 0, false, SC_NSIZES, 0, extent_state_active, false, false, false, EXTENT_NOT_HEAD); @@ -141,7 +141,7 @@ TEST_BEGIN(test_rtree_random) { rtree_ctx_t rtree_ctx; rtree_ctx_data_init(&rtree_ctx); - edata_t edata; + edata_t edata = {0}; edata_init(&edata, INVALID_ARENA_IND, NULL, 0, false, SC_NSIZES, 0, extent_state_active, false, false, false, EXTENT_NOT_HEAD);