Skip to content

Commit e67bfbc

Browse files
mykyta5Kernel Patches Daemon
authored andcommitted
bpf: introduce kfunc flags for dynptr types
The verifier currently special-cases dynptr initialization kfuncs to set the correct dynptr type for an uninitialized argument. This patch moves that logic into kfunc metadata. Introduce KF_DYNPTR_* kfunc flags and a helper, dynptr_type_from_kfunc_flags(), which translates those flags into the appropriate DYNPTR_TYPE_* mask. With the type encoded in the kfunc declaration, the verifier no longer needs explicit checks for bpf_dynptr_from_xdp(), bpf_dynptr_from_skb(), and bpf_dynptr_from_skb_meta(). This simplifies the verifier and centralizes dynptr typing in kfunc declarations, with no user-visible behavior change. Signed-off-by: Mykyta Yatsenko <[email protected]> Acked-by: Eduard Zingerman <[email protected]>
1 parent acca942 commit e67bfbc

File tree

3 files changed

+29
-11
lines changed

3 files changed

+29
-11
lines changed

include/linux/btf.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@
7979
#define KF_ARENA_RET (1 << 13) /* kfunc returns an arena pointer */
8080
#define KF_ARENA_ARG1 (1 << 14) /* kfunc takes an arena pointer as its first argument */
8181
#define KF_ARENA_ARG2 (1 << 15) /* kfunc takes an arena pointer as its second argument */
82+
#define KF_DYNPTR_XDP (1 << 16) /* kfunc takes dynptr to XDP */
83+
#define KF_DYNPTR_SKB (1 << 17) /* kfunc takes dynptr to SKB */
84+
#define KF_DYNPTR_SKB_META (1 << 18) /* kfunc takes dynptr to SKB metadata */
8285

8386
/*
8487
* Tag marking a kernel function as a kfunc. This is meant to minimize the

kernel/bpf/verifier.c

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2297,6 +2297,25 @@ static bool reg_is_dynptr_slice_pkt(const struct bpf_reg_state *reg)
22972297
(DYNPTR_TYPE_SKB | DYNPTR_TYPE_XDP | DYNPTR_TYPE_SKB_META));
22982298
}
22992299

2300+
static u64 dynptr_type_from_kfunc_flags(const struct bpf_kfunc_call_arg_meta *meta)
2301+
{
2302+
static const struct {
2303+
u64 mask;
2304+
enum bpf_type_flag type;
2305+
} type_flags[] = {
2306+
{ KF_DYNPTR_SKB, DYNPTR_TYPE_SKB },
2307+
{ KF_DYNPTR_XDP, DYNPTR_TYPE_XDP },
2308+
{ KF_DYNPTR_SKB_META, DYNPTR_TYPE_SKB_META },
2309+
};
2310+
int i;
2311+
2312+
for (i = 0; i < ARRAY_SIZE(type_flags); ++i) {
2313+
if (type_flags[i].mask & meta->kfunc_flags)
2314+
return type_flags[i].type;
2315+
}
2316+
return 0;
2317+
}
2318+
23002319
/* Unmodified PTR_TO_PACKET[_META,_END] register from ctx access. */
23012320
static bool reg_is_init_pkt_pointer(const struct bpf_reg_state *reg,
23022321
enum bpf_reg_type which)
@@ -13277,14 +13296,10 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_
1327713296
if (is_kfunc_arg_uninit(btf, &args[i]))
1327813297
dynptr_arg_type |= MEM_UNINIT;
1327913298

13280-
if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_from_skb]) {
13281-
dynptr_arg_type |= DYNPTR_TYPE_SKB;
13282-
} else if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_from_xdp]) {
13283-
dynptr_arg_type |= DYNPTR_TYPE_XDP;
13284-
} else if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_from_skb_meta]) {
13285-
dynptr_arg_type |= DYNPTR_TYPE_SKB_META;
13286-
} else if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_clone] &&
13287-
(dynptr_arg_type & MEM_UNINIT)) {
13299+
dynptr_arg_type |= dynptr_type_from_kfunc_flags(meta);
13300+
13301+
if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_clone] &&
13302+
(dynptr_arg_type & MEM_UNINIT)) {
1328813303
enum bpf_dynptr_type parent_type = meta->initialized_dynptr.type;
1328913304

1329013305
if (parent_type == BPF_DYNPTR_TYPE_INVALID) {

net/core/filter.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12228,15 +12228,15 @@ int bpf_dynptr_from_skb_rdonly(struct __sk_buff *skb, u64 flags,
1222812228
}
1222912229

1223012230
BTF_KFUNCS_START(bpf_kfunc_check_set_skb)
12231-
BTF_ID_FLAGS(func, bpf_dynptr_from_skb, KF_TRUSTED_ARGS)
12231+
BTF_ID_FLAGS(func, bpf_dynptr_from_skb, KF_TRUSTED_ARGS | KF_DYNPTR_SKB)
1223212232
BTF_KFUNCS_END(bpf_kfunc_check_set_skb)
1223312233

1223412234
BTF_KFUNCS_START(bpf_kfunc_check_set_skb_meta)
12235-
BTF_ID_FLAGS(func, bpf_dynptr_from_skb_meta, KF_TRUSTED_ARGS)
12235+
BTF_ID_FLAGS(func, bpf_dynptr_from_skb_meta, KF_TRUSTED_ARGS | KF_DYNPTR_SKB_META)
1223612236
BTF_KFUNCS_END(bpf_kfunc_check_set_skb_meta)
1223712237

1223812238
BTF_KFUNCS_START(bpf_kfunc_check_set_xdp)
12239-
BTF_ID_FLAGS(func, bpf_dynptr_from_xdp)
12239+
BTF_ID_FLAGS(func, bpf_dynptr_from_xdp, KF_DYNPTR_XDP)
1224012240
BTF_KFUNCS_END(bpf_kfunc_check_set_xdp)
1224112241

1224212242
BTF_KFUNCS_START(bpf_kfunc_check_set_sock_addr)

0 commit comments

Comments
 (0)