aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorAlexei Starovoitov <ast@fb.com>2017-03-15 21:26:40 -0400
committerDavid S. Miller <davem@davemloft.net>2017-03-16 23:44:11 -0400
commit79741b3bdec01a8628368fbcfccc7d189ed606cb (patch)
tree8c8e866e58087e26eab10b1086282a73dfcdcf86 /kernel
parente245c5c6a5656e4d61aa7bb08e9694fd6e5b2b9d (diff)
bpf: refactor fixup_bpf_calls()
reduce indent and make it iterate over instructions similar to convert_ctx_accesses(). Also convert hard BUG_ON into soft verifier error. Signed-off-by: Alexei Starovoitov <ast@kernel.org> Acked-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/bpf/verifier.c76
1 files changed, 35 insertions, 41 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index e41da6c57053..5dfa9b8111da 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -3233,59 +3233,53 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env)
3233 return 0; 3233 return 0;
3234} 3234}
3235 3235
3236/* fixup insn->imm field of bpf_call instructions: 3236/* fixup insn->imm field of bpf_call instructions
3237 * if (insn->imm == BPF_FUNC_map_lookup_elem)
3238 * insn->imm = bpf_map_lookup_elem - __bpf_call_base;
3239 * else if (insn->imm == BPF_FUNC_map_update_elem)
3240 * insn->imm = bpf_map_update_elem - __bpf_call_base;
3241 * else ...
3242 * 3237 *
3243 * this function is called after eBPF program passed verification 3238 * this function is called after eBPF program passed verification
3244 */ 3239 */
3245static void fixup_bpf_calls(struct bpf_prog *prog) 3240static int fixup_bpf_calls(struct bpf_verifier_env *env)
3246{ 3241{
3242 struct bpf_prog *prog = env->prog;
3243 struct bpf_insn *insn = prog->insnsi;
3247 const struct bpf_func_proto *fn; 3244 const struct bpf_func_proto *fn;
3245 const int insn_cnt = prog->len;
3248 int i; 3246 int i;
3249 3247
3250 for (i = 0; i < prog->len; i++) { 3248 for (i = 0; i < insn_cnt; i++, insn++) {
3251 struct bpf_insn *insn = &prog->insnsi[i]; 3249 if (insn->code != (BPF_JMP | BPF_CALL))
3250 continue;
3252 3251
3253 if (insn->code == (BPF_JMP | BPF_CALL)) { 3252 if (insn->imm == BPF_FUNC_get_route_realm)
3254 /* we reach here when program has bpf_call instructions 3253 prog->dst_needed = 1;
3255 * and it passed bpf_check(), means that 3254 if (insn->imm == BPF_FUNC_get_prandom_u32)
3256 * ops->get_func_proto must have been supplied, check it 3255 bpf_user_rnd_init_once();
3256 if (insn->imm == BPF_FUNC_xdp_adjust_head)
3257 prog->xdp_adjust_head = 1;
3258 if (insn->imm == BPF_FUNC_tail_call) {
3259 /* mark bpf_tail_call as different opcode to avoid
3260 * conditional branch in the interpeter for every normal
3261 * call and to prevent accidental JITing by JIT compiler
3262 * that doesn't support bpf_tail_call yet
3257 */ 3263 */
3258 BUG_ON(!prog->aux->ops->get_func_proto); 3264 insn->imm = 0;
3259 3265 insn->code |= BPF_X;
3260 if (insn->imm == BPF_FUNC_get_route_realm) 3266 continue;
3261 prog->dst_needed = 1; 3267 }
3262 if (insn->imm == BPF_FUNC_get_prandom_u32)
3263 bpf_user_rnd_init_once();
3264 if (insn->imm == BPF_FUNC_xdp_adjust_head)
3265 prog->xdp_adjust_head = 1;
3266 if (insn->imm == BPF_FUNC_tail_call) {
3267 /* mark bpf_tail_call as different opcode
3268 * to avoid conditional branch in
3269 * interpeter for every normal call
3270 * and to prevent accidental JITing by
3271 * JIT compiler that doesn't support
3272 * bpf_tail_call yet
3273 */
3274 insn->imm = 0;
3275 insn->code |= BPF_X;
3276 continue;
3277 }
3278 3268
3279 fn = prog->aux->ops->get_func_proto(insn->imm); 3269 fn = prog->aux->ops->get_func_proto(insn->imm);
3280 /* all functions that have prototype and verifier allowed 3270 /* all functions that have prototype and verifier allowed
3281 * programs to call them, must be real in-kernel functions 3271 * programs to call them, must be real in-kernel functions
3282 */ 3272 */
3283 BUG_ON(!fn->func); 3273 if (!fn->func) {
3284 insn->imm = fn->func - __bpf_call_base; 3274 verbose("kernel subsystem misconfigured func %s#%d\n",
3275 func_id_name(insn->imm), insn->imm);
3276 return -EFAULT;
3285 } 3277 }
3278 insn->imm = fn->func - __bpf_call_base;
3286 } 3279 }
3287}
3288 3280
3281 return 0;
3282}
3289 3283
3290static void free_states(struct bpf_verifier_env *env) 3284static void free_states(struct bpf_verifier_env *env)
3291{ 3285{
@@ -3383,7 +3377,7 @@ skip_full_check:
3383 ret = convert_ctx_accesses(env); 3377 ret = convert_ctx_accesses(env);
3384 3378
3385 if (ret == 0) 3379 if (ret == 0)
3386 fixup_bpf_calls(env->prog); 3380 ret = fixup_bpf_calls(env);
3387 3381
3388 if (log_level && log_len >= log_size - 1) { 3382 if (log_level && log_len >= log_size - 1) {
3389 BUG_ON(log_len >= log_size); 3383 BUG_ON(log_len >= log_size);