From c261b1c196fe92ffa7788b4f13959fb87f202424 Mon Sep 17 00:00:00 2001 From: Matteo Croce Date: Thu, 17 Jul 2025 22:03:37 +0200 Subject: [PATCH 1/4] libbpf: Fix warning in calloc() usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When compiling libbpf with some compilers, this warning is triggered: libbpf.c: In function ‘bpf_object__gen_loader’: libbpf.c:9209:28: error: ‘calloc’ sizes specified with ‘sizeof’ in the earlier argument and not in the later argument [-Werror=calloc-transposed-args] 9209 | gen = calloc(sizeof(*gen), 1); | ^ libbpf.c:9209:28: note: earlier argument should specify number of elements, later size of each element Fix this by inverting the calloc() arguments. Signed-off-by: Matteo Croce Signed-off-by: Andrii Nakryiko Acked-by: Yonghong Song Link: https://lore.kernel.org/bpf/20250717200337.49168-1-technoboy85@gmail.com (cherry picked from commit a9dbcc32fd5cae5f3229893cb0025a2eff03d768) --- src/libbpf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libbpf.c b/src/libbpf.c index aee36402f..af85989ae 100644 --- a/src/libbpf.c +++ b/src/libbpf.c @@ -9210,7 +9210,7 @@ int bpf_object__gen_loader(struct bpf_object *obj, struct gen_loader_opts *opts) return libbpf_err(-EFAULT); if (!OPTS_VALID(opts, gen_loader_opts)) return libbpf_err(-EINVAL); - gen = calloc(sizeof(*gen), 1); + gen = calloc(1, sizeof(*gen)); if (!gen) return libbpf_err(-ENOMEM); gen->opts = opts; From 108f2a9b782891b57d983c5542771368b4f2a3a0 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Thu, 17 Jul 2025 17:10:09 -0700 Subject: [PATCH 2/4] libbpf: Fix handling of BPF arena relocations Initial __arena global variable support implementation in libbpf contains a bug: it remembers struct bpf_map pointer for arena, which is used later on to process relocations. Recording this pointer is problematic because map pointers are not stable during ELF relocation collection phase, as an array of struct bpf_map's can be reallocated, invalidating all the pointers. Libbpf is dealing with similar issues by using a stable internal map index, though for BPF arena map specifically this approach wasn't used due to an oversight. The resulting behavior is non-deterministic issue which depends on exact layout of ELF object file, number of actual maps, etc. We didn't hit this until very recently, when this bug started triggering crash in BPF CI when validating one of sched-ext BPF programs. The fix is rather straightforward: we just follow an established pattern of remembering map index (just like obj->kconfig_map_idx, for example) instead of `struct bpf_map *`, and resolving index to a pointer at the point where map information is necessary. While at it also add debug-level message for arena-related relocation resolution information, which we already have for all other kinds of maps. Fixes: 2e7ba4f8fd1f ("libbpf: Recognize __arena global variables.") Signed-off-by: Andrii Nakryiko Tested-by: Eduard Zingerman Link: https://lore.kernel.org/r/20250718001009.610955-1-andrii@kernel.org Signed-off-by: Alexei Starovoitov (cherry picked from commit fb66fb4948933b09e5a73a5f705978c3a34de1df) --- src/libbpf.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/libbpf.c b/src/libbpf.c index af85989ae..162ebd16a 100644 --- a/src/libbpf.c +++ b/src/libbpf.c @@ -735,7 +735,7 @@ struct bpf_object { struct usdt_manager *usdt_man; - struct bpf_map *arena_map; + int arena_map_idx; void *arena_data; size_t arena_data_sz; @@ -1517,6 +1517,7 @@ static struct bpf_object *bpf_object__new(const char *path, obj->efile.obj_buf_sz = obj_buf_sz; obj->efile.btf_maps_shndx = -1; obj->kconfig_map_idx = -1; + obj->arena_map_idx = -1; obj->kern_version = get_kernel_version(); obj->state = OBJ_OPEN; @@ -2964,7 +2965,7 @@ static int init_arena_map_data(struct bpf_object *obj, struct bpf_map *map, const long page_sz = sysconf(_SC_PAGE_SIZE); size_t mmap_sz; - mmap_sz = bpf_map_mmap_sz(obj->arena_map); + mmap_sz = bpf_map_mmap_sz(map); if (roundup(data_sz, page_sz) > mmap_sz) { pr_warn("elf: sec '%s': declared ARENA map size (%zu) is too small to hold global __arena variables of size %zu\n", sec_name, mmap_sz, data_sz); @@ -3038,12 +3039,12 @@ static int bpf_object__init_user_btf_maps(struct bpf_object *obj, bool strict, if (map->def.type != BPF_MAP_TYPE_ARENA) continue; - if (obj->arena_map) { + if (obj->arena_map_idx >= 0) { pr_warn("map '%s': only single ARENA map is supported (map '%s' is also ARENA)\n", - map->name, obj->arena_map->name); + map->name, obj->maps[obj->arena_map_idx].name); return -EINVAL; } - obj->arena_map = map; + obj->arena_map_idx = i; if (obj->efile.arena_data) { err = init_arena_map_data(obj, map, ARENA_SEC, obj->efile.arena_data_shndx, @@ -3053,7 +3054,7 @@ static int bpf_object__init_user_btf_maps(struct bpf_object *obj, bool strict, return err; } } - if (obj->efile.arena_data && !obj->arena_map) { + if (obj->efile.arena_data && obj->arena_map_idx < 0) { pr_warn("elf: sec '%s': to use global __arena variables the ARENA map should be explicitly declared in SEC(\".maps\")\n", ARENA_SEC); return -ENOENT; @@ -4583,8 +4584,13 @@ static int bpf_program__record_reloc(struct bpf_program *prog, if (shdr_idx == obj->efile.arena_data_shndx) { reloc_desc->type = RELO_DATA; reloc_desc->insn_idx = insn_idx; - reloc_desc->map_idx = obj->arena_map - obj->maps; + reloc_desc->map_idx = obj->arena_map_idx; reloc_desc->sym_off = sym->st_value; + + map = &obj->maps[obj->arena_map_idx]; + pr_debug("prog '%s': found arena map %d (%s, sec %d, off %zu) for insn %u\n", + prog->name, obj->arena_map_idx, map->name, map->sec_idx, + map->sec_offset, insn_idx); return 0; } From f80f1b175a29a2ac6f775754a299ba564801f80e Mon Sep 17 00:00:00 2001 From: Eduard Zingerman Date: Fri, 18 Jul 2025 15:20:59 -0700 Subject: [PATCH 3/4] libbpf: Verify that arena map exists when adding arena relocations Fuzzer reported a memory access error in bpf_program__record_reloc() that happens when: - ".addr_space.1" section exists - there is a relocation referencing this section - there are no arena maps defined in BTF. Sanity checks for maps existence are already present in bpf_program__record_reloc(), hence this commit adds another one. [1] https://github.com/libbpf/libbpf/actions/runs/16375110681/job/46272998064 Signed-off-by: Eduard Zingerman Signed-off-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/20250718222059.281526-1-eddyz87@gmail.com (cherry picked from commit 8e59f80a935fd6dab5f718c5468afb3ec75dd029) --- src/libbpf.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libbpf.c b/src/libbpf.c index 162ebd16a..e067cb577 100644 --- a/src/libbpf.c +++ b/src/libbpf.c @@ -4582,6 +4582,11 @@ static int bpf_program__record_reloc(struct bpf_program *prog, /* arena data relocation */ if (shdr_idx == obj->efile.arena_data_shndx) { + if (obj->arena_map_idx < 0) { + pr_warn("prog '%s': bad arena data relocation at insn %u, no arena maps defined\n", + prog->name, insn_idx); + return -LIBBPF_ERRNO__RELOC; + } reloc_desc->type = RELO_DATA; reloc_desc->insn_idx = insn_idx; reloc_desc->map_idx = obj->arena_map_idx; From ba4eca3f152d92adfea38d55d5f66a9850b93973 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Fri, 18 Jul 2025 17:24:44 -0700 Subject: [PATCH 4/4] libbpf: bump version to v1.6.1 New patch version bump for v1.6.1. Signed-off-by: Andrii Nakryiko --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 61052d37e..950b26a19 100644 --- a/src/Makefile +++ b/src/Makefile @@ -10,7 +10,7 @@ endif LIBBPF_MAJOR_VERSION := 1 LIBBPF_MINOR_VERSION := 6 -LIBBPF_PATCH_VERSION := 0 +LIBBPF_PATCH_VERSION := 1 LIBBPF_VERSION := $(LIBBPF_MAJOR_VERSION).$(LIBBPF_MINOR_VERSION).$(LIBBPF_PATCH_VERSION) LIBBPF_MAJMIN_VERSION := $(LIBBPF_MAJOR_VERSION).$(LIBBPF_MINOR_VERSION).0 LIBBPF_MAP_VERSION := $(shell grep -oE '^LIBBPF_([0-9.]+)' libbpf.map | sort -rV | head -n1 | cut -d'_' -f2)