Skip to content

Commit 61777f3

Browse files
author
Alexei Starovoitov
committed
Merge branch 'fix-verifier-warning'
Paul Chaignon says: ==================== The BPF verifier checks the maximum number of call stack frames twice, first in the main CFG traversal (do_check) and then in a subsequent traversal (check_max_stack_depth). If the second check fails, it logs a 'verifier bug' warning and errors out, as the number of call stack frames should have been verified already. However, the second check may fail without indicating a verifier bug: if the excessive function calls reside in dead code, the main CFG traversal may not visit them; the subsequent traversal visits all instructions, including dead code. This case raises the question of how invalid dead code should be treated. The first patch implements the conservative option and rejects such code; the second adds a test case. ==================== Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2 parents 1da6c4d + cabacfb commit 61777f3

File tree

2 files changed

+41
-2
lines changed

2 files changed

+41
-2
lines changed

kernel/bpf/verifier.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1897,8 +1897,9 @@ static int check_max_stack_depth(struct bpf_verifier_env *env)
18971897
}
18981898
frame++;
18991899
if (frame >= MAX_CALL_FRAMES) {
1900-
WARN_ONCE(1, "verifier bug. Call stack is too deep\n");
1901-
return -EFAULT;
1900+
verbose(env, "the call stack of %d frames is too deep !\n",
1901+
frame);
1902+
return -E2BIG;
19021903
}
19031904
goto process_func;
19041905
}

tools/testing/selftests/bpf/verifier/calls.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -907,6 +907,44 @@
907907
.errstr = "call stack",
908908
.result = REJECT,
909909
},
910+
{
911+
"calls: stack depth check in dead code",
912+
.insns = {
913+
/* main */
914+
BPF_MOV64_IMM(BPF_REG_1, 0),
915+
BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call A */
916+
BPF_EXIT_INSN(),
917+
/* A */
918+
BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
919+
BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 2), /* call B */
920+
BPF_MOV64_IMM(BPF_REG_0, 0),
921+
BPF_EXIT_INSN(),
922+
/* B */
923+
BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call C */
924+
BPF_EXIT_INSN(),
925+
/* C */
926+
BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call D */
927+
BPF_EXIT_INSN(),
928+
/* D */
929+
BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call E */
930+
BPF_EXIT_INSN(),
931+
/* E */
932+
BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call F */
933+
BPF_EXIT_INSN(),
934+
/* F */
935+
BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call G */
936+
BPF_EXIT_INSN(),
937+
/* G */
938+
BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call H */
939+
BPF_EXIT_INSN(),
940+
/* H */
941+
BPF_MOV64_IMM(BPF_REG_0, 0),
942+
BPF_EXIT_INSN(),
943+
},
944+
.prog_type = BPF_PROG_TYPE_XDP,
945+
.errstr = "call stack",
946+
.result = REJECT,
947+
},
910948
{
911949
"calls: spill into caller stack frame",
912950
.insns = {

0 commit comments

Comments
 (0)