xref: /linux/tools/testing/selftests/bpf/progs/percpu_alloc_fail.c (revision 59fff63cc2b75dcfe08f9eeb4b2187d73e53843d)
1 #include "bpf_experimental.h"
2 #include "bpf_misc.h"
3 
4 struct val_t {
5 	long b, c, d;
6 };
7 
8 struct val2_t {
9 	long b;
10 };
11 
12 struct val_with_ptr_t {
13 	char *p;
14 };
15 
16 struct val_with_rb_root_t {
17 	struct bpf_spin_lock lock;
18 };
19 
20 struct elem {
21 	long sum;
22 	struct val_t __percpu_kptr *pc;
23 };
24 
25 struct {
26 	__uint(type, BPF_MAP_TYPE_ARRAY);
27 	__uint(max_entries, 1);
28 	__type(key, int);
29 	__type(value, struct elem);
30 } array SEC(".maps");
31 
32 long ret;
33 
34 SEC("?fentry/bpf_fentry_test1")
35 __failure __msg("store to referenced kptr disallowed")
36 int BPF_PROG(test_array_map_1)
37 {
38 	struct val_t __percpu_kptr *p;
39 	struct elem *e;
40 	int index = 0;
41 
42 	e = bpf_map_lookup_elem(&array, &index);
43 	if (!e)
44 		return 0;
45 
46 	p = bpf_percpu_obj_new(struct val_t);
47 	if (!p)
48 		return 0;
49 
50 	p = bpf_kptr_xchg(&e->pc, p);
51 	if (p)
52 		bpf_percpu_obj_drop(p);
53 
54 	e->pc = (struct val_t __percpu_kptr *)ret;
55 	return 0;
56 }
57 
58 SEC("?fentry/bpf_fentry_test1")
59 __failure __msg("invalid kptr access, R2 type=percpu_ptr_val2_t expected=ptr_val_t")
60 int BPF_PROG(test_array_map_2)
61 {
62 	struct val2_t __percpu_kptr *p2;
63 	struct val_t __percpu_kptr *p;
64 	struct elem *e;
65 	int index = 0;
66 
67 	e = bpf_map_lookup_elem(&array, &index);
68 	if (!e)
69 		return 0;
70 
71 	p2 = bpf_percpu_obj_new(struct val2_t);
72 	if (!p2)
73 		return 0;
74 
75 	p = bpf_kptr_xchg(&e->pc, p2);
76 	if (p)
77 		bpf_percpu_obj_drop(p);
78 
79 	return 0;
80 }
81 
82 SEC("?fentry.s/bpf_fentry_test1")
83 __failure __msg("R1 type=scalar expected=percpu_ptr_, percpu_rcu_ptr_, percpu_trusted_ptr_")
84 int BPF_PROG(test_array_map_3)
85 {
86 	struct val_t __percpu_kptr *p, *p1;
87 	struct val_t *v;
88 	struct elem *e;
89 	int index = 0;
90 
91 	e = bpf_map_lookup_elem(&array, &index);
92 	if (!e)
93 		return 0;
94 
95 	p = bpf_percpu_obj_new(struct val_t);
96 	if (!p)
97 		return 0;
98 
99 	p1 = bpf_kptr_xchg(&e->pc, p);
100 	if (p1)
101 		bpf_percpu_obj_drop(p1);
102 
103 	v = bpf_this_cpu_ptr(p);
104 	ret = v->b;
105 	return 0;
106 }
107 
108 SEC("?fentry.s/bpf_fentry_test1")
109 __failure __msg("arg#0 expected for bpf_percpu_obj_drop_impl()")
110 int BPF_PROG(test_array_map_4)
111 {
112 	struct val_t __percpu_kptr *p;
113 
114 	p = bpf_percpu_obj_new(struct val_t);
115 	if (!p)
116 		return 0;
117 
118 	bpf_obj_drop(p);
119 	return 0;
120 }
121 
122 SEC("?fentry.s/bpf_fentry_test1")
123 __failure __msg("arg#0 expected for bpf_obj_drop_impl()")
124 int BPF_PROG(test_array_map_5)
125 {
126 	struct val_t *p;
127 
128 	p = bpf_obj_new(struct val_t);
129 	if (!p)
130 		return 0;
131 
132 	bpf_percpu_obj_drop(p);
133 	return 0;
134 }
135 
136 SEC("?fentry.s/bpf_fentry_test1")
137 __failure __msg("bpf_percpu_obj_new type ID argument must be of a struct of scalars")
138 int BPF_PROG(test_array_map_6)
139 {
140 	struct val_with_ptr_t __percpu_kptr *p;
141 
142 	p = bpf_percpu_obj_new(struct val_with_ptr_t);
143 	if (!p)
144 		return 0;
145 
146 	bpf_percpu_obj_drop(p);
147 	return 0;
148 }
149 
150 SEC("?fentry.s/bpf_fentry_test1")
151 __failure __msg("bpf_percpu_obj_new type ID argument must not contain special fields")
152 int BPF_PROG(test_array_map_7)
153 {
154 	struct val_with_rb_root_t __percpu_kptr *p;
155 
156 	p = bpf_percpu_obj_new(struct val_with_rb_root_t);
157 	if (!p)
158 		return 0;
159 
160 	bpf_percpu_obj_drop(p);
161 	return 0;
162 }
163 
164 char _license[] SEC("license") = "GPL";
165