Skip to content

Commit 79ee070

Browse files
kkdwvdKernel Patches Daemon
authored andcommitted
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>
1 parent 0e22549 commit 79ee070

File tree

1 file changed

+13
-2
lines changed

1 file changed

+13
-2
lines changed

kernel/bpf/verifier.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15126,8 +15126,8 @@ static int check_cfg(struct bpf_verifier_env *env)
1512615126
{
1512715127
int insn_cnt = env->prog->len;
1512815128
int *insn_stack, *insn_state;
15129-
int ret = 0;
15130-
int i;
15129+
int ex_insn_beg, i, ret = 0;
15130+
bool ex_done = false;
1513115131

1513215132
insn_state = env->cfg.insn_state = kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL);
1513315133
if (!insn_state)
@@ -15143,6 +15143,7 @@ static int check_cfg(struct bpf_verifier_env *env)
1514315143
insn_stack[0] = 0; /* 0 is the first instruction */
1514415144
env->cfg.cur_stack = 1;
1514515145

15146+
walk_cfg:
1514615147
while (env->cfg.cur_stack > 0) {
1514715148
int t = insn_stack[env->cfg.cur_stack - 1];
1514815149

@@ -15169,6 +15170,16 @@ static int check_cfg(struct bpf_verifier_env *env)
1516915170
goto err_free;
1517015171
}
1517115172

15173+
if (env->exception_callback_subprog && !ex_done) {
15174+
ex_insn_beg = env->subprog_info[env->exception_callback_subprog].start;
15175+
15176+
insn_state[ex_insn_beg] = DISCOVERED;
15177+
insn_stack[0] = ex_insn_beg;
15178+
env->cfg.cur_stack = 1;
15179+
ex_done = true;
15180+
goto walk_cfg;
15181+
}
15182+
1517215183
for (i = 0; i < insn_cnt; i++) {
1517315184
if (insn_state[i] != EXPLORED) {
1517415185
verbose(env, "unreachable insn %d\n", i);

0 commit comments

Comments
 (0)