Skip to content

Commit c8af0a1

Browse files
liu-song-6Kernel Patches Daemon
authored andcommitted
bpf: Use btf_kfunc_id_set.remap logic for bpf_dynptr_from_skb
btf_kfunc_id_set.remap can pick proper version of a kfunc for the calling context. Use this logic to select bpf_dynptr_from_skb or bpf_dynptr_from_skb_rdonly. This will make the verifier simpler. Unfortunately, btf_kfunc_id_set.remap cannot cover the DYNPTR_TYPE_SKB logic in check_kfunc_args(). This can be addressed later. Signed-off-by: Song Liu <song@kernel.org>
1 parent 00a231d commit c8af0a1

File tree

2 files changed

+51
-23
lines changed

2 files changed

+51
-23
lines changed

kernel/bpf/verifier.c

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11677,6 +11677,7 @@ enum special_kfunc_type {
1167711677
KF_bpf_rbtree_add_impl,
1167811678
KF_bpf_rbtree_first,
1167911679
KF_bpf_dynptr_from_skb,
11680+
KF_bpf_dynptr_from_skb_rdonly,
1168011681
KF_bpf_dynptr_from_xdp,
1168111682
KF_bpf_dynptr_slice,
1168211683
KF_bpf_dynptr_slice_rdwr,
@@ -11712,6 +11713,7 @@ BTF_ID(func, bpf_rbtree_add_impl)
1171211713
BTF_ID(func, bpf_rbtree_first)
1171311714
#ifdef CONFIG_NET
1171411715
BTF_ID(func, bpf_dynptr_from_skb)
11716+
BTF_ID(func, bpf_dynptr_from_skb_rdonly)
1171511717
BTF_ID(func, bpf_dynptr_from_xdp)
1171611718
#endif
1171711719
BTF_ID(func, bpf_dynptr_slice)
@@ -11743,10 +11745,12 @@ BTF_ID(func, bpf_rbtree_add_impl)
1174311745
BTF_ID(func, bpf_rbtree_first)
1174411746
#ifdef CONFIG_NET
1174511747
BTF_ID(func, bpf_dynptr_from_skb)
11748+
BTF_ID(func, bpf_dynptr_from_skb_rdonly)
1174611749
BTF_ID(func, bpf_dynptr_from_xdp)
1174711750
#else
1174811751
BTF_ID_UNUSED
1174911752
BTF_ID_UNUSED
11753+
BTF_ID_UNUSED
1175011754
#endif
1175111755
BTF_ID(func, bpf_dynptr_slice)
1175211756
BTF_ID(func, bpf_dynptr_slice_rdwr)
@@ -12668,7 +12672,8 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_
1266812672
if (is_kfunc_arg_uninit(btf, &args[i]))
1266912673
dynptr_arg_type |= MEM_UNINIT;
1267012674

12671-
if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_from_skb]) {
12675+
if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_from_skb] ||
12676+
meta->func_id == special_kfunc_list[KF_bpf_dynptr_from_skb_rdonly]) {
1267212677
dynptr_arg_type |= DYNPTR_TYPE_SKB;
1267312678
} else if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_from_xdp]) {
1267412679
dynptr_arg_type |= DYNPTR_TYPE_XDP;
@@ -20821,9 +20826,7 @@ static void specialize_kfunc(struct bpf_verifier_env *env,
2082120826
u32 func_id, u16 offset, unsigned long *addr)
2082220827
{
2082320828
struct bpf_prog *prog = env->prog;
20824-
bool seen_direct_write;
2082520829
void *xdp_kfunc;
20826-
bool is_rdonly;
2082720830

2082820831
if (bpf_dev_bound_kfunc_id(func_id)) {
2082920832
xdp_kfunc = bpf_dev_bound_resolve_kfunc(prog, func_id);
@@ -20833,22 +20836,6 @@ static void specialize_kfunc(struct bpf_verifier_env *env,
2083320836
}
2083420837
/* fallback to default kfunc when not supported by netdev */
2083520838
}
20836-
20837-
if (offset)
20838-
return;
20839-
20840-
if (func_id == special_kfunc_list[KF_bpf_dynptr_from_skb]) {
20841-
seen_direct_write = env->seen_direct_write;
20842-
is_rdonly = !may_access_direct_pkt_data(env, NULL, BPF_WRITE);
20843-
20844-
if (is_rdonly)
20845-
*addr = (unsigned long)bpf_dynptr_from_skb_rdonly;
20846-
20847-
/* restore env->seen_direct_write to its original value, since
20848-
* may_access_direct_pkt_data mutates it
20849-
*/
20850-
env->seen_direct_write = seen_direct_write;
20851-
}
2085220839
}
2085320840

2085420841
static void __fixup_collection_insert_kfunc(struct bpf_insn_aux_data *insn_aux,

net/core/filter.c

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12047,10 +12047,8 @@ __bpf_kfunc int bpf_sk_assign_tcp_reqsk(struct __sk_buff *s, struct sock *sk,
1204712047
#endif
1204812048
}
1204912049

12050-
__bpf_kfunc_end_defs();
12051-
12052-
int bpf_dynptr_from_skb_rdonly(struct __sk_buff *skb, u64 flags,
12053-
struct bpf_dynptr *ptr__uninit)
12050+
__bpf_kfunc int bpf_dynptr_from_skb_rdonly(struct __sk_buff *skb, u64 flags,
12051+
struct bpf_dynptr *ptr__uninit)
1205412052
{
1205512053
struct bpf_dynptr_kern *ptr = (struct bpf_dynptr_kern *)ptr__uninit;
1205612054
int err;
@@ -12064,10 +12062,16 @@ int bpf_dynptr_from_skb_rdonly(struct __sk_buff *skb, u64 flags,
1206412062
return 0;
1206512063
}
1206612064

12065+
__bpf_kfunc_end_defs();
12066+
1206712067
BTF_KFUNCS_START(bpf_kfunc_check_set_skb)
1206812068
BTF_ID_FLAGS(func, bpf_dynptr_from_skb, KF_TRUSTED_ARGS)
1206912069
BTF_KFUNCS_END(bpf_kfunc_check_set_skb)
1207012070

12071+
BTF_HIDDEN_KFUNCS_START(bpf_kfunc_check_hidden_set_skb)
12072+
BTF_ID_FLAGS(func, bpf_dynptr_from_skb_rdonly, KF_TRUSTED_ARGS)
12073+
BTF_KFUNCS_END(bpf_kfunc_check_hidden_set_skb)
12074+
1207112075
BTF_KFUNCS_START(bpf_kfunc_check_set_xdp)
1207212076
BTF_ID_FLAGS(func, bpf_dynptr_from_xdp)
1207312077
BTF_KFUNCS_END(bpf_kfunc_check_set_xdp)
@@ -12080,9 +12084,46 @@ BTF_KFUNCS_START(bpf_kfunc_check_set_tcp_reqsk)
1208012084
BTF_ID_FLAGS(func, bpf_sk_assign_tcp_reqsk, KF_TRUSTED_ARGS)
1208112085
BTF_KFUNCS_END(bpf_kfunc_check_set_tcp_reqsk)
1208212086

12087+
BTF_ID_LIST(bpf_dynptr_from_skb_list)
12088+
BTF_ID(func, bpf_dynptr_from_skb)
12089+
BTF_ID(func, bpf_dynptr_from_skb_rdonly)
12090+
12091+
static u32 bpf_kfunc_set_skb_remap(const struct bpf_prog *prog, u32 kfunc_id)
12092+
{
12093+
if (kfunc_id != bpf_dynptr_from_skb_list[0])
12094+
return 0;
12095+
12096+
switch (resolve_prog_type(prog)) {
12097+
/* Program types only with direct read access go here! */
12098+
case BPF_PROG_TYPE_LWT_IN:
12099+
case BPF_PROG_TYPE_LWT_OUT:
12100+
case BPF_PROG_TYPE_LWT_SEG6LOCAL:
12101+
case BPF_PROG_TYPE_SK_REUSEPORT:
12102+
case BPF_PROG_TYPE_FLOW_DISSECTOR:
12103+
case BPF_PROG_TYPE_CGROUP_SKB:
12104+
return bpf_dynptr_from_skb_list[1];
12105+
12106+
/* Program types with direct read + write access go here! */
12107+
case BPF_PROG_TYPE_SCHED_CLS:
12108+
case BPF_PROG_TYPE_SCHED_ACT:
12109+
case BPF_PROG_TYPE_XDP:
12110+
case BPF_PROG_TYPE_LWT_XMIT:
12111+
case BPF_PROG_TYPE_SK_SKB:
12112+
case BPF_PROG_TYPE_SK_MSG:
12113+
case BPF_PROG_TYPE_CGROUP_SOCKOPT:
12114+
return kfunc_id;
12115+
12116+
default:
12117+
break;
12118+
}
12119+
return bpf_dynptr_from_skb_list[1];
12120+
}
12121+
1208312122
static const struct btf_kfunc_id_set bpf_kfunc_set_skb = {
1208412123
.owner = THIS_MODULE,
1208512124
.set = &bpf_kfunc_check_set_skb,
12125+
.hidden_set = &bpf_kfunc_check_hidden_set_skb,
12126+
.remap = &bpf_kfunc_set_skb_remap,
1208612127
};
1208712128

1208812129
static const struct btf_kfunc_id_set bpf_kfunc_set_xdp = {

0 commit comments

Comments
 (0)