selftests/bpf: add more test cases for check_cfg()
authorAndrii Nakryiko <andrii@kernel.org>
Fri, 10 Nov 2023 06:14:11 +0000 (22:14 -0800)
committerAlexei Starovoitov <ast@kernel.org>
Fri, 10 Nov 2023 06:57:25 +0000 (22:57 -0800)
Add a few more simple cases to validate proper privileged vs unprivileged
loop detection behavior. conditional_loop2 is the one reported by Hao
Sun that triggered this set of fixes.

Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Suggested-by: Hao Sun <sunhao.th@gmail.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/r/20231110061412.2995786-2-andrii@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/progs/verifier_cfg.c

index df7697b94007b12d8958738c1b38d444c10c5eff..c1f55e1d80a426f3b87c2f13a74176f19bb18e28 100644 (file)
@@ -97,4 +97,66 @@ l0_%=:       r2 = r0;                                        \
 "      ::: __clobber_all);
 }
 
+SEC("socket")
+__description("conditional loop (2)")
+__success
+__failure_unpriv __msg_unpriv("back-edge from insn 10 to 11")
+__naked void conditional_loop2(void)
+{
+       asm volatile ("                                 \
+       r9 = 2 ll;                                      \
+       r3 = 0x20 ll;                                   \
+       r4 = 0x35 ll;                                   \
+       r8 = r4;                                        \
+       goto l1_%=;                                     \
+l0_%=: r9 -= r3;                                       \
+       r9 -= r4;                                       \
+       r9 -= r8;                                       \
+l1_%=: r8 += r4;                                       \
+       if r8 < 0x64 goto l0_%=;                        \
+       r0 = r9;                                        \
+       exit;                                           \
+"      ::: __clobber_all);
+}
+
+SEC("socket")
+__description("unconditional loop after conditional jump")
+__failure __msg("infinite loop detected")
+__failure_unpriv __msg_unpriv("back-edge from insn 3 to 2")
+__naked void uncond_loop_after_cond_jmp(void)
+{
+       asm volatile ("                                 \
+       r0 = 0;                                         \
+       if r0 > 0 goto l1_%=;                           \
+l0_%=: r0 = 1;                                         \
+       goto l0_%=;                                     \
+l1_%=: exit;                                           \
+"      ::: __clobber_all);
+}
+
+
+__naked __noinline __used
+static unsigned long never_ending_subprog()
+{
+       asm volatile ("                                 \
+       r0 = r1;                                        \
+       goto -1;                                        \
+"      ::: __clobber_all);
+}
+
+SEC("socket")
+__description("unconditional loop after conditional jump")
+/* infinite loop is detected *after* check_cfg() */
+__failure __msg("infinite loop detected")
+__naked void uncond_loop_in_subprog_after_cond_jmp(void)
+{
+       asm volatile ("                                 \
+       r0 = 0;                                         \
+       if r0 > 0 goto l1_%=;                           \
+l0_%=: r0 += 1;                                        \
+       call never_ending_subprog;                      \
+l1_%=: exit;                                           \
+"      ::: __clobber_all);
+}
+
 char _license[] SEC("license") = "GPL";