]> Git Repo - linux.git/blob - tools/testing/selftests/bpf/progs/verifier_bits_iter.c
Linux 6.14-rc3
[linux.git] / tools / testing / selftests / bpf / progs / verifier_bits_iter.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (c) 2024 Yafang Shao <[email protected]> */
3
4 #include "vmlinux.h"
5 #include <bpf/bpf_helpers.h>
6 #include <bpf/bpf_tracing.h>
7
8 #include "bpf_misc.h"
9 #include "task_kfunc_common.h"
10
11 char _license[] SEC("license") = "GPL";
12
13 int bpf_iter_bits_new(struct bpf_iter_bits *it, const u64 *unsafe_ptr__ign,
14                       u32 nr_bits) __ksym __weak;
15 int *bpf_iter_bits_next(struct bpf_iter_bits *it) __ksym __weak;
16 void bpf_iter_bits_destroy(struct bpf_iter_bits *it) __ksym __weak;
17
18 u64 bits_array[511] = {};
19
20 SEC("iter.s/cgroup")
21 __description("bits iter without destroy")
22 __failure __msg("Unreleased reference")
23 int BPF_PROG(no_destroy, struct bpf_iter_meta *meta, struct cgroup *cgrp)
24 {
25         struct bpf_iter_bits it;
26         u64 data = 1;
27
28         bpf_iter_bits_new(&it, &data, 1);
29         bpf_iter_bits_next(&it);
30         return 0;
31 }
32
33 SEC("iter/cgroup")
34 __description("uninitialized iter in ->next()")
35 __failure __msg("expected an initialized iter_bits as arg #0")
36 int BPF_PROG(next_uninit, struct bpf_iter_meta *meta, struct cgroup *cgrp)
37 {
38         struct bpf_iter_bits it = {};
39
40         bpf_iter_bits_next(&it);
41         return 0;
42 }
43
44 SEC("iter/cgroup")
45 __description("uninitialized iter in ->destroy()")
46 __failure __msg("expected an initialized iter_bits as arg #0")
47 int BPF_PROG(destroy_uninit, struct bpf_iter_meta *meta, struct cgroup *cgrp)
48 {
49         struct bpf_iter_bits it = {};
50
51         bpf_iter_bits_destroy(&it);
52         return 0;
53 }
54
55 SEC("syscall")
56 __description("null pointer")
57 __success __retval(0)
58 int null_pointer(void)
59 {
60         struct bpf_iter_bits iter;
61         int err, nr = 0;
62         int *bit;
63
64         err = bpf_iter_bits_new(&iter, NULL, 1);
65         bpf_iter_bits_destroy(&iter);
66         if (err != -EINVAL)
67                 return 1;
68
69         bpf_for_each(bits, bit, NULL, 1)
70                 nr++;
71         return nr;
72 }
73
74 SEC("syscall")
75 __description("bits copy")
76 __success __retval(10)
77 int bits_copy(void)
78 {
79         u64 data = 0xf7310UL; /* 4 + 3 + 2 + 1 + 0*/
80         int nr = 0;
81         int *bit;
82
83         bpf_for_each(bits, bit, &data, 1)
84                 nr++;
85         return nr;
86 }
87
88 SEC("syscall")
89 __description("bits memalloc")
90 __success __retval(64)
91 int bits_memalloc(void)
92 {
93         u64 data[2];
94         int nr = 0;
95         int *bit;
96
97         __builtin_memset(&data, 0xf0, sizeof(data)); /* 4 * 16 */
98         bpf_for_each(bits, bit, &data[0], ARRAY_SIZE(data))
99                 nr++;
100         return nr;
101 }
102
103 SEC("syscall")
104 __description("bit index")
105 __success __retval(8)
106 int bit_index(void)
107 {
108         u64 data = 0x100;
109         int bit_idx = 0;
110         int *bit;
111
112         bpf_for_each(bits, bit, &data, 1) {
113                 if (*bit == 0)
114                         continue;
115                 bit_idx = *bit;
116         }
117         return bit_idx;
118 }
119
120 SEC("syscall")
121 __description("bits too big")
122 __success __retval(0)
123 int bits_too_big(void)
124 {
125         u64 data[4];
126         int nr = 0;
127         int *bit;
128
129         __builtin_memset(&data, 0xff, sizeof(data));
130         bpf_for_each(bits, bit, &data[0], 512) /* Be greater than 511 */
131                 nr++;
132         return nr;
133 }
134
135 SEC("syscall")
136 __description("fewer words")
137 __success __retval(1)
138 int fewer_words(void)
139 {
140         u64 data[2] = {0x1, 0xff};
141         int nr = 0;
142         int *bit;
143
144         bpf_for_each(bits, bit, &data[0], 1)
145                 nr++;
146         return nr;
147 }
148
149 SEC("syscall")
150 __description("zero words")
151 __success __retval(0)
152 int zero_words(void)
153 {
154         u64 data[2] = {0x1, 0xff};
155         int nr = 0;
156         int *bit;
157
158         bpf_for_each(bits, bit, &data[0], 0)
159                 nr++;
160         return nr;
161 }
162
163 SEC("syscall")
164 __description("huge words")
165 __success __retval(0)
166 int huge_words(void)
167 {
168         u64 data[8] = {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1};
169         int nr = 0;
170         int *bit;
171
172         bpf_for_each(bits, bit, &data[0], 67108865)
173                 nr++;
174         return nr;
175 }
176
177 SEC("syscall")
178 __description("max words")
179 __success __retval(4)
180 int max_words(void)
181 {
182         volatile int nr = 0;
183         int *bit;
184
185         bits_array[0] = (1ULL << 63) | 1U;
186         bits_array[510] = (1ULL << 33) | (1ULL << 32);
187
188         bpf_for_each(bits, bit, bits_array, 511) {
189                 if (nr == 0 && *bit != 0)
190                         break;
191                 if (nr == 2 && *bit != 32672)
192                         break;
193                 nr++;
194         }
195         return nr;
196 }
197
198 SEC("syscall")
199 __description("bad words")
200 __success __retval(0)
201 int bad_words(void)
202 {
203         void *bad_addr = (void *)-4095;
204         struct bpf_iter_bits iter;
205         volatile int nr;
206         int *bit;
207         int err;
208
209         err = bpf_iter_bits_new(&iter, bad_addr, 1);
210         bpf_iter_bits_destroy(&iter);
211         if (err != -EFAULT)
212                 return 1;
213
214         nr = 0;
215         bpf_for_each(bits, bit, bad_addr, 1)
216                 nr++;
217         if (nr != 0)
218                 return 2;
219
220         err = bpf_iter_bits_new(&iter, bad_addr, 4);
221         bpf_iter_bits_destroy(&iter);
222         if (err != -EFAULT)
223                 return 3;
224
225         nr = 0;
226         bpf_for_each(bits, bit, bad_addr, 4)
227                 nr++;
228         if (nr != 0)
229                 return 4;
230
231         return 0;
232 }
This page took 0.035887 seconds and 4 git commands to generate.