Message ID | 20230317201920.62030-3-alexei.starovoitov@gmail.com (mailing list archive) |
---|---|
State | Accepted |
Commit | 5fc13ad59b60708e52932188854d4d5bf2b0e10e |
Delegated to: | BPF |
Headers | show |
Series | bpf: Add detection of kfuncs. | expand |
On Fri, Mar 17, 2023 at 1:19 PM Alexei Starovoitov <alexei.starovoitov@gmail.com> wrote: > > From: Alexei Starovoitov <ast@kernel.org> > > 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> > --- > tools/lib/bpf/libbpf.c | 6 ++++++ > 1 file changed, 6 insertions(+) > > diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c > index a557718401e4..4c34fbd7b5be 100644 > --- a/tools/lib/bpf/libbpf.c > +++ b/tools/lib/bpf/libbpf.c > @@ -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); we should report module name here as well, I'll send a patch for both func and var ksyms > > -- > 2.34.1 >
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index a557718401e4..4c34fbd7b5be 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -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);