aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorAlexei Starovoitov <ast@plumgrid.com>2014-09-26 03:17:06 -0400
committerDavid S. Miller <davem@davemloft.net>2014-09-26 15:05:15 -0400
commit17a5267067f3c372fec9ffb798d6eaba6b5e6a4c (patch)
tree62746fb36df3ad84c88ce1421ebe524075493362 /include/linux
parent475fb78fbf48592ce541627c60a7b331060e31f5 (diff)
bpf: verifier (add verifier core)
This patch adds verifier core which simulates execution of every insn and records the state of registers and program stack. Every branch instruction seen during simulation is pushed into state stack. When verifier reaches BPF_EXIT, it pops the state from the stack and continues until it reaches BPF_EXIT again. For program: 1: bpf_mov r1, xxx 2: if (r1 == 0) goto 5 3: bpf_mov r0, 1 4: goto 6 5: bpf_mov r0, 2 6: bpf_exit The verifier will walk insns: 1, 2, 3, 4, 6 then it will pop the state recorded at insn#2 and will continue: 5, 6 This way it walks all possible paths through the program and checks all possible values of registers. While doing so, it checks for: - invalid instructions - uninitialized register access - uninitialized stack access - misaligned stack access - out of range stack access - invalid calling convention - instruction encoding is not using reserved fields Kernel subsystem configures the verifier with two callbacks: - bool (*is_valid_access)(int off, int size, enum bpf_access_type type); that provides information to the verifer which fields of 'ctx' are accessible (remember 'ctx' is the first argument to eBPF program) - const struct bpf_func_proto *(*get_func_proto)(enum bpf_func_id func_id); returns argument constraints of kernel helper functions that eBPF program may call, so that verifier can checks that R1-R5 types match the prototype More details in Documentation/networking/filter.txt and in kernel/bpf/verifier.c Signed-off-by: Alexei Starovoitov <ast@plumgrid.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/bpf.h47
1 files changed, 47 insertions, 0 deletions
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 9dfeb36f8971..3cf91754a957 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -46,6 +46,31 @@ void bpf_register_map_type(struct bpf_map_type_list *tl);
46void bpf_map_put(struct bpf_map *map); 46void bpf_map_put(struct bpf_map *map);
47struct bpf_map *bpf_map_get(struct fd f); 47struct bpf_map *bpf_map_get(struct fd f);
48 48
49/* function argument constraints */
50enum bpf_arg_type {
51 ARG_ANYTHING = 0, /* any argument is ok */
52
53 /* the following constraints used to prototype
54 * bpf_map_lookup/update/delete_elem() functions
55 */
56 ARG_CONST_MAP_PTR, /* const argument used as pointer to bpf_map */
57 ARG_PTR_TO_MAP_KEY, /* pointer to stack used as map key */
58 ARG_PTR_TO_MAP_VALUE, /* pointer to stack used as map value */
59
60 /* the following constraints used to prototype bpf_memcmp() and other
61 * functions that access data on eBPF program stack
62 */
63 ARG_PTR_TO_STACK, /* any pointer to eBPF program stack */
64 ARG_CONST_STACK_SIZE, /* number of bytes accessed from stack */
65};
66
67/* type of values returned from helper functions */
68enum bpf_return_type {
69 RET_INTEGER, /* function returns integer */
70 RET_VOID, /* function doesn't return anything */
71 RET_PTR_TO_MAP_VALUE_OR_NULL, /* returns a pointer to map elem value or NULL */
72};
73
49/* eBPF function prototype used by verifier to allow BPF_CALLs from eBPF programs 74/* eBPF function prototype used by verifier to allow BPF_CALLs from eBPF programs
50 * to in-kernel helper functions and for adjusting imm32 field in BPF_CALL 75 * to in-kernel helper functions and for adjusting imm32 field in BPF_CALL
51 * instructions after verifying 76 * instructions after verifying
@@ -53,11 +78,33 @@ struct bpf_map *bpf_map_get(struct fd f);
53struct bpf_func_proto { 78struct bpf_func_proto {
54 u64 (*func)(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5); 79 u64 (*func)(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5);
55 bool gpl_only; 80 bool gpl_only;
81 enum bpf_return_type ret_type;
82 enum bpf_arg_type arg1_type;
83 enum bpf_arg_type arg2_type;
84 enum bpf_arg_type arg3_type;
85 enum bpf_arg_type arg4_type;
86 enum bpf_arg_type arg5_type;
87};
88
89/* bpf_context is intentionally undefined structure. Pointer to bpf_context is
90 * the first argument to eBPF programs.
91 * For socket filters: 'struct bpf_context *' == 'struct sk_buff *'
92 */
93struct bpf_context;
94
95enum bpf_access_type {
96 BPF_READ = 1,
97 BPF_WRITE = 2
56}; 98};
57 99
58struct bpf_verifier_ops { 100struct bpf_verifier_ops {
59 /* return eBPF function prototype for verification */ 101 /* return eBPF function prototype for verification */
60 const struct bpf_func_proto *(*get_func_proto)(enum bpf_func_id func_id); 102 const struct bpf_func_proto *(*get_func_proto)(enum bpf_func_id func_id);
103
104 /* return true if 'size' wide access at offset 'off' within bpf_context
105 * with 'type' (read or write) is allowed
106 */
107 bool (*is_valid_access)(int off, int size, enum bpf_access_type type);
61}; 108};
62 109
63struct bpf_prog_type_list { 110struct bpf_prog_type_list {