mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-10 15:10:38 +00:00
bpf: extract setup_func_entry() utility function
Move code for simulated stack frame creation to a separate utility function. This function would be used in the follow-up change for callbacks handling. Acked-by: Andrii Nakryiko <andrii@kernel.org> Signed-off-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://lore.kernel.org/r/20231121020701.26440-6-eddyz87@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
683b96f960
commit
58124a98cb
@ -9370,11 +9370,10 @@ static int set_callee_state(struct bpf_verifier_env *env,
|
||||
struct bpf_func_state *caller,
|
||||
struct bpf_func_state *callee, int insn_idx);
|
||||
|
||||
static int __check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
|
||||
int *insn_idx, int subprog,
|
||||
set_callee_state_fn set_callee_state_cb)
|
||||
static int setup_func_entry(struct bpf_verifier_env *env, int subprog, int callsite,
|
||||
set_callee_state_fn set_callee_state_cb,
|
||||
struct bpf_verifier_state *state)
|
||||
{
|
||||
struct bpf_verifier_state *state = env->cur_state;
|
||||
struct bpf_func_state *caller, *callee;
|
||||
int err;
|
||||
|
||||
@ -9384,13 +9383,53 @@ static int __check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn
|
||||
return -E2BIG;
|
||||
}
|
||||
|
||||
caller = state->frame[state->curframe];
|
||||
if (state->frame[state->curframe + 1]) {
|
||||
verbose(env, "verifier bug. Frame %d already allocated\n",
|
||||
state->curframe + 1);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
caller = state->frame[state->curframe];
|
||||
callee = kzalloc(sizeof(*callee), GFP_KERNEL);
|
||||
if (!callee)
|
||||
return -ENOMEM;
|
||||
state->frame[state->curframe + 1] = callee;
|
||||
|
||||
/* callee cannot access r0, r6 - r9 for reading and has to write
|
||||
* into its own stack before reading from it.
|
||||
* callee can read/write into caller's stack
|
||||
*/
|
||||
init_func_state(env, callee,
|
||||
/* remember the callsite, it will be used by bpf_exit */
|
||||
callsite,
|
||||
state->curframe + 1 /* frameno within this callchain */,
|
||||
subprog /* subprog number within this prog */);
|
||||
/* Transfer references to the callee */
|
||||
err = copy_reference_state(callee, caller);
|
||||
err = err ?: set_callee_state_cb(env, caller, callee, callsite);
|
||||
if (err)
|
||||
goto err_out;
|
||||
|
||||
/* only increment it after check_reg_arg() finished */
|
||||
state->curframe++;
|
||||
|
||||
return 0;
|
||||
|
||||
err_out:
|
||||
free_func_state(callee);
|
||||
state->frame[state->curframe + 1] = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
|
||||
int *insn_idx, int subprog,
|
||||
set_callee_state_fn set_callee_state_cb)
|
||||
{
|
||||
struct bpf_verifier_state *state = env->cur_state;
|
||||
struct bpf_func_state *caller, *callee;
|
||||
int err;
|
||||
|
||||
caller = state->frame[state->curframe];
|
||||
err = btf_check_subprog_call(env, subprog, caller->regs);
|
||||
if (err == -EFAULT)
|
||||
return err;
|
||||
@ -9460,35 +9499,12 @@ static int __check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn
|
||||
return 0;
|
||||
}
|
||||
|
||||
callee = kzalloc(sizeof(*callee), GFP_KERNEL);
|
||||
if (!callee)
|
||||
return -ENOMEM;
|
||||
state->frame[state->curframe + 1] = callee;
|
||||
|
||||
/* callee cannot access r0, r6 - r9 for reading and has to write
|
||||
* into its own stack before reading from it.
|
||||
* callee can read/write into caller's stack
|
||||
*/
|
||||
init_func_state(env, callee,
|
||||
/* remember the callsite, it will be used by bpf_exit */
|
||||
*insn_idx /* callsite */,
|
||||
state->curframe + 1 /* frameno within this callchain */,
|
||||
subprog /* subprog number within this prog */);
|
||||
|
||||
/* Transfer references to the callee */
|
||||
err = copy_reference_state(callee, caller);
|
||||
err = setup_func_entry(env, subprog, *insn_idx, set_callee_state_cb, state);
|
||||
if (err)
|
||||
goto err_out;
|
||||
|
||||
err = set_callee_state_cb(env, caller, callee, *insn_idx);
|
||||
if (err)
|
||||
goto err_out;
|
||||
return err;
|
||||
|
||||
clear_caller_saved_regs(env, caller->regs);
|
||||
|
||||
/* only increment it after check_reg_arg() finished */
|
||||
state->curframe++;
|
||||
|
||||
/* and go analyze first insn of the callee */
|
||||
*insn_idx = env->subprog_info[subprog].start - 1;
|
||||
|
||||
@ -9496,14 +9512,10 @@ static int __check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn
|
||||
verbose(env, "caller:\n");
|
||||
print_verifier_state(env, caller, true);
|
||||
verbose(env, "callee:\n");
|
||||
print_verifier_state(env, callee, true);
|
||||
print_verifier_state(env, state->frame[state->curframe], true);
|
||||
}
|
||||
return 0;
|
||||
|
||||
err_out:
|
||||
free_func_state(callee);
|
||||
state->frame[state->curframe + 1] = NULL;
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int map_set_for_each_callback_args(struct bpf_verifier_env *env,
|
||||
|
Loading…
x
Reference in New Issue
Block a user