Skip to content

Commit 029258d

Browse files
anakryikoAlexei Starovoitov
authored andcommitted
libbpf: Remove any use of reallocarray() in libbpf
Re-implement glibc's reallocarray() for libbpf internal-only use. reallocarray(), unfortunately, is not available in all versions of glibc, so requires extra feature detection and using reallocarray() stub from <tools/libc_compat.h> and COMPAT_NEED_REALLOCARRAY. All this complicates build of libbpf unnecessarily and is just a maintenance burden. Instead, it's trivial to implement libbpf-specific internal version and use it throughout libbpf. Which is what this patch does, along with converting some realloc() uses that should really have been reallocarray() in the first place. Signed-off-by: Andrii Nakryiko <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 00b2e95 commit 029258d

File tree

6 files changed

+45
-29
lines changed

6 files changed

+45
-29
lines changed

tools/lib/bpf/Makefile

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ ifndef VERBOSE
5656
endif
5757

5858
FEATURE_USER = .libbpf
59-
FEATURE_TESTS = libelf libelf-mmap zlib bpf reallocarray
59+
FEATURE_TESTS = libelf libelf-mmap zlib bpf
6060
FEATURE_DISPLAY = libelf zlib bpf
6161

6262
INCLUDES = -I. -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(ARCH)/include/uapi -I$(srctree)/tools/include/uapi
@@ -102,10 +102,6 @@ ifeq ($(feature-libelf-mmap), 1)
102102
override CFLAGS += -DHAVE_LIBELF_MMAP_SUPPORT
103103
endif
104104

105-
ifeq ($(feature-reallocarray), 0)
106-
override CFLAGS += -DCOMPAT_NEED_REALLOCARRAY
107-
endif
108-
109105
# Append required CFLAGS
110106
override CFLAGS += $(EXTRA_WARNINGS) -Wno-switch-enum
111107
override CFLAGS += -Werror -Wall

tools/lib/bpf/btf.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ static int btf_add_type(struct btf *btf, struct btf_type *t)
6161
expand_by = max(btf->types_size >> 2, 16U);
6262
new_size = min(BTF_MAX_NR_TYPES, btf->types_size + expand_by);
6363

64-
new_types = realloc(btf->types, sizeof(*new_types) * new_size);
64+
new_types = libbpf_reallocarray(btf->types, new_size, sizeof(*new_types));
6565
if (!new_types)
6666
return -ENOMEM;
6767

@@ -1574,7 +1574,7 @@ static int btf_dedup_hypot_map_add(struct btf_dedup *d,
15741574
__u32 *new_list;
15751575

15761576
d->hypot_cap += max((size_t)16, d->hypot_cap / 2);
1577-
new_list = realloc(d->hypot_list, sizeof(__u32) * d->hypot_cap);
1577+
new_list = libbpf_reallocarray(d->hypot_list, d->hypot_cap, sizeof(__u32));
15781578
if (!new_list)
15791579
return -ENOMEM;
15801580
d->hypot_list = new_list;
@@ -1870,8 +1870,7 @@ static int btf_dedup_strings(struct btf_dedup *d)
18701870
struct btf_str_ptr *new_ptrs;
18711871

18721872
strs.cap += max(strs.cnt / 2, 16U);
1873-
new_ptrs = realloc(strs.ptrs,
1874-
sizeof(strs.ptrs[0]) * strs.cap);
1873+
new_ptrs = libbpf_reallocarray(strs.ptrs, strs.cap, sizeof(strs.ptrs[0]));
18751874
if (!new_ptrs) {
18761875
err = -ENOMEM;
18771876
goto done;
@@ -2956,8 +2955,8 @@ static int btf_dedup_compact_types(struct btf_dedup *d)
29562955
d->btf->nr_types = next_type_id - 1;
29572956
d->btf->types_size = d->btf->nr_types;
29582957
d->btf->hdr->type_len = p - types_start;
2959-
new_types = realloc(d->btf->types,
2960-
(1 + d->btf->nr_types) * sizeof(struct btf_type *));
2958+
new_types = libbpf_reallocarray(d->btf->types, (1 + d->btf->nr_types),
2959+
sizeof(struct btf_type *));
29612960
if (!new_types)
29622961
return -ENOMEM;
29632962
d->btf->types = new_types;

tools/lib/bpf/btf_dump.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -323,8 +323,7 @@ static int btf_dump_add_emit_queue_id(struct btf_dump *d, __u32 id)
323323

324324
if (d->emit_queue_cnt >= d->emit_queue_cap) {
325325
new_cap = max(16, d->emit_queue_cap * 3 / 2);
326-
new_queue = realloc(d->emit_queue,
327-
new_cap * sizeof(new_queue[0]));
326+
new_queue = libbpf_reallocarray(d->emit_queue, new_cap, sizeof(new_queue[0]));
328327
if (!new_queue)
329328
return -ENOMEM;
330329
d->emit_queue = new_queue;
@@ -1003,8 +1002,7 @@ static int btf_dump_push_decl_stack_id(struct btf_dump *d, __u32 id)
10031002

10041003
if (d->decl_stack_cnt >= d->decl_stack_cap) {
10051004
new_cap = max(16, d->decl_stack_cap * 3 / 2);
1006-
new_stack = realloc(d->decl_stack,
1007-
new_cap * sizeof(new_stack[0]));
1005+
new_stack = libbpf_reallocarray(d->decl_stack, new_cap, sizeof(new_stack[0]));
10081006
if (!new_stack)
10091007
return -ENOMEM;
10101008
d->decl_stack = new_stack;

tools/lib/bpf/libbpf.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
#include <sys/vfs.h>
4545
#include <sys/utsname.h>
4646
#include <sys/resource.h>
47-
#include <tools/libc_compat.h>
4847
#include <libelf.h>
4948
#include <gelf.h>
5049
#include <zlib.h>
@@ -567,7 +566,7 @@ bpf_object__add_program(struct bpf_object *obj, void *data, size_t size,
567566
progs = obj->programs;
568567
nr_progs = obj->nr_programs;
569568

570-
progs = reallocarray(progs, nr_progs + 1, sizeof(progs[0]));
569+
progs = libbpf_reallocarray(progs, nr_progs + 1, sizeof(progs[0]));
571570
if (!progs) {
572571
/*
573572
* In this case the original obj->programs
@@ -1292,7 +1291,7 @@ static struct bpf_map *bpf_object__add_map(struct bpf_object *obj)
12921291
return &obj->maps[obj->nr_maps++];
12931292

12941293
new_cap = max((size_t)4, obj->maps_cap * 3 / 2);
1295-
new_maps = realloc(obj->maps, new_cap * sizeof(*obj->maps));
1294+
new_maps = libbpf_reallocarray(obj->maps, new_cap, sizeof(*obj->maps));
12961295
if (!new_maps) {
12971296
pr_warn("alloc maps for object failed\n");
12981297
return ERR_PTR(-ENOMEM);
@@ -2721,8 +2720,8 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
27212720
continue;
27222721
}
27232722

2724-
sects = reallocarray(sects, nr_sects + 1,
2725-
sizeof(*obj->efile.reloc_sects));
2723+
sects = libbpf_reallocarray(sects, nr_sects + 1,
2724+
sizeof(*obj->efile.reloc_sects));
27262725
if (!sects) {
27272726
pr_warn("reloc_sects realloc failed\n");
27282727
return -ENOMEM;
@@ -2925,7 +2924,7 @@ static int bpf_object__collect_externs(struct bpf_object *obj)
29252924
continue;
29262925

29272926
ext = obj->externs;
2928-
ext = reallocarray(ext, obj->nr_extern + 1, sizeof(*ext));
2927+
ext = libbpf_reallocarray(ext, obj->nr_extern + 1, sizeof(*ext));
29292928
if (!ext)
29302929
return -ENOMEM;
29312930
obj->externs = ext;
@@ -4362,9 +4361,9 @@ static struct ids_vec *bpf_core_find_cands(const struct btf *local_btf,
43624361
pr_debug("CO-RE relocating [%d] %s %s: found target candidate [%d] %s %s\n",
43634362
local_type_id, btf_kind_str(local_t),
43644363
local_name, i, targ_kind, targ_name);
4365-
new_ids = reallocarray(cand_ids->data,
4366-
cand_ids->len + 1,
4367-
sizeof(*cand_ids->data));
4364+
new_ids = libbpf_reallocarray(cand_ids->data,
4365+
cand_ids->len + 1,
4366+
sizeof(*cand_ids->data));
43684367
if (!new_ids) {
43694368
err = -ENOMEM;
43704369
goto err_out;
@@ -5231,7 +5230,7 @@ bpf_program__reloc_text(struct bpf_program *prog, struct bpf_object *obj,
52315230
return -LIBBPF_ERRNO__RELOC;
52325231
}
52335232
new_cnt = prog->insns_cnt + text->insns_cnt;
5234-
new_insn = reallocarray(prog->insns, new_cnt, sizeof(*insn));
5233+
new_insn = libbpf_reallocarray(prog->insns, new_cnt, sizeof(*insn));
52355234
if (!new_insn) {
52365235
pr_warn("oom in prog realloc\n");
52375236
return -ENOMEM;
@@ -5473,7 +5472,7 @@ static int bpf_object__collect_map_relos(struct bpf_object *obj,
54735472
moff /= bpf_ptr_sz;
54745473
if (moff >= map->init_slots_sz) {
54755474
new_sz = moff + 1;
5476-
tmp = realloc(map->init_slots, new_sz * host_ptr_sz);
5475+
tmp = libbpf_reallocarray(map->init_slots, new_sz, host_ptr_sz);
54775476
if (!tmp)
54785477
return -ENOMEM;
54795478
map->init_slots = tmp;

tools/lib/bpf/libbpf_internal.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#ifndef __LIBBPF_LIBBPF_INTERNAL_H
1010
#define __LIBBPF_LIBBPF_INTERNAL_H
1111

12+
#include <stdlib.h>
1213
#include "libbpf.h"
1314

1415
#define BTF_INFO_ENC(kind, kind_flag, vlen) \
@@ -23,6 +24,12 @@
2324
#define BTF_PARAM_ENC(name, type) (name), (type)
2425
#define BTF_VAR_SECINFO_ENC(type, offset, size) (type), (offset), (size)
2526

27+
#ifndef likely
28+
#define likely(x) __builtin_expect(!!(x), 1)
29+
#endif
30+
#ifndef unlikely
31+
#define unlikely(x) __builtin_expect(!!(x), 0)
32+
#endif
2633
#ifndef min
2734
# define min(x, y) ((x) < (y) ? (x) : (y))
2835
#endif
@@ -63,6 +70,24 @@ do { \
6370
#define pr_info(fmt, ...) __pr(LIBBPF_INFO, fmt, ##__VA_ARGS__)
6471
#define pr_debug(fmt, ...) __pr(LIBBPF_DEBUG, fmt, ##__VA_ARGS__)
6572

73+
/*
74+
* Re-implement glibc's reallocarray() for libbpf internal-only use.
75+
* reallocarray(), unfortunately, is not available in all versions of glibc,
76+
* so requires extra feature detection and using reallocarray() stub from
77+
* <tools/libc_compat.h> and COMPAT_NEED_REALLOCARRAY. All this complicates
78+
* build of libbpf unnecessarily and is just a maintenance burden. Instead,
79+
* it's trivial to implement libbpf-specific internal version and use it
80+
* throughout libbpf.
81+
*/
82+
static inline void *libbpf_reallocarray(void *ptr, size_t nmemb, size_t size)
83+
{
84+
size_t total;
85+
86+
if (unlikely(__builtin_mul_overflow(nmemb, size, &total)))
87+
return NULL;
88+
return realloc(ptr, total);
89+
}
90+
6691
static inline bool libbpf_validate_opts(const char *opts,
6792
size_t opts_sz, size_t user_sz,
6893
const char *type_name)

tools/lib/bpf/ringbuf.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#include <asm/barrier.h>
1717
#include <sys/mman.h>
1818
#include <sys/epoll.h>
19-
#include <tools/libc_compat.h>
2019

2120
#include "libbpf.h"
2221
#include "libbpf_internal.h"
@@ -82,12 +81,12 @@ int ring_buffer__add(struct ring_buffer *rb, int map_fd,
8281
return -EINVAL;
8382
}
8483

85-
tmp = reallocarray(rb->rings, rb->ring_cnt + 1, sizeof(*rb->rings));
84+
tmp = libbpf_reallocarray(rb->rings, rb->ring_cnt + 1, sizeof(*rb->rings));
8685
if (!tmp)
8786
return -ENOMEM;
8887
rb->rings = tmp;
8988

90-
tmp = reallocarray(rb->events, rb->ring_cnt + 1, sizeof(*rb->events));
89+
tmp = libbpf_reallocarray(rb->events, rb->ring_cnt + 1, sizeof(*rb->events));
9190
if (!tmp)
9291
return -ENOMEM;
9392
rb->events = tmp;

0 commit comments

Comments
 (0)