From e297272377295d7de83ee7d37fa9866dff5dba21 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Vladim=C3=ADr=20=C4=8Cun=C3=A1t?= Date: Fri, 20 Mar 2020 17:28:54 +0100 Subject: [PATCH] lib/generic/array: fix a strict aliasing problem The issue here is that `char *` is not allowed to alias with `anyType *`. With gcc-10 in Fedora this now started to cause real problems and loading stats module segfaulted. Actually I can't see in standard (C11 6.5 par.7) that using `void *` is guaranteed to be correct, but at least it seems fine with gcc, and e.g. some standard functions like posix_memalign() use it in the same "dangerous" way. --- NEWS | 1 + lib/generic/array.h | 4 ++-- lib/generic/test_array.c | 4 ++-- lib/utils.c | 2 +- lib/utils.h | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index a343d8076..d014a03a2 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,7 @@ Bugfixes -------- - cache: missing filesystem support for pre-allocation is no longer fatal (#549) - lua: policy.rpz() no longer watches the file when watch is set to false (!954) +- fix a strict aliasing problem that might've lead to "miscompilation" (!962) Knot Resolver 5.0.1 (2020-02-05) diff --git a/lib/generic/array.h b/lib/generic/array.h index e29a3fbe2..b20a802a6 100644 --- a/lib/generic/array.h +++ b/lib/generic/array.h @@ -64,7 +64,7 @@ static inline size_t array_next_count(size_t want) } /** @internal Incremental memory reservation */ -static inline int array_std_reserve(void *baton, char **mem, size_t elm_size, size_t want, size_t *have) +static inline int array_std_reserve(void *baton, void **mem, size_t elm_size, size_t want, size_t *have) { if (*have >= want) { return 0; @@ -110,7 +110,7 @@ static inline void array_std_free(void *baton, void *p) * Mempool usage: pass kr_memreserve and a knot_mm_t* . * @return 0 if success, <0 on failure */ #define array_reserve_mm(array, n, reserve, baton) \ - (reserve)((baton), (char **) &(array).at, sizeof((array).at[0]), (n), &(array).cap) + (reserve)((baton), (void **) &(array).at, sizeof((array).at[0]), (n), &(array).cap) /** * Push value at the end of the array, resize it if necessary. diff --git a/lib/generic/test_array.c b/lib/generic/test_array.c index 1535967c4..98c595844 100644 --- a/lib/generic/test_array.c +++ b/lib/generic/test_array.c @@ -46,7 +46,7 @@ static void test_array(void **state) } /** Reservation through tracked memory allocator. */ -static int test_reserve(void *baton, char **mem, size_t elm_size, size_t want, size_t *have) +static int test_reserve(void *baton, void **mem, size_t elm_size, size_t want, size_t *have) { if (want > *have) { void *new_mem = mm_alloc(baton, elm_size * want); @@ -62,7 +62,7 @@ static int test_reserve(void *baton, char **mem, size_t elm_size, size_t want, s } /** Reservation through fake memory allocator. */ -static int fake_reserve(void *baton, char **mem, size_t elm_size, size_t want, size_t *have) +static int fake_reserve(void *baton, void **mem, size_t elm_size, size_t want, size_t *have) { return -1; } diff --git a/lib/utils.c b/lib/utils.c index 36d2feee0..8c7cd89df 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -213,7 +213,7 @@ char* kr_strcatdup(unsigned n, ...) return result; } -int kr_memreserve(void *baton, char **mem, size_t elm_size, size_t want, size_t *have) +int kr_memreserve(void *baton, void **mem, size_t elm_size, size_t want, size_t *have) { if (*have >= want) { return 0; diff --git a/lib/utils.h b/lib/utils.h index 322ba879d..1a5e3aafd 100644 --- a/lib/utils.h +++ b/lib/utils.h @@ -261,7 +261,7 @@ static inline bool kr_rand_coin(unsigned int nomin, unsigned int denomin) /** Memory reservation routine for knot_mm_t */ KR_EXPORT -int kr_memreserve(void *baton, char **mem, size_t elm_size, size_t want, size_t *have); +int kr_memreserve(void *baton, void **mem, size_t elm_size, size_t want, size_t *have); /** @internal Fast packet reset. */ KR_EXPORT -- 2.47.3