Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/bpf: add more test cases for check_cfg()

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>

authored by

Andrii Nakryiko and committed by
Alexei Starovoitov
e2e57d63 10e14e96

+62
+62
tools/testing/selftests/bpf/progs/verifier_cfg.c
··· 97 97 " ::: __clobber_all); 98 98 } 99 99 100 + SEC("socket") 101 + __description("conditional loop (2)") 102 + __success 103 + __failure_unpriv __msg_unpriv("back-edge from insn 10 to 11") 104 + __naked void conditional_loop2(void) 105 + { 106 + asm volatile (" \ 107 + r9 = 2 ll; \ 108 + r3 = 0x20 ll; \ 109 + r4 = 0x35 ll; \ 110 + r8 = r4; \ 111 + goto l1_%=; \ 112 + l0_%=: r9 -= r3; \ 113 + r9 -= r4; \ 114 + r9 -= r8; \ 115 + l1_%=: r8 += r4; \ 116 + if r8 < 0x64 goto l0_%=; \ 117 + r0 = r9; \ 118 + exit; \ 119 + " ::: __clobber_all); 120 + } 121 + 122 + SEC("socket") 123 + __description("unconditional loop after conditional jump") 124 + __failure __msg("infinite loop detected") 125 + __failure_unpriv __msg_unpriv("back-edge from insn 3 to 2") 126 + __naked void uncond_loop_after_cond_jmp(void) 127 + { 128 + asm volatile (" \ 129 + r0 = 0; \ 130 + if r0 > 0 goto l1_%=; \ 131 + l0_%=: r0 = 1; \ 132 + goto l0_%=; \ 133 + l1_%=: exit; \ 134 + " ::: __clobber_all); 135 + } 136 + 137 + 138 + __naked __noinline __used 139 + static unsigned long never_ending_subprog() 140 + { 141 + asm volatile (" \ 142 + r0 = r1; \ 143 + goto -1; \ 144 + " ::: __clobber_all); 145 + } 146 + 147 + SEC("socket") 148 + __description("unconditional loop after conditional jump") 149 + /* infinite loop is detected *after* check_cfg() */ 150 + __failure __msg("infinite loop detected") 151 + __naked void uncond_loop_in_subprog_after_cond_jmp(void) 152 + { 153 + asm volatile (" \ 154 + r0 = 0; \ 155 + if r0 > 0 goto l1_%=; \ 156 + l0_%=: r0 += 1; \ 157 + call never_ending_subprog; \ 158 + l1_%=: exit; \ 159 + " ::: __clobber_all); 160 + } 161 + 100 162 char _license[] SEC("license") = "GPL";