Skip to content

Commit 593fffb

Browse files
committed
Merge branch 'libbpf-fix-perm-errors-for-ldimm_64_full_range_off'
Emil Tsalapatis says: ==================== libbpf: Fix perm errors for LDIMM_64_FULL_RANGE_OFF Commit 728ff16 ("libbpf: Add gating for arena globals relocation feature") adds a feature flag for testing whether the running kernel supports LDIMM64 instructions with large direct offsets. Fix two edge cases that can cause unexpected -EPERM errors in two ways: 1) The probe program used for the feature has type TRACEPOINT, but it's possible the caller does not have permission to load it, even if it is able to do so for generic BPF programs. Use the SOCKET_FILTER type instead that requires fewer permissions. This does not affect the check itself, which will always fail verification anyway. 2) The probe is triggered during bpf_object__collect_relos(), itself called in bpf_object_open(), to compute the arena relocation offsets of arena variables. However, the caller may not have permissions to load BPF programs. This is the case in some systems with the bpftool calls made by the BPF selftests during compilation, e.g., for skeleton generation. Move all uses of the feature check to bpf_object_prepare() time instead. Fixes: 728ff16 ("libbpf: Add gating for arena globals relocation feature") Signed-off-by: Emil Tsalapatis <emil@etsalapatis.com> v2 -> v3: https://lore.kernel.org/bpf/20260214021014.15670-1-emil@etsalapatis.com/ - Only zero out the first byte of the log buffer (Andrii) - Minimize invocations of the feature gate (Andrii) v1 -> v2: https://lore.kernel.org/bpf/20260213181752.505318-1-emil@etsalapatis.com/ - Adjust the hash of the original commit post-tree rebase - Ensure close() is not called on invalid prog_fd in feature probe (Coverity) ==================== Link: https://patch.msgid.link/20260217204345.548648-1-emil@etsalapatis.com Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
2 parents b0b1a85 + d798872 commit 593fffb

2 files changed

Lines changed: 16 additions & 9 deletions

File tree

tools/lib/bpf/features.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -536,14 +536,15 @@ static int probe_ldimm64_full_range_off(int token_fd)
536536
}
537537
insns[0].imm = map_fd;
538538

539-
prog_fd = bpf_prog_load(BPF_PROG_TYPE_TRACEPOINT, "global_reloc", "GPL", insns, insn_cnt, &prog_opts);
539+
log_buf[0] = '\0';
540+
prog_fd = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, "global_reloc", "GPL", insns, insn_cnt, &prog_opts);
540541
ret = -errno;
541542

542543
close(map_fd);
543-
close(prog_fd);
544544

545545
if (prog_fd >= 0) {
546546
pr_warn("Error in %s(): Program loading unexpectedly succeeded.\n", __func__);
547+
close(prog_fd);
547548
return -EINVAL;
548549
}
549550

tools/lib/bpf/libbpf.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3009,12 +3009,6 @@ static int init_arena_map_data(struct bpf_object *obj, struct bpf_map *map,
30093009
memcpy(obj->arena_data, data, data_sz);
30103010
obj->arena_data_sz = data_sz;
30113011

3012-
/* place globals at the end of the arena (if supported) */
3013-
if (kernel_supports(obj, FEAT_LDIMM64_FULL_RANGE_OFF))
3014-
obj->arena_data_off = mmap_sz - data_alloc_sz;
3015-
else
3016-
obj->arena_data_off = 0;
3017-
30183012
/* make bpf_map__init_value() work for ARENA maps */
30193013
map->mmaped = obj->arena_data;
30203014

@@ -4672,7 +4666,7 @@ static int bpf_program__record_reloc(struct bpf_program *prog,
46724666
reloc_desc->type = RELO_DATA;
46734667
reloc_desc->insn_idx = insn_idx;
46744668
reloc_desc->map_idx = obj->arena_map_idx;
4675-
reloc_desc->sym_off = sym->st_value + obj->arena_data_off;
4669+
reloc_desc->sym_off = sym->st_value;
46764670

46774671
map = &obj->maps[obj->arena_map_idx];
46784672
pr_debug("prog '%s': found arena map %d (%s, sec %d, off %zu) for insn %u\n",
@@ -6386,6 +6380,10 @@ bpf_object__relocate_data(struct bpf_object *obj, struct bpf_program *prog)
63866380
case RELO_DATA:
63876381
map = &obj->maps[relo->map_idx];
63886382
insn[1].imm = insn[0].imm + relo->sym_off;
6383+
6384+
if (relo->map_idx == obj->arena_map_idx)
6385+
insn[1].imm += obj->arena_data_off;
6386+
63896387
if (obj->gen_loader) {
63906388
insn[0].src_reg = BPF_PSEUDO_MAP_IDX_VALUE;
63916389
insn[0].imm = relo->map_idx;
@@ -7387,6 +7385,14 @@ static int bpf_object__relocate(struct bpf_object *obj, const char *targ_btf_pat
73877385
bpf_object__sort_relos(obj);
73887386
}
73897387

7388+
/* place globals at the end of the arena (if supported) */
7389+
if (obj->arena_map_idx >= 0 && kernel_supports(obj, FEAT_LDIMM64_FULL_RANGE_OFF)) {
7390+
struct bpf_map *arena_map = &obj->maps[obj->arena_map_idx];
7391+
7392+
obj->arena_data_off = bpf_map_mmap_sz(arena_map) -
7393+
roundup(obj->arena_data_sz, sysconf(_SC_PAGE_SIZE));
7394+
}
7395+
73907396
/* Before relocating calls pre-process relocations and mark
73917397
* few ld_imm64 instructions that points to subprogs.
73927398
* Otherwise bpf_object__reloc_code() later would have to consider

0 commit comments

Comments
 (0)