Skip to content

Commit 80ca3f1

Browse files
eddyz87Alexei Starovoitov
authored andcommitted
bpf: jmp_offset() and verbose_insn() utility functions
Extract two utility functions: - One BPF jump instruction uses .imm field to encode jump offset, while the rest use .off. Encapsulate this detail as jmp_offset() function. - Avoid duplicating instruction printing callback definitions by defining a verbose_insn() function, which disassembles an instruction into the verifier log while hiding this detail. These functions will be used in the next patch. Signed-off-by: Eduard Zingerman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 5bde575 commit 80ca3f1

File tree

1 file changed

+23
-17
lines changed

1 file changed

+23
-17
lines changed

kernel/bpf/verifier.c

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3360,6 +3360,15 @@ static int add_subprog_and_kfunc(struct bpf_verifier_env *env)
33603360
return 0;
33613361
}
33623362

3363+
static int jmp_offset(struct bpf_insn *insn)
3364+
{
3365+
u8 code = insn->code;
3366+
3367+
if (code == (BPF_JMP32 | BPF_JA))
3368+
return insn->imm;
3369+
return insn->off;
3370+
}
3371+
33633372
static int check_subprogs(struct bpf_verifier_env *env)
33643373
{
33653374
int i, subprog_start, subprog_end, off, cur_subprog = 0;
@@ -3386,10 +3395,7 @@ static int check_subprogs(struct bpf_verifier_env *env)
33863395
goto next;
33873396
if (BPF_OP(code) == BPF_EXIT || BPF_OP(code) == BPF_CALL)
33883397
goto next;
3389-
if (code == (BPF_JMP32 | BPF_JA))
3390-
off = i + insn[i].imm + 1;
3391-
else
3392-
off = i + insn[i].off + 1;
3398+
off = i + jmp_offset(&insn[i]) + 1;
33933399
if (off < subprog_start || off >= subprog_end) {
33943400
verbose(env, "jump out of range from insn %d to %d\n", i, off);
33953401
return -EINVAL;
@@ -3919,6 +3925,17 @@ static const char *disasm_kfunc_name(void *data, const struct bpf_insn *insn)
39193925
return btf_name_by_offset(desc_btf, func->name_off);
39203926
}
39213927

3928+
static void verbose_insn(struct bpf_verifier_env *env, struct bpf_insn *insn)
3929+
{
3930+
const struct bpf_insn_cbs cbs = {
3931+
.cb_call = disasm_kfunc_name,
3932+
.cb_print = verbose,
3933+
.private_data = env,
3934+
};
3935+
3936+
print_bpf_insn(&cbs, insn, env->allow_ptr_leaks);
3937+
}
3938+
39223939
static inline void bt_init(struct backtrack_state *bt, u32 frame)
39233940
{
39243941
bt->frame = frame;
@@ -4119,11 +4136,6 @@ static bool calls_callback(struct bpf_verifier_env *env, int insn_idx);
41194136
static int backtrack_insn(struct bpf_verifier_env *env, int idx, int subseq_idx,
41204137
struct bpf_insn_hist_entry *hist, struct backtrack_state *bt)
41214138
{
4122-
const struct bpf_insn_cbs cbs = {
4123-
.cb_call = disasm_kfunc_name,
4124-
.cb_print = verbose,
4125-
.private_data = env,
4126-
};
41274139
struct bpf_insn *insn = env->prog->insnsi + idx;
41284140
u8 class = BPF_CLASS(insn->code);
41294141
u8 opcode = BPF_OP(insn->code);
@@ -4141,7 +4153,7 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx, int subseq_idx,
41414153
fmt_stack_mask(env->tmp_str_buf, TMP_STR_BUF_LEN, bt_stack_mask(bt));
41424154
verbose(env, "stack=%s before ", env->tmp_str_buf);
41434155
verbose(env, "%d: ", idx);
4144-
print_bpf_insn(&cbs, insn, env->allow_ptr_leaks);
4156+
verbose_insn(env, insn);
41454157
}
41464158

41474159
/* If there is a history record that some registers gained range at this insn,
@@ -19273,19 +19285,13 @@ static int do_check(struct bpf_verifier_env *env)
1927319285
}
1927419286

1927519287
if (env->log.level & BPF_LOG_LEVEL) {
19276-
const struct bpf_insn_cbs cbs = {
19277-
.cb_call = disasm_kfunc_name,
19278-
.cb_print = verbose,
19279-
.private_data = env,
19280-
};
19281-
1928219288
if (verifier_state_scratched(env))
1928319289
print_insn_state(env, state, state->curframe);
1928419290

1928519291
verbose_linfo(env, env->insn_idx, "; ");
1928619292
env->prev_log_pos = env->log.end_pos;
1928719293
verbose(env, "%d: ", env->insn_idx);
19288-
print_bpf_insn(&cbs, insn, env->allow_ptr_leaks);
19294+
verbose_insn(env, insn);
1928919295
env->prev_insn_print_pos = env->log.end_pos - env->prev_log_pos;
1929019296
env->prev_log_pos = env->log.end_pos;
1929119297
}

0 commit comments

Comments
 (0)