Skip to content

Commit 7de16e3

Browse files
Jakub Kicinskidavem330
authored andcommitted
bpf: split verifier and program ops
struct bpf_verifier_ops contains both verifier ops and operations used later during program's lifetime (test_run). Split the runtime ops into a different structure. BPF_PROG_TYPE() will now append ## _prog_ops or ## _verifier_ops to the names. Signed-off-by: Jakub Kicinski <[email protected]> Acked-by: Daniel Borkmann <[email protected]> Acked-by: Alexei Starovoitov <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 386fd5d commit 7de16e3

File tree

6 files changed

+91
-40
lines changed

6 files changed

+91
-40
lines changed

include/linux/bpf.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,11 @@ bpf_ctx_record_field_size(struct bpf_insn_access_aux *aux, u32 size)
157157
aux->ctx_field_size = size;
158158
}
159159

160+
struct bpf_prog_ops {
161+
int (*test_run)(struct bpf_prog *prog, const union bpf_attr *kattr,
162+
union bpf_attr __user *uattr);
163+
};
164+
160165
struct bpf_verifier_ops {
161166
/* return eBPF function prototype for verification */
162167
const struct bpf_func_proto *(*get_func_proto)(enum bpf_func_id func_id);
@@ -172,8 +177,6 @@ struct bpf_verifier_ops {
172177
const struct bpf_insn *src,
173178
struct bpf_insn *dst,
174179
struct bpf_prog *prog, u32 *target_size);
175-
int (*test_run)(struct bpf_prog *prog, const union bpf_attr *kattr,
176-
union bpf_attr __user *uattr);
177180
};
178181

179182
struct bpf_prog_aux {
@@ -184,7 +187,8 @@ struct bpf_prog_aux {
184187
u32 id;
185188
struct latch_tree_node ksym_tnode;
186189
struct list_head ksym_lnode;
187-
const struct bpf_verifier_ops *ops;
190+
const struct bpf_prog_ops *ops;
191+
const struct bpf_verifier_ops *vops;
188192
struct bpf_map **used_maps;
189193
struct bpf_prog *prog;
190194
struct user_struct *user;
@@ -279,8 +283,9 @@ int bpf_prog_array_copy_to_user(struct bpf_prog_array __rcu *progs,
279283
#ifdef CONFIG_BPF_SYSCALL
280284
DECLARE_PER_CPU(int, bpf_prog_active);
281285

282-
#define BPF_PROG_TYPE(_id, _ops) \
283-
extern const struct bpf_verifier_ops _ops;
286+
#define BPF_PROG_TYPE(_id, _name) \
287+
extern const struct bpf_prog_ops _name ## _prog_ops; \
288+
extern const struct bpf_verifier_ops _name ## _verifier_ops;
284289
#define BPF_MAP_TYPE(_id, _ops) \
285290
extern const struct bpf_map_ops _ops;
286291
#include <linux/bpf_types.h>

include/linux/bpf_types.h

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
/* internal file - do not include directly */
22

33
#ifdef CONFIG_NET
4-
BPF_PROG_TYPE(BPF_PROG_TYPE_SOCKET_FILTER, sk_filter_prog_ops)
5-
BPF_PROG_TYPE(BPF_PROG_TYPE_SCHED_CLS, tc_cls_act_prog_ops)
6-
BPF_PROG_TYPE(BPF_PROG_TYPE_SCHED_ACT, tc_cls_act_prog_ops)
7-
BPF_PROG_TYPE(BPF_PROG_TYPE_XDP, xdp_prog_ops)
8-
BPF_PROG_TYPE(BPF_PROG_TYPE_CGROUP_SKB, cg_skb_prog_ops)
9-
BPF_PROG_TYPE(BPF_PROG_TYPE_CGROUP_SOCK, cg_sock_prog_ops)
10-
BPF_PROG_TYPE(BPF_PROG_TYPE_LWT_IN, lwt_inout_prog_ops)
11-
BPF_PROG_TYPE(BPF_PROG_TYPE_LWT_OUT, lwt_inout_prog_ops)
12-
BPF_PROG_TYPE(BPF_PROG_TYPE_LWT_XMIT, lwt_xmit_prog_ops)
13-
BPF_PROG_TYPE(BPF_PROG_TYPE_SOCK_OPS, sock_ops_prog_ops)
14-
BPF_PROG_TYPE(BPF_PROG_TYPE_SK_SKB, sk_skb_prog_ops)
4+
BPF_PROG_TYPE(BPF_PROG_TYPE_SOCKET_FILTER, sk_filter)
5+
BPF_PROG_TYPE(BPF_PROG_TYPE_SCHED_CLS, tc_cls_act)
6+
BPF_PROG_TYPE(BPF_PROG_TYPE_SCHED_ACT, tc_cls_act)
7+
BPF_PROG_TYPE(BPF_PROG_TYPE_XDP, xdp)
8+
BPF_PROG_TYPE(BPF_PROG_TYPE_CGROUP_SKB, cg_skb)
9+
BPF_PROG_TYPE(BPF_PROG_TYPE_CGROUP_SOCK, cg_sock)
10+
BPF_PROG_TYPE(BPF_PROG_TYPE_LWT_IN, lwt_inout)
11+
BPF_PROG_TYPE(BPF_PROG_TYPE_LWT_OUT, lwt_inout)
12+
BPF_PROG_TYPE(BPF_PROG_TYPE_LWT_XMIT, lwt_xmit)
13+
BPF_PROG_TYPE(BPF_PROG_TYPE_SOCK_OPS, sock_ops)
14+
BPF_PROG_TYPE(BPF_PROG_TYPE_SK_SKB, sk_skb)
1515
#endif
1616
#ifdef CONFIG_BPF_EVENTS
17-
BPF_PROG_TYPE(BPF_PROG_TYPE_KPROBE, kprobe_prog_ops)
18-
BPF_PROG_TYPE(BPF_PROG_TYPE_TRACEPOINT, tracepoint_prog_ops)
19-
BPF_PROG_TYPE(BPF_PROG_TYPE_PERF_EVENT, perf_event_prog_ops)
17+
BPF_PROG_TYPE(BPF_PROG_TYPE_KPROBE, kprobe)
18+
BPF_PROG_TYPE(BPF_PROG_TYPE_TRACEPOINT, tracepoint)
19+
BPF_PROG_TYPE(BPF_PROG_TYPE_PERF_EVENT, perf_event)
2020
#endif
2121

2222
BPF_MAP_TYPE(BPF_MAP_TYPE_ARRAY, array_map_ops)

kernel/bpf/syscall.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -739,9 +739,18 @@ static int map_get_next_key(union bpf_attr *attr)
739739
return err;
740740
}
741741

742-
static const struct bpf_verifier_ops * const bpf_prog_types[] = {
743-
#define BPF_PROG_TYPE(_id, _ops) \
744-
[_id] = &_ops,
742+
static const struct bpf_prog_ops * const bpf_prog_types[] = {
743+
#define BPF_PROG_TYPE(_id, _name) \
744+
[_id] = & _name ## _prog_ops,
745+
#define BPF_MAP_TYPE(_id, _ops)
746+
#include <linux/bpf_types.h>
747+
#undef BPF_PROG_TYPE
748+
#undef BPF_MAP_TYPE
749+
};
750+
751+
static const struct bpf_verifier_ops * const bpf_verifier_ops[] = {
752+
#define BPF_PROG_TYPE(_id, _name) \
753+
[_id] = & _name ## _verifier_ops,
745754
#define BPF_MAP_TYPE(_id, _ops)
746755
#include <linux/bpf_types.h>
747756
#undef BPF_PROG_TYPE
@@ -754,6 +763,7 @@ static int find_prog_type(enum bpf_prog_type type, struct bpf_prog *prog)
754763
return -EINVAL;
755764

756765
prog->aux->ops = bpf_prog_types[type];
766+
prog->aux->vops = bpf_verifier_ops[type];
757767
prog->type = type;
758768
return 0;
759769
}

kernel/bpf/verifier.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -856,8 +856,8 @@ static int check_ctx_access(struct bpf_verifier_env *env, int insn_idx, int off,
856856
*reg_type = info.reg_type;
857857
return 0;
858858
}
859-
} else if (env->prog->aux->ops->is_valid_access &&
860-
env->prog->aux->ops->is_valid_access(off, size, t, &info)) {
859+
} else if (env->prog->aux->vops->is_valid_access &&
860+
env->prog->aux->vops->is_valid_access(off, size, t, &info)) {
861861
/* A non zero info.ctx_field_size indicates that this field is a
862862
* candidate for later verifier transformation to load the whole
863863
* field and then apply a mask when accessed with a narrower
@@ -1565,8 +1565,8 @@ static int check_call(struct bpf_verifier_env *env, int func_id, int insn_idx)
15651565
return -EINVAL;
15661566
}
15671567

1568-
if (env->prog->aux->ops->get_func_proto)
1569-
fn = env->prog->aux->ops->get_func_proto(func_id);
1568+
if (env->prog->aux->vops->get_func_proto)
1569+
fn = env->prog->aux->vops->get_func_proto(func_id);
15701570

15711571
if (!fn) {
15721572
verbose(env, "unknown func %s#%d\n", func_id_name(func_id),
@@ -4035,7 +4035,7 @@ static struct bpf_prog *bpf_patch_insn_data(struct bpf_verifier_env *env, u32 of
40354035
*/
40364036
static int convert_ctx_accesses(struct bpf_verifier_env *env)
40374037
{
4038-
const struct bpf_verifier_ops *ops = env->prog->aux->ops;
4038+
const struct bpf_verifier_ops *ops = env->prog->aux->vops;
40394039
int i, cnt, size, ctx_field_size, delta = 0;
40404040
const int insn_cnt = env->prog->len;
40414041
struct bpf_insn insn_buf[16], *insn;
@@ -4236,7 +4236,7 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
42364236
insn = new_prog->insnsi + i + delta;
42374237
}
42384238
patch_call_imm:
4239-
fn = prog->aux->ops->get_func_proto(insn->imm);
4239+
fn = prog->aux->vops->get_func_proto(insn->imm);
42404240
/* all functions that have prototype and verifier allowed
42414241
* programs to call them, must be real in-kernel functions
42424242
*/

kernel/trace/bpf_trace.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -561,11 +561,14 @@ static bool kprobe_prog_is_valid_access(int off, int size, enum bpf_access_type
561561
return true;
562562
}
563563

564-
const struct bpf_verifier_ops kprobe_prog_ops = {
564+
const struct bpf_verifier_ops kprobe_verifier_ops = {
565565
.get_func_proto = kprobe_prog_func_proto,
566566
.is_valid_access = kprobe_prog_is_valid_access,
567567
};
568568

569+
const struct bpf_prog_ops kprobe_prog_ops = {
570+
};
571+
569572
BPF_CALL_5(bpf_perf_event_output_tp, void *, tp_buff, struct bpf_map *, map,
570573
u64, flags, void *, data, u64, size)
571574
{
@@ -667,11 +670,14 @@ static bool tp_prog_is_valid_access(int off, int size, enum bpf_access_type type
667670
return true;
668671
}
669672

670-
const struct bpf_verifier_ops tracepoint_prog_ops = {
673+
const struct bpf_verifier_ops tracepoint_verifier_ops = {
671674
.get_func_proto = tp_prog_func_proto,
672675
.is_valid_access = tp_prog_is_valid_access,
673676
};
674677

678+
const struct bpf_prog_ops tracepoint_prog_ops = {
679+
};
680+
675681
static bool pe_prog_is_valid_access(int off, int size, enum bpf_access_type type,
676682
struct bpf_insn_access_aux *info)
677683
{
@@ -727,8 +733,11 @@ static u32 pe_prog_convert_ctx_access(enum bpf_access_type type,
727733
return insn - insn_buf;
728734
}
729735

730-
const struct bpf_verifier_ops perf_event_prog_ops = {
736+
const struct bpf_verifier_ops perf_event_verifier_ops = {
731737
.get_func_proto = tp_prog_func_proto,
732738
.is_valid_access = pe_prog_is_valid_access,
733739
.convert_ctx_access = pe_prog_convert_ctx_access,
734740
};
741+
742+
const struct bpf_prog_ops perf_event_prog_ops = {
743+
};

net/core/filter.c

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4395,68 +4395,95 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
43954395
return insn - insn_buf;
43964396
}
43974397

4398-
const struct bpf_verifier_ops sk_filter_prog_ops = {
4398+
const struct bpf_verifier_ops sk_filter_verifier_ops = {
43994399
.get_func_proto = sk_filter_func_proto,
44004400
.is_valid_access = sk_filter_is_valid_access,
44014401
.convert_ctx_access = bpf_convert_ctx_access,
44024402
};
44034403

4404-
const struct bpf_verifier_ops tc_cls_act_prog_ops = {
4404+
const struct bpf_prog_ops sk_filter_prog_ops = {
4405+
};
4406+
4407+
const struct bpf_verifier_ops tc_cls_act_verifier_ops = {
44054408
.get_func_proto = tc_cls_act_func_proto,
44064409
.is_valid_access = tc_cls_act_is_valid_access,
44074410
.convert_ctx_access = tc_cls_act_convert_ctx_access,
44084411
.gen_prologue = tc_cls_act_prologue,
4412+
};
4413+
4414+
const struct bpf_prog_ops tc_cls_act_prog_ops = {
44094415
.test_run = bpf_prog_test_run_skb,
44104416
};
44114417

4412-
const struct bpf_verifier_ops xdp_prog_ops = {
4418+
const struct bpf_verifier_ops xdp_verifier_ops = {
44134419
.get_func_proto = xdp_func_proto,
44144420
.is_valid_access = xdp_is_valid_access,
44154421
.convert_ctx_access = xdp_convert_ctx_access,
4422+
};
4423+
4424+
const struct bpf_prog_ops xdp_prog_ops = {
44164425
.test_run = bpf_prog_test_run_xdp,
44174426
};
44184427

4419-
const struct bpf_verifier_ops cg_skb_prog_ops = {
4428+
const struct bpf_verifier_ops cg_skb_verifier_ops = {
44204429
.get_func_proto = sk_filter_func_proto,
44214430
.is_valid_access = sk_filter_is_valid_access,
44224431
.convert_ctx_access = bpf_convert_ctx_access,
4432+
};
4433+
4434+
const struct bpf_prog_ops cg_skb_prog_ops = {
44234435
.test_run = bpf_prog_test_run_skb,
44244436
};
44254437

4426-
const struct bpf_verifier_ops lwt_inout_prog_ops = {
4438+
const struct bpf_verifier_ops lwt_inout_verifier_ops = {
44274439
.get_func_proto = lwt_inout_func_proto,
44284440
.is_valid_access = lwt_is_valid_access,
44294441
.convert_ctx_access = bpf_convert_ctx_access,
4442+
};
4443+
4444+
const struct bpf_prog_ops lwt_inout_prog_ops = {
44304445
.test_run = bpf_prog_test_run_skb,
44314446
};
44324447

4433-
const struct bpf_verifier_ops lwt_xmit_prog_ops = {
4448+
const struct bpf_verifier_ops lwt_xmit_verifier_ops = {
44344449
.get_func_proto = lwt_xmit_func_proto,
44354450
.is_valid_access = lwt_is_valid_access,
44364451
.convert_ctx_access = bpf_convert_ctx_access,
44374452
.gen_prologue = tc_cls_act_prologue,
4453+
};
4454+
4455+
const struct bpf_prog_ops lwt_xmit_prog_ops = {
44384456
.test_run = bpf_prog_test_run_skb,
44394457
};
44404458

4441-
const struct bpf_verifier_ops cg_sock_prog_ops = {
4459+
const struct bpf_verifier_ops cg_sock_verifier_ops = {
44424460
.get_func_proto = sock_filter_func_proto,
44434461
.is_valid_access = sock_filter_is_valid_access,
44444462
.convert_ctx_access = sock_filter_convert_ctx_access,
44454463
};
44464464

4447-
const struct bpf_verifier_ops sock_ops_prog_ops = {
4465+
const struct bpf_prog_ops cg_sock_prog_ops = {
4466+
};
4467+
4468+
const struct bpf_verifier_ops sock_ops_verifier_ops = {
44484469
.get_func_proto = sock_ops_func_proto,
44494470
.is_valid_access = sock_ops_is_valid_access,
44504471
.convert_ctx_access = sock_ops_convert_ctx_access,
44514472
};
44524473

4453-
const struct bpf_verifier_ops sk_skb_prog_ops = {
4474+
const struct bpf_prog_ops sock_ops_prog_ops = {
4475+
};
4476+
4477+
const struct bpf_verifier_ops sk_skb_verifier_ops = {
44544478
.get_func_proto = sk_skb_func_proto,
44554479
.is_valid_access = sk_skb_is_valid_access,
44564480
.convert_ctx_access = bpf_convert_ctx_access,
44574481
.gen_prologue = sk_skb_prologue,
44584482
};
44594483

4484+
const struct bpf_prog_ops sk_skb_prog_ops = {
4485+
};
4486+
44604487
int sk_detach_filter(struct sock *sk)
44614488
{
44624489
int ret = -ENOENT;

0 commit comments

Comments
 (0)