1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */ 3 4 #include <vmlinux.h> 5 #include <bpf/bpf_helpers.h> 6 #include "bpf_experimental.h" 7 #include "bpf_misc.h" 8 #include "uptr_test_common.h" 9 10 struct { 11 __uint(type, BPF_MAP_TYPE_TASK_STORAGE); 12 __uint(map_flags, BPF_F_NO_PREALLOC); 13 __type(key, int); 14 __type(value, struct value_type); 15 } datamap SEC(".maps"); 16 17 SEC("?syscall") 18 __failure __msg("store to uptr disallowed") 19 int uptr_write(const void *ctx) 20 { 21 struct task_struct *task; 22 struct value_type *v; 23 24 task = bpf_get_current_task_btf(); 25 v = bpf_task_storage_get(&datamap, task, 0, 26 BPF_LOCAL_STORAGE_GET_F_CREATE); 27 if (!v) 28 return 0; 29 30 v->udata = NULL; 31 return 0; 32 } 33 34 SEC("?syscall") 35 __failure __msg("store to uptr disallowed") 36 int uptr_write_nested(const void *ctx) 37 { 38 struct task_struct *task; 39 struct value_type *v; 40 41 task = bpf_get_current_task_btf(); 42 v = bpf_task_storage_get(&datamap, task, 0, 43 BPF_LOCAL_STORAGE_GET_F_CREATE); 44 if (!v) 45 return 0; 46 47 v->nested.udata = NULL; 48 return 0; 49 } 50 51 SEC("?syscall") 52 __failure __msg("R1 invalid mem access 'mem_or_null'") 53 int uptr_no_null_check(const void *ctx) 54 { 55 struct task_struct *task; 56 struct value_type *v; 57 58 task = bpf_get_current_task_btf(); 59 v = bpf_task_storage_get(&datamap, task, 0, 60 BPF_LOCAL_STORAGE_GET_F_CREATE); 61 if (!v) 62 return 0; 63 64 v->udata->result = 0; 65 66 return 0; 67 } 68 69 SEC("?syscall") 70 __failure __msg("doesn't point to kptr") 71 int uptr_kptr_xchg(const void *ctx) 72 { 73 struct task_struct *task; 74 struct value_type *v; 75 76 task = bpf_get_current_task_btf(); 77 v = bpf_task_storage_get(&datamap, task, 0, 78 BPF_LOCAL_STORAGE_GET_F_CREATE); 79 if (!v) 80 return 0; 81 82 bpf_kptr_xchg(&v->udata, NULL); 83 84 return 0; 85 } 86 87 SEC("?syscall") 88 __failure __msg("invalid mem access 'scalar'") 89 int uptr_obj_new(const void *ctx) 90 { 91 struct value_type *v; 92 93 v = bpf_obj_new(typeof(*v)); 94 if (!v) 95 return 0; 96 97 if (v->udata) 98 v->udata->result = 0; 99 100 bpf_obj_drop(v); 101 102 return 0; 103 } 104 105 char _license[] SEC("license") = "GPL"; 106