From: Ondřej Surý Date: Thu, 22 Jun 2023 10:25:45 +0000 (+0200) Subject: Workaround AddressSanitizer overzealous check X-Git-Tag: v9.19.16~19^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=dc3e07572b311398968c05c8d9999761c6868143;p=thirdparty%2Fbind9.git Workaround AddressSanitizer overzealous check 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 header, so our CI checks pass. --- diff --git a/lib/isc/include/isc/urcu.h b/lib/isc/include/isc/urcu.h index c4dfe6a180b..d1acf991219 100644 --- a/lib/isc/include/isc/urcu.h +++ b/lib/isc/include/isc/urcu.h @@ -117,3 +117,54 @@ #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 */