Thread (7 messages) 7 messages, 2 authors, 2026-02-26
STALE111d

[PATCH RFC bpf-next 2/5] bpf: Allow passing kernel context pointer to kfuncs

From: Jakub Sitnicki <jakub@cloudflare.com>
Date: 2026-02-26 21:13:11
Also in: bpf
Subsystem: bpf [core], bpf [general] (safe dynamic programs and tools), the rest · Maintainers: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi, Linus Torvalds

bpf_cast_to_kern_ctx() returns a trusted PTR_TO_BTF_ID pointing to the
kernel-side context struct (e.g., sk_buff for TC programs). Passing this
pointer to a kfunc that expects KF_ARG_PTR_TO_CTX fails verification,
because the check accepts only PTR_TO_CTX.

Relax the check to also accept a trusted PTR_TO_BTF_ID whose btf_id matches
the kernel context BTF ID for the program type. Introduce is_kern_ctx_ptr()
to perform this check.

Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com>
---
 kernel/bpf/verifier.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 113e2eaec4db..017071197466 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -6474,6 +6474,27 @@ static bool is_trusted_reg(const struct bpf_reg_state *reg)
 	       !bpf_type_has_unsafe_modifiers(reg->type);
 }
 
+static bool is_kern_ctx_ptr(struct bpf_verifier_env *env,
+			    const struct bpf_reg_state *reg)
+{
+	int kctx_id;
+
+	if (base_type(reg->type) != PTR_TO_BTF_ID)
+		return false;
+	if (!tnum_is_const(reg->var_off))
+		return false;
+	if (!is_trusted_reg(reg))
+		return false;
+
+	kctx_id = get_kern_ctx_btf_id(&env->log, resolve_prog_type(env->prog));
+	if (kctx_id < 0)
+		return false;
+
+	return btf_struct_ids_match(&env->log, reg->btf, reg->btf_id,
+				    reg->var_off.value, btf_vmlinux, kctx_id,
+				    true);
+}
+
 static bool is_rcu_reg(const struct bpf_reg_state *reg)
 {
 	return reg->type & MEM_RCU;
@@ -13495,7 +13516,8 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_
 
 		switch (kf_arg_type) {
 		case KF_ARG_PTR_TO_CTX:
-			if (reg->type != PTR_TO_CTX) {
+			if (reg->type != PTR_TO_CTX &&
+			    !is_kern_ctx_ptr(env, reg)) {
 				verbose(env, "arg#%d expected pointer to ctx, but got %s\n",
 					i, reg_type_str(env, reg->type));
 				return -EINVAL;
-- 
2.43.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help