1 // SPDX-License-Identifier: GPL-2.0 2 /* Converted from tools/testing/selftests/bpf/verifier/cfg.c */ 3 4 #include <linux/bpf.h> 5 #include <bpf/bpf_helpers.h> 6 #include "../../../include/linux/filter.h" 7 #include "bpf_misc.h" 8 9 SEC("socket") 10 __description("unreachable") 11 __failure __msg("unreachable") 12 __failure_unpriv unreachable(void)13__naked void unreachable(void) 14 { 15 asm volatile (" \ 16 exit; \ 17 exit; \ 18 " ::: __clobber_all); 19 } 20 21 SEC("socket") 22 __description("unreachable2") 23 __failure __msg("unreachable") 24 __failure_unpriv unreachable2(void)25__naked void unreachable2(void) 26 { 27 asm volatile (" \ 28 goto l0_%=; \ 29 goto l0_%=; \ 30 l0_%=: exit; \ 31 " ::: __clobber_all); 32 } 33 34 SEC("socket") 35 __description("out of range jump") 36 __failure __msg("jump out of range") 37 __failure_unpriv out_of_range_jump(void)38__naked void out_of_range_jump(void) 39 { 40 asm volatile (" \ 41 goto l0_%=; \ 42 exit; \ 43 l0_%=: \ 44 " ::: __clobber_all); 45 } 46 47 SEC("socket") 48 __description("out of range jump2") 49 __failure __msg("jump out of range") 50 __failure_unpriv out_of_range_jump2(void)51__naked void out_of_range_jump2(void) 52 { 53 asm volatile (" \ 54 goto -2; \ 55 exit; \ 56 " ::: __clobber_all); 57 } 58 59 SEC("socket") 60 __description("invalid DW LDSX instruction in diagnostics") 61 __failure __msg("BUG_ldx_99") 62 __log_level(2) invalid_dw_ldsx(void)63__naked void invalid_dw_ldsx(void) 64 { 65 asm volatile (" \ 66 .8byte %[ldsx_dw]; \ 67 " : 68 : __imm_insn(ldsx_dw, BPF_RAW_INSN(BPF_LDX | BPF_MEMSX | BPF_DW, BPF_REG_0, BPF_REG_0, 0, 0)) 69 : __clobber_all); 70 } 71 72 SEC("socket") 73 __description("loop (back-edge)") 74 __failure __msg("unreachable insn 1") 75 __msg_unpriv("back-edge") loop_back_edge(void)76__naked void loop_back_edge(void) 77 { 78 asm volatile (" \ 79 l0_%=: goto l0_%=; \ 80 exit; \ 81 " ::: __clobber_all); 82 } 83 84 SEC("socket") 85 __description("loop2 (back-edge)") 86 __failure __msg("unreachable insn 4") 87 __msg_unpriv("back-edge") loop2_back_edge(void)88__naked void loop2_back_edge(void) 89 { 90 asm volatile (" \ 91 l0_%=: r1 = r0; \ 92 r2 = r0; \ 93 r3 = r0; \ 94 goto l0_%=; \ 95 exit; \ 96 " ::: __clobber_all); 97 } 98 99 SEC("socket") 100 __description("conditional loop") 101 __failure __msg("infinite loop detected") 102 __msg_unpriv("back-edge") conditional_loop(void)103__naked void conditional_loop(void) 104 { 105 asm volatile (" \ 106 r0 = r1; \ 107 l0_%=: r2 = r0; \ 108 r3 = r0; \ 109 if r1 == 0 goto l0_%=; \ 110 exit; \ 111 " ::: __clobber_all); 112 } 113 114 SEC("socket") 115 __description("conditional loop (2)") 116 __success 117 __failure_unpriv __msg_unpriv("back-edge from insn 10 to 11") conditional_loop2(void)118__naked void conditional_loop2(void) 119 { 120 asm volatile (" \ 121 r9 = 2 ll; \ 122 r3 = 0x20 ll; \ 123 r4 = 0x35 ll; \ 124 r8 = r4; \ 125 goto l1_%=; \ 126 l0_%=: r9 -= r3; \ 127 r9 -= r4; \ 128 r9 -= r8; \ 129 l1_%=: r8 += r4; \ 130 if r8 < 0x64 goto l0_%=; \ 131 r0 = r9; \ 132 exit; \ 133 " ::: __clobber_all); 134 } 135 136 SEC("socket") 137 __description("unconditional loop after conditional jump") 138 __failure __msg("infinite loop detected") 139 __failure_unpriv __msg_unpriv("back-edge from insn 3 to 2") uncond_loop_after_cond_jmp(void)140__naked void uncond_loop_after_cond_jmp(void) 141 { 142 asm volatile (" \ 143 r0 = 0; \ 144 if r0 > 0 goto l1_%=; \ 145 l0_%=: r0 = 1; \ 146 goto l0_%=; \ 147 l1_%=: exit; \ 148 " ::: __clobber_all); 149 } 150 151 152 __naked __noinline __used never_ending_subprog()153static unsigned long never_ending_subprog() 154 { 155 asm volatile (" \ 156 r0 = r1; \ 157 goto -1; \ 158 " ::: __clobber_all); 159 } 160 161 SEC("socket") 162 __description("unconditional loop after conditional jump") 163 /* infinite loop is detected *after* check_cfg() */ 164 __failure __msg("infinite loop detected") uncond_loop_in_subprog_after_cond_jmp(void)165__naked void uncond_loop_in_subprog_after_cond_jmp(void) 166 { 167 asm volatile (" \ 168 r0 = 0; \ 169 if r0 > 0 goto l1_%=; \ 170 l0_%=: r0 += 1; \ 171 call never_ending_subprog; \ 172 l1_%=: exit; \ 173 " ::: __clobber_all); 174 } 175 176 char _license[] SEC("license") = "GPL"; 177