Commit bdeeed34 authored by Andrii Nakryiko's avatar Andrii Nakryiko Committed by Alexei Starovoitov
Browse files

libbpf: fix offsetof() and container_of() to work with CO-RE



It seems like __builtin_offset() doesn't preserve CO-RE field
relocations properly. So if offsetof() macro is defined through
__builtin_offset(), CO-RE-enabled BPF code using container_of() will be
subtly and silently broken.

To avoid this problem, redefine offsetof() and container_of() in the
form that works with CO-RE relocations more reliably.

Fixes: 5fbc2208 ("tools/libpf: Add offsetof/container_of macro in bpf_helpers.h")
Reported-by: default avatarLennart Poettering <lennart@poettering.net>
Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Acked-by: default avatarYonghong Song <yhs@fb.com>
Link: https://lore.kernel.org/r/20230509065502.2306180-1-andrii@kernel.org


Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent ee9fd0ac
Loading
Loading
Loading
Loading
+10 −5
Original line number Original line Diff line number Diff line
@@ -77,16 +77,21 @@
/*
/*
 * Helper macros to manipulate data structures
 * Helper macros to manipulate data structures
 */
 */
#ifndef offsetof

#define offsetof(TYPE, MEMBER)	((unsigned long)&((TYPE *)0)->MEMBER)
/* offsetof() definition that uses __builtin_offset() might not preserve field
#endif
 * offset CO-RE relocation properly, so force-redefine offsetof() using
#ifndef container_of
 * old-school approach which works with CO-RE correctly
 */
#undef offsetof
#define offsetof(type, member)	((unsigned long)&((type *)0)->member)

/* redefined container_of() to ensure we use the above offsetof() macro */
#undef container_of
#define container_of(ptr, type, member)				\
#define container_of(ptr, type, member)				\
	({							\
	({							\
		void *__mptr = (void *)(ptr);			\
		void *__mptr = (void *)(ptr);			\
		((type *)(__mptr - offsetof(type, member)));	\
		((type *)(__mptr - offsetof(type, member)));	\
	})
	})
#endif


/*
/*
 * Compiler (optimization) barrier.
 * Compiler (optimization) barrier.