0001
0002 #include <vmlinux.h>
0003 #include <bpf/bpf_tracing.h>
0004 #include <bpf/bpf_helpers.h>
0005 #include <bpf/bpf_core_read.h>
0006
0007 struct map_value {
0008 char buf[8];
0009 struct prog_test_ref_kfunc __kptr *unref_ptr;
0010 struct prog_test_ref_kfunc __kptr_ref *ref_ptr;
0011 struct prog_test_member __kptr_ref *ref_memb_ptr;
0012 };
0013
0014 struct array_map {
0015 __uint(type, BPF_MAP_TYPE_ARRAY);
0016 __type(key, int);
0017 __type(value, struct map_value);
0018 __uint(max_entries, 1);
0019 } array_map SEC(".maps");
0020
0021 extern struct prog_test_ref_kfunc *bpf_kfunc_call_test_acquire(unsigned long *sp) __ksym;
0022 extern struct prog_test_ref_kfunc *
0023 bpf_kfunc_call_test_kptr_get(struct prog_test_ref_kfunc **p, int a, int b) __ksym;
0024
0025 SEC("?tc")
0026 int size_not_bpf_dw(struct __sk_buff *ctx)
0027 {
0028 struct map_value *v;
0029 int key = 0;
0030
0031 v = bpf_map_lookup_elem(&array_map, &key);
0032 if (!v)
0033 return 0;
0034
0035 *(u32 *)&v->unref_ptr = 0;
0036 return 0;
0037 }
0038
0039 SEC("?tc")
0040 int non_const_var_off(struct __sk_buff *ctx)
0041 {
0042 struct map_value *v;
0043 int key = 0, id;
0044
0045 v = bpf_map_lookup_elem(&array_map, &key);
0046 if (!v)
0047 return 0;
0048
0049 id = ctx->protocol;
0050 if (id < 4 || id > 12)
0051 return 0;
0052 *(u64 *)((void *)v + id) = 0;
0053
0054 return 0;
0055 }
0056
0057 SEC("?tc")
0058 int non_const_var_off_kptr_xchg(struct __sk_buff *ctx)
0059 {
0060 struct map_value *v;
0061 int key = 0, id;
0062
0063 v = bpf_map_lookup_elem(&array_map, &key);
0064 if (!v)
0065 return 0;
0066
0067 id = ctx->protocol;
0068 if (id < 4 || id > 12)
0069 return 0;
0070 bpf_kptr_xchg((void *)v + id, NULL);
0071
0072 return 0;
0073 }
0074
0075 SEC("?tc")
0076 int misaligned_access_write(struct __sk_buff *ctx)
0077 {
0078 struct map_value *v;
0079 int key = 0;
0080
0081 v = bpf_map_lookup_elem(&array_map, &key);
0082 if (!v)
0083 return 0;
0084
0085 *(void **)((void *)v + 7) = NULL;
0086
0087 return 0;
0088 }
0089
0090 SEC("?tc")
0091 int misaligned_access_read(struct __sk_buff *ctx)
0092 {
0093 struct map_value *v;
0094 int key = 0;
0095
0096 v = bpf_map_lookup_elem(&array_map, &key);
0097 if (!v)
0098 return 0;
0099
0100 return *(u64 *)((void *)v + 1);
0101 }
0102
0103 SEC("?tc")
0104 int reject_var_off_store(struct __sk_buff *ctx)
0105 {
0106 struct prog_test_ref_kfunc *unref_ptr;
0107 struct map_value *v;
0108 int key = 0, id;
0109
0110 v = bpf_map_lookup_elem(&array_map, &key);
0111 if (!v)
0112 return 0;
0113
0114 unref_ptr = v->unref_ptr;
0115 if (!unref_ptr)
0116 return 0;
0117 id = ctx->protocol;
0118 if (id < 4 || id > 12)
0119 return 0;
0120 unref_ptr += id;
0121 v->unref_ptr = unref_ptr;
0122
0123 return 0;
0124 }
0125
0126 SEC("?tc")
0127 int reject_bad_type_match(struct __sk_buff *ctx)
0128 {
0129 struct prog_test_ref_kfunc *unref_ptr;
0130 struct map_value *v;
0131 int key = 0;
0132
0133 v = bpf_map_lookup_elem(&array_map, &key);
0134 if (!v)
0135 return 0;
0136
0137 unref_ptr = v->unref_ptr;
0138 if (!unref_ptr)
0139 return 0;
0140 unref_ptr = (void *)unref_ptr + 4;
0141 v->unref_ptr = unref_ptr;
0142
0143 return 0;
0144 }
0145
0146 SEC("?tc")
0147 int marked_as_untrusted_or_null(struct __sk_buff *ctx)
0148 {
0149 struct map_value *v;
0150 int key = 0;
0151
0152 v = bpf_map_lookup_elem(&array_map, &key);
0153 if (!v)
0154 return 0;
0155
0156 bpf_this_cpu_ptr(v->unref_ptr);
0157 return 0;
0158 }
0159
0160 SEC("?tc")
0161 int correct_btf_id_check_size(struct __sk_buff *ctx)
0162 {
0163 struct prog_test_ref_kfunc *p;
0164 struct map_value *v;
0165 int key = 0;
0166
0167 v = bpf_map_lookup_elem(&array_map, &key);
0168 if (!v)
0169 return 0;
0170
0171 p = v->unref_ptr;
0172 if (!p)
0173 return 0;
0174 return *(int *)((void *)p + bpf_core_type_size(struct prog_test_ref_kfunc));
0175 }
0176
0177 SEC("?tc")
0178 int inherit_untrusted_on_walk(struct __sk_buff *ctx)
0179 {
0180 struct prog_test_ref_kfunc *unref_ptr;
0181 struct map_value *v;
0182 int key = 0;
0183
0184 v = bpf_map_lookup_elem(&array_map, &key);
0185 if (!v)
0186 return 0;
0187
0188 unref_ptr = v->unref_ptr;
0189 if (!unref_ptr)
0190 return 0;
0191 unref_ptr = unref_ptr->next;
0192 bpf_this_cpu_ptr(unref_ptr);
0193 return 0;
0194 }
0195
0196 SEC("?tc")
0197 int reject_kptr_xchg_on_unref(struct __sk_buff *ctx)
0198 {
0199 struct map_value *v;
0200 int key = 0;
0201
0202 v = bpf_map_lookup_elem(&array_map, &key);
0203 if (!v)
0204 return 0;
0205
0206 bpf_kptr_xchg(&v->unref_ptr, NULL);
0207 return 0;
0208 }
0209
0210 SEC("?tc")
0211 int reject_kptr_get_no_map_val(struct __sk_buff *ctx)
0212 {
0213 bpf_kfunc_call_test_kptr_get((void *)&ctx, 0, 0);
0214 return 0;
0215 }
0216
0217 SEC("?tc")
0218 int reject_kptr_get_no_null_map_val(struct __sk_buff *ctx)
0219 {
0220 bpf_kfunc_call_test_kptr_get(bpf_map_lookup_elem(&array_map, &(int){0}), 0, 0);
0221 return 0;
0222 }
0223
0224 SEC("?tc")
0225 int reject_kptr_get_no_kptr(struct __sk_buff *ctx)
0226 {
0227 struct map_value *v;
0228 int key = 0;
0229
0230 v = bpf_map_lookup_elem(&array_map, &key);
0231 if (!v)
0232 return 0;
0233
0234 bpf_kfunc_call_test_kptr_get((void *)v, 0, 0);
0235 return 0;
0236 }
0237
0238 SEC("?tc")
0239 int reject_kptr_get_on_unref(struct __sk_buff *ctx)
0240 {
0241 struct map_value *v;
0242 int key = 0;
0243
0244 v = bpf_map_lookup_elem(&array_map, &key);
0245 if (!v)
0246 return 0;
0247
0248 bpf_kfunc_call_test_kptr_get(&v->unref_ptr, 0, 0);
0249 return 0;
0250 }
0251
0252 SEC("?tc")
0253 int reject_kptr_get_bad_type_match(struct __sk_buff *ctx)
0254 {
0255 struct map_value *v;
0256 int key = 0;
0257
0258 v = bpf_map_lookup_elem(&array_map, &key);
0259 if (!v)
0260 return 0;
0261
0262 bpf_kfunc_call_test_kptr_get((void *)&v->ref_memb_ptr, 0, 0);
0263 return 0;
0264 }
0265
0266 SEC("?tc")
0267 int mark_ref_as_untrusted_or_null(struct __sk_buff *ctx)
0268 {
0269 struct map_value *v;
0270 int key = 0;
0271
0272 v = bpf_map_lookup_elem(&array_map, &key);
0273 if (!v)
0274 return 0;
0275
0276 bpf_this_cpu_ptr(v->ref_ptr);
0277 return 0;
0278 }
0279
0280 SEC("?tc")
0281 int reject_untrusted_store_to_ref(struct __sk_buff *ctx)
0282 {
0283 struct prog_test_ref_kfunc *p;
0284 struct map_value *v;
0285 int key = 0;
0286
0287 v = bpf_map_lookup_elem(&array_map, &key);
0288 if (!v)
0289 return 0;
0290
0291 p = v->ref_ptr;
0292 if (!p)
0293 return 0;
0294
0295 *(struct prog_test_ref_kfunc * volatile *)&v->ref_ptr = p;
0296 return 0;
0297 }
0298
0299 SEC("?tc")
0300 int reject_untrusted_xchg(struct __sk_buff *ctx)
0301 {
0302 struct prog_test_ref_kfunc *p;
0303 struct map_value *v;
0304 int key = 0;
0305
0306 v = bpf_map_lookup_elem(&array_map, &key);
0307 if (!v)
0308 return 0;
0309
0310 p = v->ref_ptr;
0311 if (!p)
0312 return 0;
0313 bpf_kptr_xchg(&v->ref_ptr, p);
0314 return 0;
0315 }
0316
0317 SEC("?tc")
0318 int reject_bad_type_xchg(struct __sk_buff *ctx)
0319 {
0320 struct prog_test_ref_kfunc *ref_ptr;
0321 struct map_value *v;
0322 int key = 0;
0323
0324 v = bpf_map_lookup_elem(&array_map, &key);
0325 if (!v)
0326 return 0;
0327
0328 ref_ptr = bpf_kfunc_call_test_acquire(&(unsigned long){0});
0329 if (!ref_ptr)
0330 return 0;
0331 bpf_kptr_xchg(&v->ref_memb_ptr, ref_ptr);
0332 return 0;
0333 }
0334
0335 SEC("?tc")
0336 int reject_member_of_ref_xchg(struct __sk_buff *ctx)
0337 {
0338 struct prog_test_ref_kfunc *ref_ptr;
0339 struct map_value *v;
0340 int key = 0;
0341
0342 v = bpf_map_lookup_elem(&array_map, &key);
0343 if (!v)
0344 return 0;
0345
0346 ref_ptr = bpf_kfunc_call_test_acquire(&(unsigned long){0});
0347 if (!ref_ptr)
0348 return 0;
0349 bpf_kptr_xchg(&v->ref_memb_ptr, &ref_ptr->memb);
0350 return 0;
0351 }
0352
0353 SEC("?syscall")
0354 int reject_indirect_helper_access(struct __sk_buff *ctx)
0355 {
0356 struct map_value *v;
0357 int key = 0;
0358
0359 v = bpf_map_lookup_elem(&array_map, &key);
0360 if (!v)
0361 return 0;
0362
0363 bpf_get_current_comm(v, sizeof(v->buf) + 1);
0364 return 0;
0365 }
0366
0367 __noinline
0368 int write_func(int *p)
0369 {
0370 return p ? *p = 42 : 0;
0371 }
0372
0373 SEC("?tc")
0374 int reject_indirect_global_func_access(struct __sk_buff *ctx)
0375 {
0376 struct map_value *v;
0377 int key = 0;
0378
0379 v = bpf_map_lookup_elem(&array_map, &key);
0380 if (!v)
0381 return 0;
0382
0383 return write_func((void *)v + 5);
0384 }
0385
0386 SEC("?tc")
0387 int kptr_xchg_ref_state(struct __sk_buff *ctx)
0388 {
0389 struct prog_test_ref_kfunc *p;
0390 struct map_value *v;
0391 int key = 0;
0392
0393 v = bpf_map_lookup_elem(&array_map, &key);
0394 if (!v)
0395 return 0;
0396
0397 p = bpf_kfunc_call_test_acquire(&(unsigned long){0});
0398 if (!p)
0399 return 0;
0400 bpf_kptr_xchg(&v->ref_ptr, p);
0401 return 0;
0402 }
0403
0404 SEC("?tc")
0405 int kptr_get_ref_state(struct __sk_buff *ctx)
0406 {
0407 struct map_value *v;
0408 int key = 0;
0409
0410 v = bpf_map_lookup_elem(&array_map, &key);
0411 if (!v)
0412 return 0;
0413
0414 bpf_kfunc_call_test_kptr_get(&v->ref_ptr, 0, 0);
0415 return 0;
0416 }
0417
0418 char _license[] SEC("license") = "GPL";