Commit 0a0ffcac authored by Andrii Nakryiko's avatar Andrii Nakryiko Committed by Alexei Starovoitov

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: default avatarEduard Zingerman <eddyz87@gmail.com>
Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/r/20231215011334.2307144-10-andrii@kernel.orgSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent aae9c25d
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */
#include <stdbool.h>
#include <errno.h>
#include <string.h>
#include <linux/bpf.h>
#include <vmlinux.h>
#include <bpf/bpf_helpers.h>
#include "bpf_misc.h"
#include "xdp_metadata.h"
#include "bpf_kfuncs.h"
int arr[1];
int unkn_idx;
......@@ -98,4 +97,96 @@ int unguarded_unsupp_global_called(void)
return global_unsupp(&x);
}
long stack[128];
__weak int subprog_nullable_ptr_bad(int *p)
{
return (*p) * 2; /* bad, missing null check */
}
SEC("?raw_tp")
__failure __log_level(2)
__msg("invalid mem access 'mem_or_null'")
int arg_tag_nullable_ptr_fail(void *ctx)
{
int x = 42;
return subprog_nullable_ptr_bad(&x);
}
__noinline __weak int subprog_nonnull_ptr_good(int *p1 __arg_nonnull, int *p2 __arg_nonnull)
{
return (*p1) * (*p2); /* good, no need for NULL checks */
}
int x = 47;
SEC("?raw_tp")
__success __log_level(2)
int arg_tag_nonnull_ptr_good(void *ctx)
{
int y = 74;
return subprog_nonnull_ptr_good(&x, &y);
}
/* this global subprog can be now called from many types of entry progs, each
* with different context type
*/
__weak int subprog_ctx_tag(void *ctx __arg_ctx)
{
return bpf_get_stack(ctx, stack, sizeof(stack), 0);
}
SEC("?raw_tp")
__success __log_level(2)
int arg_tag_ctx_raw_tp(void *ctx)
{
return subprog_ctx_tag(ctx);
}
SEC("?tp")
__success __log_level(2)
int arg_tag_ctx_tp(void *ctx)
{
return subprog_ctx_tag(ctx);
}
SEC("?kprobe")
__success __log_level(2)
int arg_tag_ctx_kprobe(void *ctx)
{
return subprog_ctx_tag(ctx);
}
__weak int subprog_dynptr(struct bpf_dynptr *dptr)
{
long *d, t, buf[1] = {};
d = bpf_dynptr_data(dptr, 0, sizeof(long));
if (!d)
return 0;
t = *d + 1;
d = bpf_dynptr_slice(dptr, 0, &buf, sizeof(long));
if (!d)
return t;
t = *d + 2;
return t;
}
SEC("?xdp")
__success __log_level(2)
int arg_tag_dynptr(struct xdp_md *ctx)
{
struct bpf_dynptr dptr;
bpf_dynptr_from_xdp(ctx, 0, &dptr);
return subprog_dynptr(&dptr);
}
char _license[] SEC("license") = "GPL";
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment