[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250220134503.835224-2-maciej.fijalkowski@intel.com>
Date: Thu, 20 Feb 2025 14:45:01 +0100
From: Maciej Fijalkowski <maciej.fijalkowski@...el.com>
To: bpf@...r.kernel.org,
ast@...nel.org,
daniel@...earbox.net,
andrii@...nel.org
Cc: netdev@...r.kernel.org,
magnus.karlsson@...el.com,
martin.lau@...ux.dev,
Maciej Fijalkowski <maciej.fijalkowski@...el.com>
Subject: [PATCH bpf-next 1/3] bpf: call btf_is_projection_of() conditionally
Currently verifier thinks when sk_buff is used as kfunc's argument it is
coming as pointer to context (KF_ARG_PTR_TO_CTX) but in kfuncs that are
going to be introduced for sk_buff's refcount handling we want it to be
interpreted as KF_ARG_PTR_TO_BTF_ID.
Make it possible by calling btf_is_projection_of() conditionally.
Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@...el.com>
---
include/linux/btf.h | 4 ++--
kernel/bpf/btf.c | 11 ++++++-----
kernel/bpf/verifier.c | 3 ++-
3 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/include/linux/btf.h b/include/linux/btf.h
index ebc0c0c9b944..1307ea17542a 100644
--- a/include/linux/btf.h
+++ b/include/linux/btf.h
@@ -585,7 +585,7 @@ struct btf_struct_meta *btf_find_struct_meta(const struct btf *btf, u32 btf_id);
bool btf_is_projection_of(const char *pname, const char *tname);
bool btf_is_prog_ctx_type(struct bpf_verifier_log *log, const struct btf *btf,
const struct btf_type *t, enum bpf_prog_type prog_type,
- int arg);
+ int arg, bool check_proj);
int get_kern_ctx_btf_id(struct bpf_verifier_log *log, enum bpf_prog_type prog_type);
bool btf_types_are_same(const struct btf *btf1, u32 id1,
const struct btf *btf2, u32 id2);
@@ -661,7 +661,7 @@ static inline struct btf_struct_meta *btf_find_struct_meta(const struct btf *btf
static inline bool
btf_is_prog_ctx_type(struct bpf_verifier_log *log, const struct btf *btf,
const struct btf_type *t, enum bpf_prog_type prog_type,
- int arg)
+ int arg, bool check_proj)
{
return false;
}
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 69f5752e880b..62bdf6980cfb 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -5909,7 +5909,7 @@ bool btf_is_projection_of(const char *pname, const char *tname)
bool btf_is_prog_ctx_type(struct bpf_verifier_log *log, const struct btf *btf,
const struct btf_type *t, enum bpf_prog_type prog_type,
- int arg)
+ int arg, bool check_proj)
{
const struct btf_type *ctx_type;
const char *tname, *ctx_tname;
@@ -5969,8 +5969,9 @@ bool btf_is_prog_ctx_type(struct bpf_verifier_log *log, const struct btf *btf,
* int socket_filter_bpf_prog(struct __sk_buff *skb)
* { // no fields of skb are ever used }
*/
- if (btf_is_projection_of(ctx_tname, tname))
- return true;
+ if (check_proj)
+ if (btf_is_projection_of(ctx_tname, tname))
+ return true;
if (strcmp(ctx_tname, tname)) {
/* bpf_user_pt_regs_t is a typedef, so resolve it to
* underlying struct and check name again
@@ -6133,7 +6134,7 @@ static int btf_translate_to_vmlinux(struct bpf_verifier_log *log,
enum bpf_prog_type prog_type,
int arg)
{
- if (!btf_is_prog_ctx_type(log, btf, t, prog_type, arg))
+ if (!btf_is_prog_ctx_type(log, btf, t, prog_type, arg, true))
return -ENOENT;
return find_kern_ctx_type_id(prog_type);
}
@@ -7739,7 +7740,7 @@ int btf_prepare_func_args(struct bpf_verifier_env *env, int subprog)
if (!btf_type_is_ptr(t))
goto skip_pointer;
- if ((tags & ARG_TAG_CTX) || btf_is_prog_ctx_type(log, btf, t, prog_type, i)) {
+ if ((tags & ARG_TAG_CTX) || btf_is_prog_ctx_type(log, btf, t, prog_type, i, true)) {
if (tags & ~ARG_TAG_CTX) {
bpf_log(log, "arg#%d has invalid combination of tags\n", i);
return -EINVAL;
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index e57b7c949860..6492bfa4bc7a 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -11997,7 +11997,8 @@ get_kfunc_ptr_arg_type(struct bpf_verifier_env *env,
* type to our caller. When a set of conditions hold in the BTF type of
* arguments, we resolve it to a known kfunc_ptr_arg_type.
*/
- if (btf_is_prog_ctx_type(&env->log, meta->btf, t, resolve_prog_type(env->prog), argno))
+ if (btf_is_prog_ctx_type(&env->log, meta->btf, t, resolve_prog_type(env->prog),
+ argno, false))
return KF_ARG_PTR_TO_CTX;
if (is_kfunc_arg_nullable(meta->btf, &args[argno]) && register_is_null(reg))
--
2.43.0
Powered by blists - more mailing lists