From: KP Singh <kpsingh@kernel.org>
To: linux-security-module@vger.kernel.org, bpf@vger.kernel.org
Cc: ast@kernel.org, daniel@iogearbox.net, memxor@gmail.com,
James.Bottomley@HansenPartnership.com, paul@paul-moore.com,
KP Singh <kpsingh@kernel.org>
Subject: [PATCH bpf-next 06/13] bpf: resolve loader-style kfunc CALLs against prog BTF
Date: Fri, 22 May 2026 04:32:26 +0200 [thread overview]
Message-ID: <20260522023234.3778588-7-kpsingh@kernel.org> (raw)
In-Reply-To: <20260522023234.3778588-1-kpsingh@kernel.org>
gen_loader-emitted signed loaders cannot bake vmlinux BTF ids into
kfunc CALL imm at sign time. Add a new pseudo
BPF_PSEUDO_KFUNC_CALL_PROG_BTF that gen_loader emits in src_reg, with
imm holding the FUNC type id in the loader's own prog BTF.
In add_subprog_and_kfunc, look the FUNC up by name in vmlinux BTF,
patch imm with the resolved id, and rewrite src_reg back to
BPF_PSEUDO_KFUNC_CALL so downstream passes see a normal kfunc CALL.
Leave standard src_reg calls unchanged.
Signed-off-by: KP Singh <kpsingh@kernel.org>
---
include/linux/bpf_verifier.h | 6 ++++
include/uapi/linux/bpf.h | 5 ++++
kernel/bpf/verifier.c | 54 ++++++++++++++++++++++++++++++++--
tools/include/uapi/linux/bpf.h | 5 ++++
4 files changed, 67 insertions(+), 3 deletions(-)
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index 185b2aa43a42..396b85830996 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -959,6 +959,12 @@ static inline bool bpf_pseudo_kfunc_call(const struct bpf_insn *insn)
insn->src_reg == BPF_PSEUDO_KFUNC_CALL;
}
+static inline bool bpf_pseudo_kfunc_call_prog_btf(const struct bpf_insn *insn)
+{
+ return insn->code == (BPF_JMP | BPF_CALL) &&
+ insn->src_reg == BPF_PSEUDO_KFUNC_CALL_PROG_BTF;
+}
+
__printf(2, 0) void bpf_verifier_vlog(struct bpf_verifier_log *log,
const char *fmt, va_list args);
__printf(2, 3) void bpf_verifier_log_write(struct bpf_verifier_env *env,
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 552bc5d9afbd..06056e714e8e 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -1382,6 +1382,11 @@ enum {
* bpf_call->imm == btf_id of a BTF_KIND_FUNC in the running kernel
*/
#define BPF_PSEUDO_KFUNC_CALL 2
+/* when bpf_call->src_reg == BPF_PSEUDO_KFUNC_CALL_PROG_BTF,
+ * bpf_call->imm == btf_id of a BTF_KIND_FUNC in the program's
+ * prog BTF. The verifier resolves it to a vmlinux btf_id by name.
+ */
+#define BPF_PSEUDO_KFUNC_CALL_PROG_BTF 3
enum bpf_addr_space_cast {
BPF_ADDR_SPACE_CAST = 1,
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index f0e45cfa5b34..1b5d06b9d74a 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -3088,6 +3088,47 @@ bool bpf_prog_has_kfunc_call(const struct bpf_prog *prog)
return !!prog->aux->kfunc_tab;
}
+/*
+ * Resolve a gen_loader-emitted kfunc CALL by FUNC name in vmlinux BTF,
+ * then rewrite src_reg back to BPF_PSEUDO_KFUNC_CALL. Caller must have
+ * already filtered for BPF_PSEUDO_KFUNC_CALL_PROG_BTF.
+ */
+static int resolve_loader_kfunc(struct bpf_verifier_env *env,
+ struct bpf_insn *insn, int insn_idx)
+{
+ struct btf *prog_btf = env->prog->aux->btf;
+ const struct btf_type *t;
+ const char *name;
+ s32 vmlinux_id;
+
+ if (!prog_btf || !btf_vmlinux || insn->off) {
+ verbose(env, "kfunc call insn %d: PROG_BTF resolution requires prog BTF and insn->off == 0\n",
+ insn_idx);
+ return -EINVAL;
+ }
+ t = btf_type_by_id(prog_btf, insn->imm);
+ if (!t || !btf_type_is_func(t)) {
+ verbose(env, "kfunc call insn %d: imm %d is not a FUNC in prog BTF\n",
+ insn_idx, insn->imm);
+ return -EINVAL;
+ }
+ name = btf_name_by_offset(prog_btf, t->name_off);
+ if (!name || !name[0]) {
+ verbose(env, "kfunc call insn %d: prog-BTF FUNC has no name\n",
+ insn_idx);
+ return -EINVAL;
+ }
+ vmlinux_id = btf_find_by_name_kind(btf_vmlinux, name, BTF_KIND_FUNC);
+ if (vmlinux_id < 0) {
+ verbose(env, "kfunc call insn %d: %s not found in vmlinux BTF\n",
+ insn_idx, name);
+ return vmlinux_id;
+ }
+ insn->imm = vmlinux_id;
+ insn->src_reg = BPF_PSEUDO_KFUNC_CALL;
+ return 0;
+}
+
static int add_subprog_and_kfunc(struct bpf_verifier_env *env)
{
struct bpf_subprog_info *subprog = env->subprog_info;
@@ -3101,7 +3142,8 @@ static int add_subprog_and_kfunc(struct bpf_verifier_env *env)
for (i = 0; i < insn_cnt; i++, insn++) {
if (!bpf_pseudo_func(insn) && !bpf_pseudo_call(insn) &&
- !bpf_pseudo_kfunc_call(insn))
+ !bpf_pseudo_kfunc_call(insn) &&
+ !bpf_pseudo_kfunc_call_prog_btf(insn))
continue;
if (!env->bpf_capable) {
@@ -3109,10 +3151,16 @@ static int add_subprog_and_kfunc(struct bpf_verifier_env *env)
return -EPERM;
}
- if (bpf_pseudo_func(insn) || bpf_pseudo_call(insn))
+ if (bpf_pseudo_func(insn) || bpf_pseudo_call(insn)) {
ret = add_subprog(env, i + insn->imm + 1);
- else
+ } else {
+ if (bpf_pseudo_kfunc_call_prog_btf(insn)) {
+ ret = resolve_loader_kfunc(env, insn, i);
+ if (ret < 0)
+ return ret;
+ }
ret = bpf_add_kfunc_call(env, insn->imm, insn->off);
+ }
if (ret < 0)
return ret;
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 677be9a47347..d4f7f3e0aaa3 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -1382,6 +1382,11 @@ enum {
* bpf_call->imm == btf_id of a BTF_KIND_FUNC in the running kernel
*/
#define BPF_PSEUDO_KFUNC_CALL 2
+/* when bpf_call->src_reg == BPF_PSEUDO_KFUNC_CALL_PROG_BTF,
+ * bpf_call->imm == btf_id of a BTF_KIND_FUNC in the program's
+ * prog BTF. The verifier resolves it to a vmlinux btf_id by name.
+ */
+#define BPF_PSEUDO_KFUNC_CALL_PROG_BTF 3
enum bpf_addr_space_cast {
BPF_ADDR_SPACE_CAST = 1,
--
2.53.0
next prev parent reply other threads:[~2026-05-22 2:32 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-22 2:32 [PATCH bpf-next 00/13] Signed BPF + IPE Policies KP Singh
2026-05-22 2:32 ` [PATCH bpf-next 01/13] bpf: expose signature verdict to LSMs via bpf_prog_aux KP Singh
2026-05-22 2:32 ` [PATCH bpf-next 02/13] bpf: include prog BTF in the signed loader signature scope KP Singh
2026-05-22 2:32 ` [PATCH bpf-next 03/13] bpf, libbpf: load prog BTF in the skel_internal loader KP Singh
2026-05-22 2:32 ` [PATCH bpf-next 04/13] bpf: add bpf_loader_verify_metadata kfunc KP Singh
2026-05-22 2:32 ` [PATCH bpf-next 05/13] bpf: compute prog->digest at BPF_PROG_LOAD entry KP Singh
2026-05-23 16:49 ` Alexei Starovoitov
2026-05-22 2:32 ` KP Singh [this message]
2026-05-23 17:01 ` [PATCH bpf-next 06/13] bpf: resolve loader-style kfunc CALLs against prog BTF Alexei Starovoitov
2026-05-22 2:32 ` [PATCH bpf-next 07/13] libbpf: generate prog BTF for loader programs KP Singh
2026-05-22 2:32 ` [PATCH bpf-next 08/13] bpftool gen: embed loader prog BTF in the lskel header KP Singh
2026-05-22 2:32 ` [PATCH bpf-next 09/13] lsm: add bpf_prog_load_post_integrity hook KP Singh
2026-05-24 0:55 ` Paul Moore
2026-05-22 2:32 ` [PATCH bpf-next 10/13] bpf: invoke security_bpf_prog_load_post_integrity from the metadata kfunc KP Singh
2026-05-22 2:32 ` [PATCH bpf-next 11/13] ipe: add BPF program signature properties KP Singh
2026-05-22 2:32 ` [PATCH bpf-next 12/13] ipe: gate post-integrity BPF program loads KP Singh
2026-05-22 2:32 ` [PATCH bpf-next 13/13] selftests/bpf: add IPE BPF policy integration tests KP Singh
2026-05-22 18:56 ` [PATCH bpf-next 00/13] Signed BPF + IPE Policies Paul Moore
2026-05-22 20:46 ` KP Singh
2026-05-23 4:07 ` Paul Moore
2026-05-23 8:40 ` Alexei Starovoitov
2026-05-23 12:40 ` Paul Moore
2026-05-23 12:44 ` Paul Moore
2026-05-23 15:43 ` Blaise Boscaccy
2026-05-23 14:34 ` Alexei Starovoitov
2026-05-23 16:34 ` Blaise Boscaccy
2026-05-26 16:23 ` KP Singh
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260522023234.3778588-7-kpsingh@kernel.org \
--to=kpsingh@kernel.org \
--cc=James.Bottomley@HansenPartnership.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=linux-security-module@vger.kernel.org \
--cc=memxor@gmail.com \
--cc=paul@paul-moore.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.