Skip to content

Commit 0a0ffca

Browse files
anakryikoAlexei Starovoitov
authored andcommitted
selftests/bpf: add global subprog annotation tests
Add test cases to validate semantics of global subprog argument annotations: - non-null pointers; - context argument; - const dynptr passing; - packet pointers (data, metadata, end). Acked-by: Eduard Zingerman <[email protected]> Signed-off-by: Andrii Nakryiko <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent aae9c25 commit 0a0ffca

File tree

1 file changed

+95
-4
lines changed

1 file changed

+95
-4
lines changed

tools/testing/selftests/bpf/progs/verifier_global_subprogs.c

Lines changed: 95 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
// SPDX-License-Identifier: GPL-2.0
22
/* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */
33

4-
#include <stdbool.h>
5-
#include <errno.h>
6-
#include <string.h>
7-
#include <linux/bpf.h>
4+
#include <vmlinux.h>
85
#include <bpf/bpf_helpers.h>
96
#include "bpf_misc.h"
7+
#include "xdp_metadata.h"
8+
#include "bpf_kfuncs.h"
109

1110
int arr[1];
1211
int unkn_idx;
@@ -98,4 +97,96 @@ int unguarded_unsupp_global_called(void)
9897
return global_unsupp(&x);
9998
}
10099

100+
long stack[128];
101+
102+
__weak int subprog_nullable_ptr_bad(int *p)
103+
{
104+
return (*p) * 2; /* bad, missing null check */
105+
}
106+
107+
SEC("?raw_tp")
108+
__failure __log_level(2)
109+
__msg("invalid mem access 'mem_or_null'")
110+
int arg_tag_nullable_ptr_fail(void *ctx)
111+
{
112+
int x = 42;
113+
114+
return subprog_nullable_ptr_bad(&x);
115+
}
116+
117+
__noinline __weak int subprog_nonnull_ptr_good(int *p1 __arg_nonnull, int *p2 __arg_nonnull)
118+
{
119+
return (*p1) * (*p2); /* good, no need for NULL checks */
120+
}
121+
122+
int x = 47;
123+
124+
SEC("?raw_tp")
125+
__success __log_level(2)
126+
int arg_tag_nonnull_ptr_good(void *ctx)
127+
{
128+
int y = 74;
129+
130+
return subprog_nonnull_ptr_good(&x, &y);
131+
}
132+
133+
/* this global subprog can be now called from many types of entry progs, each
134+
* with different context type
135+
*/
136+
__weak int subprog_ctx_tag(void *ctx __arg_ctx)
137+
{
138+
return bpf_get_stack(ctx, stack, sizeof(stack), 0);
139+
}
140+
141+
SEC("?raw_tp")
142+
__success __log_level(2)
143+
int arg_tag_ctx_raw_tp(void *ctx)
144+
{
145+
return subprog_ctx_tag(ctx);
146+
}
147+
148+
SEC("?tp")
149+
__success __log_level(2)
150+
int arg_tag_ctx_tp(void *ctx)
151+
{
152+
return subprog_ctx_tag(ctx);
153+
}
154+
155+
SEC("?kprobe")
156+
__success __log_level(2)
157+
int arg_tag_ctx_kprobe(void *ctx)
158+
{
159+
return subprog_ctx_tag(ctx);
160+
}
161+
162+
__weak int subprog_dynptr(struct bpf_dynptr *dptr)
163+
{
164+
long *d, t, buf[1] = {};
165+
166+
d = bpf_dynptr_data(dptr, 0, sizeof(long));
167+
if (!d)
168+
return 0;
169+
170+
t = *d + 1;
171+
172+
d = bpf_dynptr_slice(dptr, 0, &buf, sizeof(long));
173+
if (!d)
174+
return t;
175+
176+
t = *d + 2;
177+
178+
return t;
179+
}
180+
181+
SEC("?xdp")
182+
__success __log_level(2)
183+
int arg_tag_dynptr(struct xdp_md *ctx)
184+
{
185+
struct bpf_dynptr dptr;
186+
187+
bpf_dynptr_from_xdp(ctx, 0, &dptr);
188+
189+
return subprog_dynptr(&dptr);
190+
}
191+
101192
char _license[] SEC("license") = "GPL";

0 commit comments

Comments
 (0)