Skip to content

Commit ba7b3e7

Browse files
kkdwivediAlexei Starovoitov
authored andcommitted
bpf: Fix subprog idx logic in check_max_stack_depth
The assignment to idx in check_max_stack_depth happens once we see a bpf_pseudo_call or bpf_pseudo_func. This is not an issue as the rest of the code performs a few checks and then pushes the frame to the frame stack, except the case of async callbacks. If the async callback case causes the loop iteration to be skipped, the idx assignment will be incorrect on the next iteration of the loop. The value stored in the frame stack (as the subprogno of the current subprog) will be incorrect. This leads to incorrect checks and incorrect tail_call_reachable marking. Save the target subprog in a new variable and only assign to idx once we are done with the is_async_cb check which may skip pushing of frame to the frame stack and subsequent stack depth checks and tail call markings. Fixes: 7ddc80a ("bpf: Teach stack depth check about async callbacks.") Signed-off-by: Kumar Kartikeya Dwivedi <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 8fcd7c7 commit ba7b3e7

File tree

1 file changed

+6
-5
lines changed

1 file changed

+6
-5
lines changed

kernel/bpf/verifier.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5621,7 +5621,7 @@ static int check_max_stack_depth(struct bpf_verifier_env *env)
56215621
continue_func:
56225622
subprog_end = subprog[idx + 1].start;
56235623
for (; i < subprog_end; i++) {
5624-
int next_insn;
5624+
int next_insn, sidx;
56255625

56265626
if (!bpf_pseudo_call(insn + i) && !bpf_pseudo_func(insn + i))
56275627
continue;
@@ -5631,14 +5631,14 @@ static int check_max_stack_depth(struct bpf_verifier_env *env)
56315631

56325632
/* find the callee */
56335633
next_insn = i + insn[i].imm + 1;
5634-
idx = find_subprog(env, next_insn);
5635-
if (idx < 0) {
5634+
sidx = find_subprog(env, next_insn);
5635+
if (sidx < 0) {
56365636
WARN_ONCE(1, "verifier bug. No program starts at insn %d\n",
56375637
next_insn);
56385638
return -EFAULT;
56395639
}
5640-
if (subprog[idx].is_async_cb) {
5641-
if (subprog[idx].has_tail_call) {
5640+
if (subprog[sidx].is_async_cb) {
5641+
if (subprog[sidx].has_tail_call) {
56425642
verbose(env, "verifier bug. subprog has tail_call and async cb\n");
56435643
return -EFAULT;
56445644
}
@@ -5647,6 +5647,7 @@ static int check_max_stack_depth(struct bpf_verifier_env *env)
56475647
continue;
56485648
}
56495649
i = next_insn;
5650+
idx = sidx;
56505651

56515652
if (subprog[idx].has_tail_call)
56525653
tail_call_reachable = true;

0 commit comments

Comments
 (0)