Skip to content

Commit c464a3d

Browse files
Jakub KicinskiSomasundaram Krishnasamy
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]> (cherry picked from commit 7de16e3) Orabug: 31667601 Signed-off-by: Alan Maguire <[email protected]> Reviewed-by: Mark Haywood <[email protected]> Conflicts: include/linux/bpf.h KABI replace/extend for splitting ops into verifier and prog ops Signed-off-by: Somasundaram Krishnasamy <[email protected]>
1 parent 1980920 commit c464a3d

File tree

6 files changed

+92
-40
lines changed

6 files changed

+92
-40
lines changed

include/linux/bpf.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@ bpf_ctx_record_field_size(struct bpf_insn_access_aux *aux, u32 size)
167167
aux->ctx_field_size = size;
168168
}
169169

170+
struct bpf_prog_ops {
171+
int (*test_run)(struct bpf_prog *prog, const union bpf_attr *kattr,
172+
union bpf_attr __user *uattr);
173+
};
174+
170175
struct bpf_verifier_ops {
171176
/* return eBPF function prototype for verification */
172177
const struct bpf_func_proto *(*get_func_proto)(enum bpf_func_id func_id);
@@ -182,8 +187,6 @@ struct bpf_verifier_ops {
182187
const struct bpf_insn *src,
183188
struct bpf_insn *dst,
184189
struct bpf_prog *prog, u32 *target_size);
185-
int (*test_run)(struct bpf_prog *prog, const union bpf_attr *kattr,
186-
union bpf_attr __user *uattr);
187190
};
188191

189192
struct bpf_prog_aux {
@@ -194,14 +197,16 @@ struct bpf_prog_aux {
194197
u32 id;
195198
struct latch_tree_node ksym_tnode;
196199
struct list_head ksym_lnode;
197-
const struct bpf_verifier_ops *ops;
200+
UEK_KABI_REPLACE(const struct bpf_verifier_ops *ops,
201+
const struct bpf_prog_ops *ops)
198202
struct bpf_map **used_maps;
199203
struct bpf_prog *prog;
200204
struct user_struct *user;
201205
union {
202206
struct work_struct work;
203207
struct rcu_head rcu;
204208
};
209+
UEK_KABI_EXTEND(const struct bpf_verifier_ops *vops)
205210
};
206211

207212
struct bpf_array {
@@ -288,8 +293,9 @@ int bpf_prog_array_copy_to_user(struct bpf_prog_array __rcu *progs,
288293
#ifdef CONFIG_BPF_SYSCALL
289294
DECLARE_PER_CPU(int, bpf_prog_active);
290295

291-
#define BPF_PROG_TYPE(_id, _ops) \
292-
extern const struct bpf_verifier_ops _ops;
296+
#define BPF_PROG_TYPE(_id, _name) \
297+
extern const struct bpf_prog_ops _name ## _prog_ops; \
298+
extern const struct bpf_verifier_ops _name ## _verifier_ops;
293299
#define BPF_MAP_TYPE(_id, _ops) \
294300
extern const struct bpf_map_ops _ops;
295301
#include <linux/bpf_types.h>

include/linux/bpf_types.h

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

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

2323
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
@@ -716,9 +716,18 @@ static int map_get_next_key(union bpf_attr *attr)
716716
return err;
717717
}
718718

719-
static const struct bpf_verifier_ops * const bpf_prog_types[] = {
720-
#define BPF_PROG_TYPE(_id, _ops) \
721-
[_id] = &_ops,
719+
static const struct bpf_prog_ops * const bpf_prog_types[] = {
720+
#define BPF_PROG_TYPE(_id, _name) \
721+
[_id] = & _name ## _prog_ops,
722+
#define BPF_MAP_TYPE(_id, _ops)
723+
#include <linux/bpf_types.h>
724+
#undef BPF_PROG_TYPE
725+
#undef BPF_MAP_TYPE
726+
};
727+
728+
static const struct bpf_verifier_ops * const bpf_verifier_ops[] = {
729+
#define BPF_PROG_TYPE(_id, _name) \
730+
[_id] = & _name ## _verifier_ops,
722731
#define BPF_MAP_TYPE(_id, _ops)
723732
#include <linux/bpf_types.h>
724733
#undef BPF_PROG_TYPE
@@ -731,6 +740,7 @@ static int find_prog_type(enum bpf_prog_type type, struct bpf_prog *prog)
731740
return -EINVAL;
732741

733742
prog->aux->ops = bpf_prog_types[type];
743+
prog->aux->vops = bpf_verifier_ops[type];
734744
prog->type = type;
735745
return 0;
736746
}

kernel/bpf/verifier.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,8 +1145,8 @@ static int check_ctx_access(struct bpf_verifier_env *env, int insn_idx, int off,
11451145
*reg_type = info.reg_type;
11461146
return 0;
11471147
}
1148-
} else if (env->prog->aux->ops->is_valid_access &&
1149-
env->prog->aux->ops->is_valid_access(off, size, t, &info)) {
1148+
} else if (env->prog->aux->vops->is_valid_access &&
1149+
env->prog->aux->vops->is_valid_access(off, size, t, &info)) {
11501150
/* A non zero info.ctx_field_size indicates that this field is a
11511151
* candidate for later verifier transformation to load the whole
11521152
* field and then apply a mask when accessed with a narrower
@@ -1882,8 +1882,8 @@ static int check_call(struct bpf_verifier_env *env, int func_id, int insn_idx)
18821882
return -EINVAL;
18831883
}
18841884

1885-
if (env->prog->aux->ops->get_func_proto)
1886-
fn = env->prog->aux->ops->get_func_proto(func_id);
1885+
if (env->prog->aux->vops->get_func_proto)
1886+
fn = env->prog->aux->vops->get_func_proto(func_id);
18871887

18881888
if (!fn) {
18891889
verbose("unknown func %s#%d\n", func_id_name(func_id), func_id);
@@ -4607,7 +4607,7 @@ static void sanitize_dead_code(struct bpf_verifier_env *env)
46074607
*/
46084608
static int convert_ctx_accesses(struct bpf_verifier_env *env)
46094609
{
4610-
const struct bpf_verifier_ops *ops = env->prog->aux->ops;
4610+
const struct bpf_verifier_ops *ops = env->prog->aux->vops;
46114611
int i, cnt, size, ctx_field_size, delta = 0;
46124612
const int insn_cnt = env->prog->len;
46134613
struct bpf_insn insn_buf[16], *insn;
@@ -4936,7 +4936,7 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
49364936
insn = new_prog->insnsi + i + delta;
49374937
}
49384938
patch_call_imm:
4939-
fn = prog->aux->ops->get_func_proto(insn->imm);
4939+
fn = prog->aux->vops->get_func_proto(insn->imm);
49404940
/* all functions that have prototype and verifier allowed
49414941
* programs to call them, must be real in-kernel functions
49424942
*/

kernel/trace/bpf_trace.c

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

534-
const struct bpf_verifier_ops kprobe_prog_ops = {
534+
const struct bpf_verifier_ops kprobe_verifier_ops = {
535535
.get_func_proto = kprobe_prog_func_proto,
536536
.is_valid_access = kprobe_prog_is_valid_access,
537537
};
538538

539+
const struct bpf_prog_ops kprobe_prog_ops = {
540+
};
541+
539542
BPF_CALL_5(bpf_perf_event_output_tp, void *, tp_buff, struct bpf_map *, map,
540543
u64, flags, void *, data, u64, size)
541544
{
@@ -609,11 +612,14 @@ static bool tp_prog_is_valid_access(int off, int size, enum bpf_access_type type
609612
return true;
610613
}
611614

612-
const struct bpf_verifier_ops tracepoint_prog_ops = {
615+
const struct bpf_verifier_ops tracepoint_verifier_ops = {
613616
.get_func_proto = tp_prog_func_proto,
614617
.is_valid_access = tp_prog_is_valid_access,
615618
};
616619

620+
const struct bpf_prog_ops tracepoint_prog_ops = {
621+
};
622+
617623
static bool pe_prog_is_valid_access(int off, int size, enum bpf_access_type type,
618624
struct bpf_insn_access_aux *info)
619625
{
@@ -669,8 +675,11 @@ static u32 pe_prog_convert_ctx_access(enum bpf_access_type type,
669675
return insn - insn_buf;
670676
}
671677

672-
const struct bpf_verifier_ops perf_event_prog_ops = {
678+
const struct bpf_verifier_ops perf_event_verifier_ops = {
673679
.get_func_proto = tp_prog_func_proto,
674680
.is_valid_access = pe_prog_is_valid_access,
675681
.convert_ctx_access = pe_prog_convert_ctx_access,
676682
};
683+
684+
const struct bpf_prog_ops perf_event_prog_ops = {
685+
};

net/core/filter.c

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4728,68 +4728,95 @@ static u32 sk_skb_convert_ctx_access(enum bpf_access_type type,
47284728
return insn - insn_buf;
47294729
}
47304730

4731-
const struct bpf_verifier_ops sk_filter_prog_ops = {
4731+
const struct bpf_verifier_ops sk_filter_verifier_ops = {
47324732
.get_func_proto = sk_filter_func_proto,
47334733
.is_valid_access = sk_filter_is_valid_access,
47344734
.convert_ctx_access = bpf_convert_ctx_access,
47354735
};
47364736

4737-
const struct bpf_verifier_ops tc_cls_act_prog_ops = {
4737+
const struct bpf_prog_ops sk_filter_prog_ops = {
4738+
};
4739+
4740+
const struct bpf_verifier_ops tc_cls_act_verifier_ops = {
47384741
.get_func_proto = tc_cls_act_func_proto,
47394742
.is_valid_access = tc_cls_act_is_valid_access,
47404743
.convert_ctx_access = tc_cls_act_convert_ctx_access,
47414744
.gen_prologue = tc_cls_act_prologue,
4745+
};
4746+
4747+
const struct bpf_prog_ops tc_cls_act_prog_ops = {
47424748
.test_run = bpf_prog_test_run_skb,
47434749
};
47444750

4745-
const struct bpf_verifier_ops xdp_prog_ops = {
4751+
const struct bpf_verifier_ops xdp_verifier_ops = {
47464752
.get_func_proto = xdp_func_proto,
47474753
.is_valid_access = xdp_is_valid_access,
47484754
.convert_ctx_access = xdp_convert_ctx_access,
4755+
};
4756+
4757+
const struct bpf_prog_ops xdp_prog_ops = {
47494758
.test_run = bpf_prog_test_run_xdp,
47504759
};
47514760

4752-
const struct bpf_verifier_ops cg_skb_prog_ops = {
4761+
const struct bpf_verifier_ops cg_skb_verifier_ops = {
47534762
.get_func_proto = sk_filter_func_proto,
47544763
.is_valid_access = sk_filter_is_valid_access,
47554764
.convert_ctx_access = bpf_convert_ctx_access,
4765+
};
4766+
4767+
const struct bpf_prog_ops cg_skb_prog_ops = {
47564768
.test_run = bpf_prog_test_run_skb,
47574769
};
47584770

4759-
const struct bpf_verifier_ops lwt_inout_prog_ops = {
4771+
const struct bpf_verifier_ops lwt_inout_verifier_ops = {
47604772
.get_func_proto = lwt_inout_func_proto,
47614773
.is_valid_access = lwt_is_valid_access,
47624774
.convert_ctx_access = bpf_convert_ctx_access,
4775+
};
4776+
4777+
const struct bpf_prog_ops lwt_inout_prog_ops = {
47634778
.test_run = bpf_prog_test_run_skb,
47644779
};
47654780

4766-
const struct bpf_verifier_ops lwt_xmit_prog_ops = {
4781+
const struct bpf_verifier_ops lwt_xmit_verifier_ops = {
47674782
.get_func_proto = lwt_xmit_func_proto,
47684783
.is_valid_access = lwt_is_valid_access,
47694784
.convert_ctx_access = bpf_convert_ctx_access,
47704785
.gen_prologue = tc_cls_act_prologue,
4786+
};
4787+
4788+
const struct bpf_prog_ops lwt_xmit_prog_ops = {
47714789
.test_run = bpf_prog_test_run_skb,
47724790
};
47734791

4774-
const struct bpf_verifier_ops cg_sock_prog_ops = {
4792+
const struct bpf_verifier_ops cg_sock_verifier_ops = {
47754793
.get_func_proto = sock_filter_func_proto,
47764794
.is_valid_access = sock_filter_is_valid_access,
47774795
.convert_ctx_access = sock_filter_convert_ctx_access,
47784796
};
47794797

4780-
const struct bpf_verifier_ops sock_ops_prog_ops = {
4798+
const struct bpf_prog_ops cg_sock_prog_ops = {
4799+
};
4800+
4801+
const struct bpf_verifier_ops sock_ops_verifier_ops = {
47814802
.get_func_proto = sock_ops_func_proto,
47824803
.is_valid_access = sock_ops_is_valid_access,
47834804
.convert_ctx_access = sock_ops_convert_ctx_access,
47844805
};
47854806

4786-
const struct bpf_verifier_ops sk_skb_prog_ops = {
4807+
const struct bpf_prog_ops sock_ops_prog_ops = {
4808+
};
4809+
4810+
const struct bpf_verifier_ops sk_skb_verifier_ops = {
47874811
.get_func_proto = sk_skb_func_proto,
47884812
.is_valid_access = sk_skb_is_valid_access,
47894813
.convert_ctx_access = sk_skb_convert_ctx_access,
47904814
.gen_prologue = sk_skb_prologue,
47914815
};
47924816

4817+
const struct bpf_prog_ops sk_skb_prog_ops = {
4818+
};
4819+
47934820
int sk_detach_filter(struct sock *sk)
47944821
{
47954822
int ret = -ENOENT;

0 commit comments

Comments
 (0)