Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions kernel/bpf/verifier.c
Original file line number Diff line number Diff line change
Expand Up @@ -11005,6 +11005,10 @@ static int prepare_func_exit(struct bpf_verifier_env *env, int *insn_idx)
bool in_callback_fn;
int err;

err = bpf_update_live_stack(env);
if (err)
return err;

callee = state->frame[state->curframe];
r0 = &callee->regs[BPF_REG_0];
if (r0->type == PTR_TO_STACK) {
Expand Down Expand Up @@ -11911,6 +11915,25 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn
env->prog->call_get_func_ip = true;
}

if (func_id == BPF_FUNC_tail_call) {
if (env->cur_state->curframe) {
struct bpf_verifier_state *branch;

mark_reg_scratched(env, BPF_REG_0);
branch = push_stack(env, env->insn_idx + 1, env->insn_idx, false);
if (IS_ERR(branch))
return PTR_ERR(branch);
clear_all_pkt_pointers(env);
mark_reg_unknown(env, regs, BPF_REG_0);
err = prepare_func_exit(env, &env->insn_idx);
if (err)
return err;
env->insn_idx--;
} else {
changes_data = false;
}
}

if (changes_data)
clear_all_pkt_pointers(env);
return 0;
Expand Down Expand Up @@ -19876,9 +19899,6 @@ static int process_bpf_exit_full(struct bpf_verifier_env *env,
return PROCESS_BPF_EXIT;

if (env->cur_state->curframe) {
err = bpf_update_live_stack(env);
if (err)
return err;
/* exit from nested function */
err = prepare_func_exit(env, &env->insn_idx);
if (err)
Expand Down
Loading