diff options
Diffstat (limited to 'include/linux/bpf_verifier.h')
-rw-r--r-- | include/linux/bpf_verifier.h | 63 |
1 files changed, 46 insertions, 17 deletions
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h index 1632bb13ad8a..6b66cd1aa0b9 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h | |||
@@ -76,6 +76,14 @@ struct bpf_reg_state { | |||
76 | s64 smax_value; /* maximum possible (s64)value */ | 76 | s64 smax_value; /* maximum possible (s64)value */ |
77 | u64 umin_value; /* minimum possible (u64)value */ | 77 | u64 umin_value; /* minimum possible (u64)value */ |
78 | u64 umax_value; /* maximum possible (u64)value */ | 78 | u64 umax_value; /* maximum possible (u64)value */ |
79 | /* Inside the callee two registers can be both PTR_TO_STACK like | ||
80 | * R1=fp-8 and R2=fp-8, but one of them points to this function stack | ||
81 | * while another to the caller's stack. To differentiate them 'frameno' | ||
82 | * is used which is an index in bpf_verifier_state->frame[] array | ||
83 | * pointing to bpf_func_state. | ||
84 | * This field must be second to last, for states_equal() reasons. | ||
85 | */ | ||
86 | u32 frameno; | ||
79 | /* This field must be last, for states_equal() reasons. */ | 87 | /* This field must be last, for states_equal() reasons. */ |
80 | enum bpf_reg_liveness live; | 88 | enum bpf_reg_liveness live; |
81 | }; | 89 | }; |
@@ -83,7 +91,8 @@ struct bpf_reg_state { | |||
83 | enum bpf_stack_slot_type { | 91 | enum bpf_stack_slot_type { |
84 | STACK_INVALID, /* nothing was stored in this stack slot */ | 92 | STACK_INVALID, /* nothing was stored in this stack slot */ |
85 | STACK_SPILL, /* register spilled into stack */ | 93 | STACK_SPILL, /* register spilled into stack */ |
86 | STACK_MISC /* BPF program wrote some data into this slot */ | 94 | STACK_MISC, /* BPF program wrote some data into this slot */ |
95 | STACK_ZERO, /* BPF program wrote constant zero */ | ||
87 | }; | 96 | }; |
88 | 97 | ||
89 | #define BPF_REG_SIZE 8 /* size of eBPF register in bytes */ | 98 | #define BPF_REG_SIZE 8 /* size of eBPF register in bytes */ |
@@ -96,13 +105,34 @@ struct bpf_stack_state { | |||
96 | /* state of the program: | 105 | /* state of the program: |
97 | * type of all registers and stack info | 106 | * type of all registers and stack info |
98 | */ | 107 | */ |
99 | struct bpf_verifier_state { | 108 | struct bpf_func_state { |
100 | struct bpf_reg_state regs[MAX_BPF_REG]; | 109 | struct bpf_reg_state regs[MAX_BPF_REG]; |
101 | struct bpf_verifier_state *parent; | 110 | struct bpf_verifier_state *parent; |
111 | /* index of call instruction that called into this func */ | ||
112 | int callsite; | ||
113 | /* stack frame number of this function state from pov of | ||
114 | * enclosing bpf_verifier_state. | ||
115 | * 0 = main function, 1 = first callee. | ||
116 | */ | ||
117 | u32 frameno; | ||
118 | /* subprog number == index within subprog_stack_depth | ||
119 | * zero == main subprog | ||
120 | */ | ||
121 | u32 subprogno; | ||
122 | |||
123 | /* should be second to last. See copy_func_state() */ | ||
102 | int allocated_stack; | 124 | int allocated_stack; |
103 | struct bpf_stack_state *stack; | 125 | struct bpf_stack_state *stack; |
104 | }; | 126 | }; |
105 | 127 | ||
128 | #define MAX_CALL_FRAMES 8 | ||
129 | struct bpf_verifier_state { | ||
130 | /* call stack tracking */ | ||
131 | struct bpf_func_state *frame[MAX_CALL_FRAMES]; | ||
132 | struct bpf_verifier_state *parent; | ||
133 | u32 curframe; | ||
134 | }; | ||
135 | |||
106 | /* linked list of verifier states used to prune search */ | 136 | /* linked list of verifier states used to prune search */ |
107 | struct bpf_verifier_state_list { | 137 | struct bpf_verifier_state_list { |
108 | struct bpf_verifier_state state; | 138 | struct bpf_verifier_state state; |
@@ -113,6 +143,7 @@ struct bpf_insn_aux_data { | |||
113 | union { | 143 | union { |
114 | enum bpf_reg_type ptr_type; /* pointer type for load/store insns */ | 144 | enum bpf_reg_type ptr_type; /* pointer type for load/store insns */ |
115 | struct bpf_map *map_ptr; /* pointer for call insn into lookup_elem */ | 145 | struct bpf_map *map_ptr; /* pointer for call insn into lookup_elem */ |
146 | s32 call_imm; /* saved imm field of call insn */ | ||
116 | }; | 147 | }; |
117 | int ctx_field_size; /* the ctx field size for load insn, maybe 0 */ | 148 | int ctx_field_size; /* the ctx field size for load insn, maybe 0 */ |
118 | bool seen; /* this insn was processed by the verifier */ | 149 | bool seen; /* this insn was processed by the verifier */ |
@@ -135,11 +166,7 @@ static inline bool bpf_verifier_log_full(const struct bpf_verifer_log *log) | |||
135 | return log->len_used >= log->len_total - 1; | 166 | return log->len_used >= log->len_total - 1; |
136 | } | 167 | } |
137 | 168 | ||
138 | struct bpf_verifier_env; | 169 | #define BPF_MAX_SUBPROGS 256 |
139 | struct bpf_ext_analyzer_ops { | ||
140 | int (*insn_hook)(struct bpf_verifier_env *env, | ||
141 | int insn_idx, int prev_insn_idx); | ||
142 | }; | ||
143 | 170 | ||
144 | /* single container for all structs | 171 | /* single container for all structs |
145 | * one verifier_env per bpf_check() call | 172 | * one verifier_env per bpf_check() call |
@@ -152,29 +179,31 @@ struct bpf_verifier_env { | |||
152 | bool strict_alignment; /* perform strict pointer alignment checks */ | 179 | bool strict_alignment; /* perform strict pointer alignment checks */ |
153 | struct bpf_verifier_state *cur_state; /* current verifier state */ | 180 | struct bpf_verifier_state *cur_state; /* current verifier state */ |
154 | struct bpf_verifier_state_list **explored_states; /* search pruning optimization */ | 181 | struct bpf_verifier_state_list **explored_states; /* search pruning optimization */ |
155 | const struct bpf_ext_analyzer_ops *dev_ops; /* device analyzer ops */ | ||
156 | struct bpf_map *used_maps[MAX_USED_MAPS]; /* array of map's used by eBPF program */ | 182 | struct bpf_map *used_maps[MAX_USED_MAPS]; /* array of map's used by eBPF program */ |
157 | u32 used_map_cnt; /* number of used maps */ | 183 | u32 used_map_cnt; /* number of used maps */ |
158 | u32 id_gen; /* used to generate unique reg IDs */ | 184 | u32 id_gen; /* used to generate unique reg IDs */ |
159 | bool allow_ptr_leaks; | 185 | bool allow_ptr_leaks; |
160 | bool seen_direct_write; | 186 | bool seen_direct_write; |
161 | struct bpf_insn_aux_data *insn_aux_data; /* array of per-insn state */ | 187 | struct bpf_insn_aux_data *insn_aux_data; /* array of per-insn state */ |
162 | |||
163 | struct bpf_verifer_log log; | 188 | struct bpf_verifer_log log; |
189 | u32 subprog_starts[BPF_MAX_SUBPROGS]; | ||
190 | /* computes the stack depth of each bpf function */ | ||
191 | u16 subprog_stack_depth[BPF_MAX_SUBPROGS + 1]; | ||
192 | u32 subprog_cnt; | ||
164 | }; | 193 | }; |
165 | 194 | ||
195 | __printf(2, 3) void bpf_verifier_log_write(struct bpf_verifier_env *env, | ||
196 | const char *fmt, ...); | ||
197 | |||
166 | static inline struct bpf_reg_state *cur_regs(struct bpf_verifier_env *env) | 198 | static inline struct bpf_reg_state *cur_regs(struct bpf_verifier_env *env) |
167 | { | 199 | { |
168 | return env->cur_state->regs; | 200 | struct bpf_verifier_state *cur = env->cur_state; |
201 | |||
202 | return cur->frame[cur->curframe]->regs; | ||
169 | } | 203 | } |
170 | 204 | ||
171 | #if defined(CONFIG_NET) && defined(CONFIG_BPF_SYSCALL) | ||
172 | int bpf_prog_offload_verifier_prep(struct bpf_verifier_env *env); | 205 | int bpf_prog_offload_verifier_prep(struct bpf_verifier_env *env); |
173 | #else | 206 | int bpf_prog_offload_verify_insn(struct bpf_verifier_env *env, |
174 | static inline int bpf_prog_offload_verifier_prep(struct bpf_verifier_env *env) | 207 | int insn_idx, int prev_insn_idx); |
175 | { | ||
176 | return -EOPNOTSUPP; | ||
177 | } | ||
178 | #endif | ||
179 | 208 | ||
180 | #endif /* _LINUX_BPF_VERIFIER_H */ | 209 | #endif /* _LINUX_BPF_VERIFIER_H */ |