Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
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     /* Checkmate, clang */
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";