]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Workaround AddressSanitizer overzealous check
authorOndřej Surý <ondrej@isc.org>
Thu, 22 Jun 2023 10:25:45 +0000 (12:25 +0200)
committerOndřej Surý <ondrej@isc.org>
Thu, 27 Jul 2023 13:21:39 +0000 (15:21 +0200)
The cds_lfht_for_each_entry and cds_lfht_for_each_entry_duplicate macros
had a code that operated on the NULL pointer, at the end of the list it
was calling caa_container_of() on the NULL pointer in the init-clause
and iteration-expression, but the result wasn't actually used anywhere
because the cond-expression in the for loop has prevented executing
loop-statement.  This made AddressSanitizer notice the invalid operation
and rightfully complain.

This was reported to the upstream and fixed there.  Pull the upstream
fix into our <isc/urcu.h> header, so our CI checks pass.

lib/isc/include/isc/urcu.h

index c4dfe6a180b03abbf57bcdc1d099a7db5aaeb7b7..d1acf991219654231c49e4117136f42fdec75f88 100644 (file)
 #define rcu_dereference(ptr) isc_qsbr_rcu_dereference(ptr)
 
 #endif /* RCU_QSBR */
+
+/* clang-format off */
+/*
+ * Following definitions were copied from liburcu development branch to help
+ * with AddressSanitizer complaining about calling caa_container_of on NULL.
+ */
+
+#if !defined(caa_container_of_check_null)
+/*
+ * caa_container_of_check_null - Get the address of an object containing a field.
+ *
+ * @ptr: pointer to the field.
+ * @type: type of the object.
+ * @member: name of the field within the object.
+ *
+ * Return the address of the object containing the field. Return NULL if
+ * @ptr is NULL.
+ */
+#define caa_container_of_check_null(ptr, type, member)                 \
+       __extension__                                                   \
+       ({                                                              \
+               const __typeof__(((type *) NULL)->member) * __ptr = (ptr); \
+               (__ptr) ? (type *)((char *)__ptr - offsetof(type, member)) : NULL; \
+       })
+
+#define cds_lfht_entry(ptr, type, member)                              \
+       caa_container_of_check_null(ptr, type, member)
+
+#undef cds_lfht_for_each_entry
+#define cds_lfht_for_each_entry(ht, iter, pos, member)                 \
+       for (cds_lfht_first(ht, iter),                                  \
+                       pos = cds_lfht_entry(cds_lfht_iter_get_node(iter), \
+                               __typeof__(*(pos)), member);            \
+               pos != NULL;                                            \
+               cds_lfht_next(ht, iter),                                \
+                       pos = cds_lfht_entry(cds_lfht_iter_get_node(iter), \
+                               __typeof__(*(pos)), member))
+
+#undef cds_lfht_for_each_entry_duplicate
+#define cds_lfht_for_each_entry_duplicate(ht, hash, match, key,                \
+                               iter, pos, member)                      \
+       for (cds_lfht_lookup(ht, hash, match, key, iter),               \
+                       pos = cds_lfht_entry(cds_lfht_iter_get_node(iter), \
+                               __typeof__(*(pos)), member);            \
+               pos != NULL;                                            \
+               cds_lfht_next_duplicate(ht, match, key, iter),          \
+                       pos = cds_lfht_entry(cds_lfht_iter_get_node(iter), \
+                               __typeof__(*(pos)), member))
+
+#endif /* !defined(caa_container_of_check_null) */
+/* clang-format on */