libbpf: Fix relocation of kfunc ksym in ld_imm64 insn.
authorAlexei Starovoitov <ast@kernel.org>
Fri, 17 Mar 2023 20:19:18 +0000 (13:19 -0700)
committerAndrii Nakryiko <andrii@kernel.org>
Fri, 17 Mar 2023 22:44:27 +0000 (15:44 -0700)
void *p = kfunc; -> generates ld_imm64 insn.
kfunc() -> generates bpf_call insn.

libbpf patches bpf_call insn correctly while only btf_id part of ld_imm64 is
set in the former case. Which means that pointers to kfuncs in modules are not
patched correctly and the verifier rejects load of such programs due to btf_id
being out of range. Fix libbpf to patch ld_imm64 for kfunc.

Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20230317201920.62030-3-alexei.starovoitov@gmail.com
tools/lib/bpf/libbpf.c

index a557718..4c34fbd 100644 (file)
@@ -7533,6 +7533,12 @@ static int bpf_object__resolve_ksym_func_btf_id(struct bpf_object *obj,
        ext->is_set = true;
        ext->ksym.kernel_btf_id = kfunc_id;
        ext->ksym.btf_fd_idx = mod_btf ? mod_btf->fd_array_idx : 0;
+       /* Also set kernel_btf_obj_fd to make sure that bpf_object__relocate_data()
+        * populates FD into ld_imm64 insn when it's used to point to kfunc.
+        * {kernel_btf_id, btf_fd_idx} -> fixup bpf_call.
+        * {kernel_btf_id, kernel_btf_obj_fd} -> fixup ld_imm64.
+        */
+       ext->ksym.kernel_btf_obj_fd = mod_btf ? mod_btf->fd : 0;
        pr_debug("extern (func ksym) '%s': resolved to kernel [%d]\n",
                 ext->name, kfunc_id);