mirror of
https://github.com/nxp-imx/linux-imx.git
synced 2025-12-22 18:37:35 +01:00
bpf: Perform CFG walk for exception callback
Since exception callbacks are not referenced using bpf_pseudo_func and bpf_pseudo_call instructions, check_cfg traversal will never explore instructions of the exception callback. Even after adding the subprog, the program will then fail with a 'unreachable insn' error. We thus need to begin walking from the start of the exception callback again in check_cfg after a complete CFG traversal finishes, so as to explore the CFG rooted at the exception callback. Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Link: https://lore.kernel.org/r/20230912233214.1518551-8-memxor@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
b9ae0c9dd0
commit
b62bf8a5e9
|
|
@ -15126,8 +15126,8 @@ static int check_cfg(struct bpf_verifier_env *env)
|
||||||
{
|
{
|
||||||
int insn_cnt = env->prog->len;
|
int insn_cnt = env->prog->len;
|
||||||
int *insn_stack, *insn_state;
|
int *insn_stack, *insn_state;
|
||||||
int ret = 0;
|
int ex_insn_beg, i, ret = 0;
|
||||||
int i;
|
bool ex_done = false;
|
||||||
|
|
||||||
insn_state = env->cfg.insn_state = kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL);
|
insn_state = env->cfg.insn_state = kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL);
|
||||||
if (!insn_state)
|
if (!insn_state)
|
||||||
|
|
@ -15143,6 +15143,7 @@ static int check_cfg(struct bpf_verifier_env *env)
|
||||||
insn_stack[0] = 0; /* 0 is the first instruction */
|
insn_stack[0] = 0; /* 0 is the first instruction */
|
||||||
env->cfg.cur_stack = 1;
|
env->cfg.cur_stack = 1;
|
||||||
|
|
||||||
|
walk_cfg:
|
||||||
while (env->cfg.cur_stack > 0) {
|
while (env->cfg.cur_stack > 0) {
|
||||||
int t = insn_stack[env->cfg.cur_stack - 1];
|
int t = insn_stack[env->cfg.cur_stack - 1];
|
||||||
|
|
||||||
|
|
@ -15169,6 +15170,16 @@ static int check_cfg(struct bpf_verifier_env *env)
|
||||||
goto err_free;
|
goto err_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (env->exception_callback_subprog && !ex_done) {
|
||||||
|
ex_insn_beg = env->subprog_info[env->exception_callback_subprog].start;
|
||||||
|
|
||||||
|
insn_state[ex_insn_beg] = DISCOVERED;
|
||||||
|
insn_stack[0] = ex_insn_beg;
|
||||||
|
env->cfg.cur_stack = 1;
|
||||||
|
ex_done = true;
|
||||||
|
goto walk_cfg;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < insn_cnt; i++) {
|
for (i = 0; i < insn_cnt; i++) {
|
||||||
if (insn_state[i] != EXPLORED) {
|
if (insn_state[i] != EXPLORED) {
|
||||||
verbose(env, "unreachable insn %d\n", i);
|
verbose(env, "unreachable insn %d\n", i);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user