bpf: Fix subprog idx logic in check_max_stack_depth
[ Upstream commitba7b3e7d5f
] 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:7ddc80a476
("bpf: Teach stack depth check about async callbacks.") Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Link: https://lore.kernel.org/r/20230717161530.1238-2-memxor@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Родитель
4e87eb2248
Коммит
e35dc107a1
|
@ -3744,7 +3744,7 @@ process_func:
|
|||
continue_func:
|
||||
subprog_end = subprog[idx + 1].start;
|
||||
for (; i < subprog_end; i++) {
|
||||
int next_insn;
|
||||
int next_insn, sidx;
|
||||
|
||||
if (!bpf_pseudo_call(insn + i) && !bpf_pseudo_func(insn + i))
|
||||
continue;
|
||||
|
@ -3754,14 +3754,14 @@ continue_func:
|
|||
|
||||
/* find the callee */
|
||||
next_insn = i + insn[i].imm + 1;
|
||||
idx = find_subprog(env, next_insn);
|
||||
if (idx < 0) {
|
||||
sidx = find_subprog(env, next_insn);
|
||||
if (sidx < 0) {
|
||||
WARN_ONCE(1, "verifier bug. No program starts at insn %d\n",
|
||||
next_insn);
|
||||
return -EFAULT;
|
||||
}
|
||||
if (subprog[idx].is_async_cb) {
|
||||
if (subprog[idx].has_tail_call) {
|
||||
if (subprog[sidx].is_async_cb) {
|
||||
if (subprog[sidx].has_tail_call) {
|
||||
verbose(env, "verifier bug. subprog has tail_call and async cb\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
@ -3770,6 +3770,7 @@ continue_func:
|
|||
continue;
|
||||
}
|
||||
i = next_insn;
|
||||
idx = sidx;
|
||||
|
||||
if (subprog[idx].has_tail_call)
|
||||
tail_call_reachable = true;
|
||||
|
|
Загрузка…
Ссылка в новой задаче