]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib/generic/array: fix a strict aliasing problem
authorVladimír Čunát <vladimir.cunat@nic.cz>
Fri, 20 Mar 2020 16:28:54 +0000 (17:28 +0100)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Fri, 20 Mar 2020 17:09:40 +0000 (18:09 +0100)
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
lib/generic/array.h
lib/generic/test_array.c
lib/utils.c
lib/utils.h

diff --git a/NEWS b/NEWS
index a343d807600c95be816406287163012968765116..d014a03a25af752c071ae62d807efc3415fd2570 100644 (file)
--- 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)
index e29a3fbe2fa9c07fa1675a3bf7386a2a7aa6f2b4..b20a802a6e7a2f91bbb078e00dcd9b06b9110ee3 100644 (file)
@@ -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.
index 1535967c4bb8e8553339d9b7de6ebd8b3ff82b9c..98c5958449a45d84e82e2a11fdc0382829844579 100644 (file)
@@ -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;
 }
index 36d2feee066b2ff584801b9d9b27b6314dc34759..8c7cd89dfac2e79992fca4ce39c17afb06d9dbbe 100644 (file)
@@ -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;
index 322ba879db108c801d5ec9fbbc79c9837a3300de..1a5e3aafdcc143f074684c0ce0517b72c0c94085 100644 (file)
@@ -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