libbpf: Fix libbpf build on compilers missing __builtin_mul_overflow
authorAndrii Nakryiko <andriin@fb.com>
Thu, 20 Aug 2020 06:14:09 +0000 (23:14 -0700)
committerDaniel Borkmann <daniel@iogearbox.net>
Thu, 20 Aug 2020 14:45:09 +0000 (16:45 +0200)
GCC compilers older than version 5 don't support __builtin_mul_overflow yet.
Given GCC 4.9 is the minimal supported compiler for building kernel and the
fact that libbpf is a dependency of resolve_btfids, which is dependency of
CONFIG_DEBUG_INFO_BTF=y, this needs to be handled. This patch fixes the issue
by falling back to slower detection of integer overflow in such cases.

Fixes: 029258d7b228 ("libbpf: Remove any use of reallocarray() in libbpf")
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Yonghong Song <yhs@fb.com>
Link: https://lore.kernel.org/bpf/20200820061411.1755905-2-andriin@fb.com
tools/lib/bpf/libbpf_internal.h

index 61dff515a2f0f32b073ce231122cf55ac82a9d13..4d1c366fca2ca46be5865bd3f99e0212a531cf53 100644 (file)
@@ -10,6 +10,7 @@
 #define __LIBBPF_LIBBPF_INTERNAL_H
 
 #include <stdlib.h>
+#include <limits.h>
 
 /* make sure libbpf doesn't use kernel-only integer typedefs */
 #pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
@@ -77,6 +78,9 @@ do {                          \
 #define pr_info(fmt, ...)      __pr(LIBBPF_INFO, fmt, ##__VA_ARGS__)
 #define pr_debug(fmt, ...)     __pr(LIBBPF_DEBUG, fmt, ##__VA_ARGS__)
 
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
 /*
  * Re-implement glibc's reallocarray() for libbpf internal-only use.
  * reallocarray(), unfortunately, is not available in all versions of glibc,
@@ -90,8 +94,14 @@ static inline void *libbpf_reallocarray(void *ptr, size_t nmemb, size_t size)
 {
        size_t total;
 
+#if __has_builtin(__builtin_mul_overflow)
        if (unlikely(__builtin_mul_overflow(nmemb, size, &total)))
                return NULL;
+#else
+       if (size == 0 || nmemb > ULONG_MAX / size)
+               return NULL;
+       total = nmemb * size;
+#endif
        return realloc(ptr, total);
 }