1 // SPDX-License-Identifier: GPL-2.0 2 /* Converted from tools/testing/selftests/bpf/verifier/ctx.c */ 3 4 #include <linux/bpf.h> 5 #include <bpf/bpf_helpers.h> 6 #include "bpf_misc.h" 7 8 SEC("tc") 9 __description("context stores via BPF_ATOMIC") 10 __failure __msg("BPF_ATOMIC stores into R1 ctx is not allowed") 11 __naked void context_stores_via_bpf_atomic(void) 12 { 13 asm volatile (" \ 14 r0 = 0; \ 15 lock *(u32 *)(r1 + %[__sk_buff_mark]) += w0; \ 16 exit; \ 17 " : 18 : __imm_const(__sk_buff_mark, offsetof(struct __sk_buff, mark)) 19 : __clobber_all); 20 } 21 22 SEC("tc") 23 __description("arithmetic ops make PTR_TO_CTX unusable") 24 __failure __msg("dereference of modified ctx ptr") 25 __naked void make_ptr_to_ctx_unusable(void) 26 { 27 asm volatile (" \ 28 r1 += %[__imm_0]; \ 29 r0 = *(u32*)(r1 + %[__sk_buff_mark]); \ 30 exit; \ 31 " : 32 : __imm_const(__imm_0, 33 offsetof(struct __sk_buff, data) - offsetof(struct __sk_buff, mark)), 34 __imm_const(__sk_buff_mark, offsetof(struct __sk_buff, mark)) 35 : __clobber_all); 36 } 37 38 SEC("tc") 39 __description("pass unmodified ctx pointer to helper") 40 __success __retval(0) 41 __naked void unmodified_ctx_pointer_to_helper(void) 42 { 43 asm volatile (" \ 44 r2 = 0; \ 45 call %[bpf_csum_update]; \ 46 r0 = 0; \ 47 exit; \ 48 " : 49 : __imm(bpf_csum_update) 50 : __clobber_all); 51 } 52 53 SEC("tc") 54 __description("pass modified ctx pointer to helper, 1") 55 __failure __msg("negative offset ctx ptr R1 off=-612 disallowed") 56 __naked void ctx_pointer_to_helper_1(void) 57 { 58 asm volatile (" \ 59 r1 += -612; \ 60 r2 = 0; \ 61 call %[bpf_csum_update]; \ 62 r0 = 0; \ 63 exit; \ 64 " : 65 : __imm(bpf_csum_update) 66 : __clobber_all); 67 } 68 69 SEC("socket") 70 __description("pass modified ctx pointer to helper, 2") 71 __failure __msg("negative offset ctx ptr R1 off=-612 disallowed") 72 __failure_unpriv __msg_unpriv("negative offset ctx ptr R1 off=-612 disallowed") 73 __naked void ctx_pointer_to_helper_2(void) 74 { 75 asm volatile (" \ 76 r1 += -612; \ 77 call %[bpf_get_socket_cookie]; \ 78 r0 = 0; \ 79 exit; \ 80 " : 81 : __imm(bpf_get_socket_cookie) 82 : __clobber_all); 83 } 84 85 SEC("tc") 86 __description("pass modified ctx pointer to helper, 3") 87 __failure __msg("variable ctx access var_off=(0x0; 0x4)") 88 __naked void ctx_pointer_to_helper_3(void) 89 { 90 asm volatile (" \ 91 r3 = *(u32*)(r1 + 0); \ 92 r3 &= 4; \ 93 r1 += r3; \ 94 r2 = 0; \ 95 call %[bpf_csum_update]; \ 96 r0 = 0; \ 97 exit; \ 98 " : 99 : __imm(bpf_csum_update) 100 : __clobber_all); 101 } 102 103 SEC("cgroup/sendmsg6") 104 __description("pass ctx or null check, 1: ctx") 105 __success 106 __naked void or_null_check_1_ctx(void) 107 { 108 asm volatile (" \ 109 call %[bpf_get_netns_cookie]; \ 110 r0 = 0; \ 111 exit; \ 112 " : 113 : __imm(bpf_get_netns_cookie) 114 : __clobber_all); 115 } 116 117 SEC("cgroup/sendmsg6") 118 __description("pass ctx or null check, 2: null") 119 __success 120 __naked void or_null_check_2_null(void) 121 { 122 asm volatile (" \ 123 r1 = 0; \ 124 call %[bpf_get_netns_cookie]; \ 125 r0 = 0; \ 126 exit; \ 127 " : 128 : __imm(bpf_get_netns_cookie) 129 : __clobber_all); 130 } 131 132 SEC("cgroup/sendmsg6") 133 __description("pass ctx or null check, 3: 1") 134 __failure __msg("R1 type=scalar expected=ctx") 135 __naked void or_null_check_3_1(void) 136 { 137 asm volatile (" \ 138 r1 = 1; \ 139 call %[bpf_get_netns_cookie]; \ 140 r0 = 0; \ 141 exit; \ 142 " : 143 : __imm(bpf_get_netns_cookie) 144 : __clobber_all); 145 } 146 147 SEC("cgroup/sendmsg6") 148 __description("pass ctx or null check, 4: ctx - const") 149 __failure __msg("negative offset ctx ptr R1 off=-612 disallowed") 150 __naked void null_check_4_ctx_const(void) 151 { 152 asm volatile (" \ 153 r1 += -612; \ 154 call %[bpf_get_netns_cookie]; \ 155 r0 = 0; \ 156 exit; \ 157 " : 158 : __imm(bpf_get_netns_cookie) 159 : __clobber_all); 160 } 161 162 SEC("cgroup/connect4") 163 __description("pass ctx or null check, 5: null (connect)") 164 __success 165 __naked void null_check_5_null_connect(void) 166 { 167 asm volatile (" \ 168 r1 = 0; \ 169 call %[bpf_get_netns_cookie]; \ 170 r0 = 0; \ 171 exit; \ 172 " : 173 : __imm(bpf_get_netns_cookie) 174 : __clobber_all); 175 } 176 177 SEC("cgroup/post_bind4") 178 __description("pass ctx or null check, 6: null (bind)") 179 __success 180 __naked void null_check_6_null_bind(void) 181 { 182 asm volatile (" \ 183 r1 = 0; \ 184 call %[bpf_get_netns_cookie]; \ 185 r0 = 0; \ 186 exit; \ 187 " : 188 : __imm(bpf_get_netns_cookie) 189 : __clobber_all); 190 } 191 192 SEC("cgroup/post_bind4") 193 __description("pass ctx or null check, 7: ctx (bind)") 194 __success 195 __naked void null_check_7_ctx_bind(void) 196 { 197 asm volatile (" \ 198 call %[bpf_get_socket_cookie]; \ 199 r0 = 0; \ 200 exit; \ 201 " : 202 : __imm(bpf_get_socket_cookie) 203 : __clobber_all); 204 } 205 206 SEC("cgroup/post_bind4") 207 __description("pass ctx or null check, 8: null (bind)") 208 __failure __msg("R1 type=scalar expected=ctx") 209 __naked void null_check_8_null_bind(void) 210 { 211 asm volatile (" \ 212 r1 = 0; \ 213 call %[bpf_get_socket_cookie]; \ 214 r0 = 0; \ 215 exit; \ 216 " : 217 : __imm(bpf_get_socket_cookie) 218 : __clobber_all); 219 } 220 221 char _license[] SEC("license") = "GPL"; 222