Skip to content

Commit 1435137

Browse files
yonghong-songAlexei Starovoitov
authored andcommitted
bpf: Refactor check_func_call() to allow callback function
Later proposed bpf_for_each_map_elem() helper has callback function as one of its arguments. This patch refactored check_func_call() to permit callback function which sets callee state. Different callback functions may have different callee states. There is no functionality change for this patch. Signed-off-by: Yonghong Song <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Acked-by: Andrii Nakryiko <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent bc2591d commit 1435137

File tree

1 file changed

+43
-17
lines changed

1 file changed

+43
-17
lines changed

kernel/bpf/verifier.c

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5249,13 +5249,19 @@ static void clear_caller_saved_regs(struct bpf_verifier_env *env,
52495249
}
52505250
}
52515251

5252-
static int check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
5253-
int *insn_idx)
5252+
typedef int (*set_callee_state_fn)(struct bpf_verifier_env *env,
5253+
struct bpf_func_state *caller,
5254+
struct bpf_func_state *callee,
5255+
int insn_idx);
5256+
5257+
static int __check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
5258+
int *insn_idx, int subprog,
5259+
set_callee_state_fn set_callee_state_cb)
52545260
{
52555261
struct bpf_verifier_state *state = env->cur_state;
52565262
struct bpf_func_info_aux *func_info_aux;
52575263
struct bpf_func_state *caller, *callee;
5258-
int i, err, subprog, target_insn;
5264+
int err;
52595265
bool is_global = false;
52605266

52615267
if (state->curframe + 1 >= MAX_CALL_FRAMES) {
@@ -5264,14 +5270,6 @@ static int check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
52645270
return -E2BIG;
52655271
}
52665272

5267-
target_insn = *insn_idx + insn->imm;
5268-
subprog = find_subprog(env, target_insn + 1);
5269-
if (subprog < 0) {
5270-
verbose(env, "verifier bug. No program starts at insn %d\n",
5271-
target_insn + 1);
5272-
return -EFAULT;
5273-
}
5274-
52755273
caller = state->frame[state->curframe];
52765274
if (state->frame[state->curframe + 1]) {
52775275
verbose(env, "verifier bug. Frame %d already allocated\n",
@@ -5326,19 +5324,17 @@ static int check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
53265324
if (err)
53275325
return err;
53285326

5329-
/* copy r1 - r5 args that callee can access. The copy includes parent
5330-
* pointers, which connects us up to the liveness chain
5331-
*/
5332-
for (i = BPF_REG_1; i <= BPF_REG_5; i++)
5333-
callee->regs[i] = caller->regs[i];
5327+
err = set_callee_state_cb(env, caller, callee, *insn_idx);
5328+
if (err)
5329+
return err;
53345330

53355331
clear_caller_saved_regs(env, caller->regs);
53365332

53375333
/* only increment it after check_reg_arg() finished */
53385334
state->curframe++;
53395335

53405336
/* and go analyze first insn of the callee */
5341-
*insn_idx = target_insn;
5337+
*insn_idx = env->subprog_info[subprog].start - 1;
53425338

53435339
if (env->log.level & BPF_LOG_LEVEL) {
53445340
verbose(env, "caller:\n");
@@ -5349,6 +5345,36 @@ static int check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
53495345
return 0;
53505346
}
53515347

5348+
static int set_callee_state(struct bpf_verifier_env *env,
5349+
struct bpf_func_state *caller,
5350+
struct bpf_func_state *callee, int insn_idx)
5351+
{
5352+
int i;
5353+
5354+
/* copy r1 - r5 args that callee can access. The copy includes parent
5355+
* pointers, which connects us up to the liveness chain
5356+
*/
5357+
for (i = BPF_REG_1; i <= BPF_REG_5; i++)
5358+
callee->regs[i] = caller->regs[i];
5359+
return 0;
5360+
}
5361+
5362+
static int check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
5363+
int *insn_idx)
5364+
{
5365+
int subprog, target_insn;
5366+
5367+
target_insn = *insn_idx + insn->imm + 1;
5368+
subprog = find_subprog(env, target_insn);
5369+
if (subprog < 0) {
5370+
verbose(env, "verifier bug. No program starts at insn %d\n",
5371+
target_insn);
5372+
return -EFAULT;
5373+
}
5374+
5375+
return __check_func_call(env, insn, insn_idx, subprog, set_callee_state);
5376+
}
5377+
53525378
static int prepare_func_exit(struct bpf_verifier_env *env, int *insn_idx)
53535379
{
53545380
struct bpf_verifier_state *state = env->cur_state;

0 commit comments

Comments
 (0)