1 // SPDX-License-Identifier: GPL-2.0 2 /* Converted from tools/testing/selftests/bpf/verifier/cgroup_storage.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 struct { 10 __uint(type, BPF_MAP_TYPE_CGROUP_STORAGE); 11 __uint(max_entries, 0); 12 __type(key, struct bpf_cgroup_storage_key); 13 __type(value, char[TEST_DATA_LEN]); 14 } cgroup_storage SEC(".maps"); 15 16 struct { 17 __uint(type, BPF_MAP_TYPE_HASH); 18 __uint(max_entries, 1); 19 __type(key, long long); 20 __type(value, long long); 21 } map_hash_8b SEC(".maps"); 22 23 struct { 24 __uint(type, BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE); 25 __uint(max_entries, 0); 26 __type(key, struct bpf_cgroup_storage_key); 27 __type(value, char[64]); 28 } percpu_cgroup_storage SEC(".maps"); 29 30 SEC("cgroup/skb") 31 __description("valid cgroup storage access") 32 __success __success_unpriv __retval(0) 33 __naked void valid_cgroup_storage_access(void) 34 { 35 asm volatile (" \ 36 r2 = 0; \ 37 r1 = %[cgroup_storage] ll; \ 38 call %[bpf_get_local_storage]; \ 39 r1 = *(u32*)(r0 + 0); \ 40 r0 = r1; \ 41 r0 &= 1; \ 42 exit; \ 43 " : 44 : __imm(bpf_get_local_storage), 45 __imm_addr(cgroup_storage) 46 : __clobber_all); 47 } 48 49 SEC("cgroup/skb") 50 __description("invalid cgroup storage access 1") 51 __failure __msg("cannot pass map_type 1 into func bpf_get_local_storage") 52 __failure_unpriv 53 __naked void invalid_cgroup_storage_access_1(void) 54 { 55 asm volatile (" \ 56 r2 = 0; \ 57 r1 = %[map_hash_8b] ll; \ 58 call %[bpf_get_local_storage]; \ 59 r1 = *(u32*)(r0 + 0); \ 60 r0 = r1; \ 61 r0 &= 1; \ 62 exit; \ 63 " : 64 : __imm(bpf_get_local_storage), 65 __imm_addr(map_hash_8b) 66 : __clobber_all); 67 } 68 69 SEC("cgroup/skb") 70 __description("invalid cgroup storage access 2") 71 __failure __msg("fd 1 is not pointing to valid bpf_map") 72 __failure_unpriv 73 __naked void invalid_cgroup_storage_access_2(void) 74 { 75 asm volatile (" \ 76 r2 = 0; \ 77 .8byte %[ld_map_fd]; \ 78 .8byte 0; \ 79 call %[bpf_get_local_storage]; \ 80 r0 &= 1; \ 81 exit; \ 82 " : 83 : __imm(bpf_get_local_storage), 84 __imm_insn(ld_map_fd, BPF_RAW_INSN(BPF_LD | BPF_DW | BPF_IMM, BPF_REG_1, BPF_PSEUDO_MAP_FD, 0, 1)) 85 : __clobber_all); 86 } 87 88 SEC("cgroup/skb") 89 __description("invalid cgroup storage access 3") 90 __failure __msg("invalid access to map value, value_size=64 off=256 size=4") 91 __failure_unpriv 92 __naked void invalid_cgroup_storage_access_3(void) 93 { 94 asm volatile (" \ 95 r2 = 0; \ 96 r1 = %[cgroup_storage] ll; \ 97 call %[bpf_get_local_storage]; \ 98 r1 = *(u32*)(r0 + 256); \ 99 r1 += 1; \ 100 r0 = 0; \ 101 exit; \ 102 " : 103 : __imm(bpf_get_local_storage), 104 __imm_addr(cgroup_storage) 105 : __clobber_all); 106 } 107 108 SEC("cgroup/skb") 109 __description("invalid cgroup storage access 4") 110 __failure __msg("invalid access to map value, value_size=64 off=-2 size=4") 111 __failure_unpriv 112 __flag(BPF_F_ANY_ALIGNMENT) 113 __naked void invalid_cgroup_storage_access_4(void) 114 { 115 asm volatile (" \ 116 r2 = 0; \ 117 r1 = %[cgroup_storage] ll; \ 118 call %[bpf_get_local_storage]; \ 119 r1 = *(u32*)(r0 - 2); \ 120 r0 = r1; \ 121 r1 += 1; \ 122 exit; \ 123 " : 124 : __imm(bpf_get_local_storage), 125 __imm_addr(cgroup_storage) 126 : __clobber_all); 127 } 128 129 SEC("cgroup/skb") 130 __description("invalid cgroup storage access 5") 131 __failure __msg("get_local_storage() doesn't support non-zero flags") 132 __failure_unpriv 133 __naked void invalid_cgroup_storage_access_5(void) 134 { 135 asm volatile (" \ 136 r2 = 7; \ 137 r1 = %[cgroup_storage] ll; \ 138 call %[bpf_get_local_storage]; \ 139 r1 = *(u32*)(r0 + 0); \ 140 r0 = r1; \ 141 r0 &= 1; \ 142 exit; \ 143 " : 144 : __imm(bpf_get_local_storage), 145 __imm_addr(cgroup_storage) 146 : __clobber_all); 147 } 148 149 SEC("cgroup/skb") 150 __description("invalid cgroup storage access 6") 151 __failure __msg("get_local_storage() doesn't support non-zero flags") 152 __msg_unpriv("R2 leaks addr into helper function") 153 __naked void invalid_cgroup_storage_access_6(void) 154 { 155 asm volatile (" \ 156 r2 = r1; \ 157 r1 = %[cgroup_storage] ll; \ 158 call %[bpf_get_local_storage]; \ 159 r1 = *(u32*)(r0 + 0); \ 160 r0 = r1; \ 161 r0 &= 1; \ 162 exit; \ 163 " : 164 : __imm(bpf_get_local_storage), 165 __imm_addr(cgroup_storage) 166 : __clobber_all); 167 } 168 169 SEC("cgroup/skb") 170 __description("valid per-cpu cgroup storage access") 171 __success __success_unpriv __retval(0) 172 __naked void per_cpu_cgroup_storage_access(void) 173 { 174 asm volatile (" \ 175 r2 = 0; \ 176 r1 = %[percpu_cgroup_storage] ll; \ 177 call %[bpf_get_local_storage]; \ 178 r1 = *(u32*)(r0 + 0); \ 179 r0 = r1; \ 180 r0 &= 1; \ 181 exit; \ 182 " : 183 : __imm(bpf_get_local_storage), 184 __imm_addr(percpu_cgroup_storage) 185 : __clobber_all); 186 } 187 188 SEC("cgroup/skb") 189 __description("invalid per-cpu cgroup storage access 1") 190 __failure __msg("cannot pass map_type 1 into func bpf_get_local_storage") 191 __failure_unpriv 192 __naked void cpu_cgroup_storage_access_1(void) 193 { 194 asm volatile (" \ 195 r2 = 0; \ 196 r1 = %[map_hash_8b] ll; \ 197 call %[bpf_get_local_storage]; \ 198 r1 = *(u32*)(r0 + 0); \ 199 r0 = r1; \ 200 r0 &= 1; \ 201 exit; \ 202 " : 203 : __imm(bpf_get_local_storage), 204 __imm_addr(map_hash_8b) 205 : __clobber_all); 206 } 207 208 SEC("cgroup/skb") 209 __description("invalid per-cpu cgroup storage access 2") 210 __failure __msg("fd 1 is not pointing to valid bpf_map") 211 __failure_unpriv 212 __naked void cpu_cgroup_storage_access_2(void) 213 { 214 asm volatile (" \ 215 r2 = 0; \ 216 .8byte %[ld_map_fd]; \ 217 .8byte 0; \ 218 call %[bpf_get_local_storage]; \ 219 r0 &= 1; \ 220 exit; \ 221 " : 222 : __imm(bpf_get_local_storage), 223 __imm_insn(ld_map_fd, BPF_RAW_INSN(BPF_LD | BPF_DW | BPF_IMM, BPF_REG_1, BPF_PSEUDO_MAP_FD, 0, 1)) 224 : __clobber_all); 225 } 226 227 SEC("cgroup/skb") 228 __description("invalid per-cpu cgroup storage access 3") 229 __failure __msg("invalid access to map value, value_size=64 off=256 size=4") 230 __failure_unpriv 231 __naked void cpu_cgroup_storage_access_3(void) 232 { 233 asm volatile (" \ 234 r2 = 0; \ 235 r1 = %[percpu_cgroup_storage] ll; \ 236 call %[bpf_get_local_storage]; \ 237 r1 = *(u32*)(r0 + 256); \ 238 r1 += 1; \ 239 r0 = 0; \ 240 exit; \ 241 " : 242 : __imm(bpf_get_local_storage), 243 __imm_addr(percpu_cgroup_storage) 244 : __clobber_all); 245 } 246 247 SEC("cgroup/skb") 248 __description("invalid per-cpu cgroup storage access 4") 249 __failure __msg("invalid access to map value, value_size=64 off=-2 size=4") 250 __failure_unpriv 251 __flag(BPF_F_ANY_ALIGNMENT) 252 __naked void cpu_cgroup_storage_access_4(void) 253 { 254 asm volatile (" \ 255 r2 = 0; \ 256 r1 = %[cgroup_storage] ll; \ 257 call %[bpf_get_local_storage]; \ 258 r1 = *(u32*)(r0 - 2); \ 259 r0 = r1; \ 260 r1 += 1; \ 261 exit; \ 262 " : 263 : __imm(bpf_get_local_storage), 264 __imm_addr(cgroup_storage) 265 : __clobber_all); 266 } 267 268 SEC("cgroup/skb") 269 __description("invalid per-cpu cgroup storage access 5") 270 __failure __msg("get_local_storage() doesn't support non-zero flags") 271 __failure_unpriv 272 __naked void cpu_cgroup_storage_access_5(void) 273 { 274 asm volatile (" \ 275 r2 = 7; \ 276 r1 = %[percpu_cgroup_storage] ll; \ 277 call %[bpf_get_local_storage]; \ 278 r1 = *(u32*)(r0 + 0); \ 279 r0 = r1; \ 280 r0 &= 1; \ 281 exit; \ 282 " : 283 : __imm(bpf_get_local_storage), 284 __imm_addr(percpu_cgroup_storage) 285 : __clobber_all); 286 } 287 288 SEC("cgroup/skb") 289 __description("invalid per-cpu cgroup storage access 6") 290 __failure __msg("get_local_storage() doesn't support non-zero flags") 291 __msg_unpriv("R2 leaks addr into helper function") 292 __naked void cpu_cgroup_storage_access_6(void) 293 { 294 asm volatile (" \ 295 r2 = r1; \ 296 r1 = %[percpu_cgroup_storage] ll; \ 297 call %[bpf_get_local_storage]; \ 298 r1 = *(u32*)(r0 + 0); \ 299 r0 = r1; \ 300 r0 &= 1; \ 301 exit; \ 302 " : 303 : __imm(bpf_get_local_storage), 304 __imm_addr(percpu_cgroup_storage) 305 : __clobber_all); 306 } 307 308 char _license[] SEC("license") = "GPL"; 309