Skip to content

Commit 58124a9

Browse files
eddyz87Alexei Starovoitov
authored andcommitted
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>
1 parent 683b96f commit 58124a9

File tree

1 file changed

+48
-36
lines changed

1 file changed

+48
-36
lines changed

kernel/bpf/verifier.c

Lines changed: 48 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9370,11 +9370,10 @@ static int set_callee_state(struct bpf_verifier_env *env,
93709370
struct bpf_func_state *caller,
93719371
struct bpf_func_state *callee, int insn_idx);
93729372

9373-
static int __check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
9374-
int *insn_idx, int subprog,
9375-
set_callee_state_fn set_callee_state_cb)
9373+
static int setup_func_entry(struct bpf_verifier_env *env, int subprog, int callsite,
9374+
set_callee_state_fn set_callee_state_cb,
9375+
struct bpf_verifier_state *state)
93769376
{
9377-
struct bpf_verifier_state *state = env->cur_state;
93789377
struct bpf_func_state *caller, *callee;
93799378
int err;
93809379

@@ -9384,13 +9383,53 @@ static int __check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn
93849383
return -E2BIG;
93859384
}
93869385

9387-
caller = state->frame[state->curframe];
93889386
if (state->frame[state->curframe + 1]) {
93899387
verbose(env, "verifier bug. Frame %d already allocated\n",
93909388
state->curframe + 1);
93919389
return -EFAULT;
93929390
}
93939391

9392+
caller = state->frame[state->curframe];
9393+
callee = kzalloc(sizeof(*callee), GFP_KERNEL);
9394+
if (!callee)
9395+
return -ENOMEM;
9396+
state->frame[state->curframe + 1] = callee;
9397+
9398+
/* callee cannot access r0, r6 - r9 for reading and has to write
9399+
* into its own stack before reading from it.
9400+
* callee can read/write into caller's stack
9401+
*/
9402+
init_func_state(env, callee,
9403+
/* remember the callsite, it will be used by bpf_exit */
9404+
callsite,
9405+
state->curframe + 1 /* frameno within this callchain */,
9406+
subprog /* subprog number within this prog */);
9407+
/* Transfer references to the callee */
9408+
err = copy_reference_state(callee, caller);
9409+
err = err ?: set_callee_state_cb(env, caller, callee, callsite);
9410+
if (err)
9411+
goto err_out;
9412+
9413+
/* only increment it after check_reg_arg() finished */
9414+
state->curframe++;
9415+
9416+
return 0;
9417+
9418+
err_out:
9419+
free_func_state(callee);
9420+
state->frame[state->curframe + 1] = NULL;
9421+
return err;
9422+
}
9423+
9424+
static int __check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
9425+
int *insn_idx, int subprog,
9426+
set_callee_state_fn set_callee_state_cb)
9427+
{
9428+
struct bpf_verifier_state *state = env->cur_state;
9429+
struct bpf_func_state *caller, *callee;
9430+
int err;
9431+
9432+
caller = state->frame[state->curframe];
93949433
err = btf_check_subprog_call(env, subprog, caller->regs);
93959434
if (err == -EFAULT)
93969435
return err;
@@ -9460,50 +9499,23 @@ static int __check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn
94609499
return 0;
94619500
}
94629501

9463-
callee = kzalloc(sizeof(*callee), GFP_KERNEL);
9464-
if (!callee)
9465-
return -ENOMEM;
9466-
state->frame[state->curframe + 1] = callee;
9467-
9468-
/* callee cannot access r0, r6 - r9 for reading and has to write
9469-
* into its own stack before reading from it.
9470-
* callee can read/write into caller's stack
9471-
*/
9472-
init_func_state(env, callee,
9473-
/* remember the callsite, it will be used by bpf_exit */
9474-
*insn_idx /* callsite */,
9475-
state->curframe + 1 /* frameno within this callchain */,
9476-
subprog /* subprog number within this prog */);
9477-
9478-
/* Transfer references to the callee */
9479-
err = copy_reference_state(callee, caller);
9502+
err = setup_func_entry(env, subprog, *insn_idx, set_callee_state_cb, state);
94809503
if (err)
9481-
goto err_out;
9482-
9483-
err = set_callee_state_cb(env, caller, callee, *insn_idx);
9484-
if (err)
9485-
goto err_out;
9504+
return err;
94869505

94879506
clear_caller_saved_regs(env, caller->regs);
94889507

9489-
/* only increment it after check_reg_arg() finished */
9490-
state->curframe++;
9491-
94929508
/* and go analyze first insn of the callee */
94939509
*insn_idx = env->subprog_info[subprog].start - 1;
94949510

94959511
if (env->log.level & BPF_LOG_LEVEL) {
94969512
verbose(env, "caller:\n");
94979513
print_verifier_state(env, caller, true);
94989514
verbose(env, "callee:\n");
9499-
print_verifier_state(env, callee, true);
9515+
print_verifier_state(env, state->frame[state->curframe], true);
95009516
}
9501-
return 0;
95029517

9503-
err_out:
9504-
free_func_state(callee);
9505-
state->frame[state->curframe + 1] = NULL;
9506-
return err;
9518+
return 0;
95079519
}
95089520

95099521
int map_set_for_each_callback_args(struct bpf_verifier_env *env,

0 commit comments

Comments
 (0)