The C standard specifies that it's undefined behavior to dereference NULL (even if you use & right after). The hand-rolled offsetof idiom &(((s*)NULL)->f) is thus technically undefined. This clutters the output of UBSan and is simple to fix: just use the real offsetof when it's available.
This patch also changes two instances of pointer arithmetic on void * to use char * instead, again to avoid UB. After this patch, HAProxy can run without crashing after building w/ clang-19 -fsanitize=undefined -fno-sanitize=function,alignment --- include/haproxy/compiler.h | 4 ++-- include/haproxy/list.h | 2 +- include/import/mt_list.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/haproxy/compiler.h b/include/haproxy/compiler.h index 80d9be772..52aee39b9 100644 --- a/include/haproxy/compiler.h +++ b/include/haproxy/compiler.h @@ -350,7 +350,7 @@ * <type> which has its member <name> stored at address <ptr>. */ #ifndef container_of -#define container_of(ptr, type, name) ((type *)(((void *)(ptr)) - ((long)&((type *)0)->name))) +#define container_of(ptr, type, name) ((type *)(((char *)(ptr)) - offsetof(type, name))) #endif /* returns a pointer to the structure of type <type> which has its member <name> @@ -359,7 +359,7 @@ #ifndef container_of_safe #define container_of_safe(ptr, type, name) \ ({ void *__p = (ptr); \ - __p ? (type *)(__p - ((long)&((type *)0)->name)) : (type *)0; \ + __p ? (type *)((char *)__p - offsetof(type, name)) : (type *)0; \ }) #endif diff --git a/include/haproxy/list.h b/include/haproxy/list.h index ff203147c..c2fcdfbc6 100644 --- a/include/haproxy/list.h +++ b/include/haproxy/list.h @@ -97,7 +97,7 @@ * since it's used only once. * Example: LIST_ELEM(cur_node->args.next, struct node *, args) */ -#define LIST_ELEM(lh, pt, el) ((pt)(((const char *)(lh)) - ((size_t)&((pt)NULL)->el))) +#define LIST_ELEM(lh, pt, el) ((pt)(((const char *)(lh)) - offsetof(typeof(*(pt)NULL), el))) /* checks if the list head <lh> is empty or not */ #define LIST_ISEMPTY(lh) ((lh)->n == (lh)) diff --git a/include/import/mt_list.h b/include/import/mt_list.h index 9339d0e07..09526eb0b 100644 --- a/include/import/mt_list.h +++ b/include/import/mt_list.h @@ -87,7 +87,7 @@ struct mt_list { * * return MT_LIST_ELEM(cur_node->args.next, struct node *, args) */ -#define MT_LIST_ELEM(a, t, m) ((t)(size_t)(((size_t)(a)) - ((size_t)&((t)NULL)->m))) +#define MT_LIST_ELEM(a, t, m) ((t)(size_t)(((size_t)(a)) - offsetof(typeof(*(t)NULL), m))) /* Returns a pointer of type <t> to a structure following the element which -- 2.50.1