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 val_600b_t { |
21 | char b[600]; |
22 | }; |
23 | |
24 | struct elem { |
25 | long sum; |
26 | struct val_t __percpu_kptr *pc; |
27 | }; |
28 | |
29 | struct { |
30 | __uint(type, BPF_MAP_TYPE_ARRAY); |
31 | __uint(max_entries, 1); |
32 | __type(key, int); |
33 | __type(value, struct elem); |
34 | } array SEC(".maps" ); |
35 | |
36 | long ret; |
37 | |
38 | SEC("?fentry/bpf_fentry_test1" ) |
39 | __failure __msg("store to referenced kptr disallowed" ) |
40 | int BPF_PROG(test_array_map_1) |
41 | { |
42 | struct val_t __percpu_kptr *p; |
43 | struct elem *e; |
44 | int index = 0; |
45 | |
46 | e = bpf_map_lookup_elem(&array, &index); |
47 | if (!e) |
48 | return 0; |
49 | |
50 | p = bpf_percpu_obj_new(struct val_t); |
51 | if (!p) |
52 | return 0; |
53 | |
54 | p = bpf_kptr_xchg(&e->pc, p); |
55 | if (p) |
56 | bpf_percpu_obj_drop(p); |
57 | |
58 | e->pc = (struct val_t __percpu_kptr *)ret; |
59 | return 0; |
60 | } |
61 | |
62 | SEC("?fentry/bpf_fentry_test1" ) |
63 | __failure __msg("invalid kptr access, R2 type=percpu_ptr_val2_t expected=ptr_val_t" ) |
64 | int BPF_PROG(test_array_map_2) |
65 | { |
66 | struct val2_t __percpu_kptr *p2; |
67 | struct val_t __percpu_kptr *p; |
68 | struct elem *e; |
69 | int index = 0; |
70 | |
71 | e = bpf_map_lookup_elem(&array, &index); |
72 | if (!e) |
73 | return 0; |
74 | |
75 | p2 = bpf_percpu_obj_new(struct val2_t); |
76 | if (!p2) |
77 | return 0; |
78 | |
79 | p = bpf_kptr_xchg(&e->pc, p2); |
80 | if (p) |
81 | bpf_percpu_obj_drop(p); |
82 | |
83 | return 0; |
84 | } |
85 | |
86 | SEC("?fentry.s/bpf_fentry_test1" ) |
87 | __failure __msg("R1 type=scalar expected=percpu_ptr_, percpu_rcu_ptr_, percpu_trusted_ptr_" ) |
88 | int BPF_PROG(test_array_map_3) |
89 | { |
90 | struct val_t __percpu_kptr *p, *p1; |
91 | struct val_t *v; |
92 | struct elem *e; |
93 | int index = 0; |
94 | |
95 | e = bpf_map_lookup_elem(&array, &index); |
96 | if (!e) |
97 | return 0; |
98 | |
99 | p = bpf_percpu_obj_new(struct val_t); |
100 | if (!p) |
101 | return 0; |
102 | |
103 | p1 = bpf_kptr_xchg(&e->pc, p); |
104 | if (p1) |
105 | bpf_percpu_obj_drop(p1); |
106 | |
107 | v = bpf_this_cpu_ptr(p); |
108 | ret = v->b; |
109 | return 0; |
110 | } |
111 | |
112 | SEC("?fentry.s/bpf_fentry_test1" ) |
113 | __failure __msg("arg#0 expected for bpf_percpu_obj_drop_impl()" ) |
114 | int BPF_PROG(test_array_map_4) |
115 | { |
116 | struct val_t __percpu_kptr *p; |
117 | |
118 | p = bpf_percpu_obj_new(struct val_t); |
119 | if (!p) |
120 | return 0; |
121 | |
122 | bpf_obj_drop(p); |
123 | return 0; |
124 | } |
125 | |
126 | SEC("?fentry.s/bpf_fentry_test1" ) |
127 | __failure __msg("arg#0 expected for bpf_obj_drop_impl()" ) |
128 | int BPF_PROG(test_array_map_5) |
129 | { |
130 | struct val_t *p; |
131 | |
132 | p = bpf_obj_new(struct val_t); |
133 | if (!p) |
134 | return 0; |
135 | |
136 | bpf_percpu_obj_drop(p); |
137 | return 0; |
138 | } |
139 | |
140 | SEC("?fentry.s/bpf_fentry_test1" ) |
141 | __failure __msg("bpf_percpu_obj_new type ID argument must be of a struct of scalars" ) |
142 | int BPF_PROG(test_array_map_6) |
143 | { |
144 | struct val_with_ptr_t __percpu_kptr *p; |
145 | |
146 | p = bpf_percpu_obj_new(struct val_with_ptr_t); |
147 | if (!p) |
148 | return 0; |
149 | |
150 | bpf_percpu_obj_drop(p); |
151 | return 0; |
152 | } |
153 | |
154 | SEC("?fentry.s/bpf_fentry_test1" ) |
155 | __failure __msg("bpf_percpu_obj_new type ID argument must not contain special fields" ) |
156 | int BPF_PROG(test_array_map_7) |
157 | { |
158 | struct val_with_rb_root_t __percpu_kptr *p; |
159 | |
160 | p = bpf_percpu_obj_new(struct val_with_rb_root_t); |
161 | if (!p) |
162 | return 0; |
163 | |
164 | bpf_percpu_obj_drop(p); |
165 | return 0; |
166 | } |
167 | |
168 | SEC("?fentry.s/bpf_fentry_test1" ) |
169 | __failure __msg("bpf_percpu_obj_new type size (600) is greater than 512" ) |
170 | int BPF_PROG(test_array_map_8) |
171 | { |
172 | struct val_600b_t __percpu_kptr *p; |
173 | |
174 | p = bpf_percpu_obj_new(struct val_600b_t); |
175 | if (!p) |
176 | return 0; |
177 | |
178 | bpf_percpu_obj_drop(p); |
179 | return 0; |
180 | } |
181 | |
182 | char _license[] SEC("license" ) = "GPL" ; |
183 | |