linux/tools/testing/selftests/bpf/progs/kfunc_call_fail.c
Toke Høiland-Jørgensen d6212d82bf selftests/bpf: Consolidate kernel modules into common directory
The selftests build four kernel modules which use copy-pasted Makefile
targets. This is a bit messy, and doesn't scale so well when we add more
modules, so let's consolidate these rules into a single rule generated
for each module name, and move the module sources into a single
directory.

To avoid parallel builds of the different modules stepping on each
other's toes during the 'modpost' phase of the Kbuild 'make modules',
the module files should really be a grouped target. However, make only
added explicit support for grouped targets in version 4.3, which is
newer than the minimum version supported by the kernel. However, make
implicitly treats pattern matching rules with multiple targets as a
grouped target, so we can work around this by turning the rule into a
pattern matching target. We do this by replacing '.ko' with '%ko' in the
targets with subst().

Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Viktor Malik <vmalik@redhat.com>
Link: https://lore.kernel.org/bpf/20241204-bpf-selftests-mod-compile-v5-1-b96231134a49@redhat.com
2024-12-06 10:44:10 -08:00

160 lines
3.1 KiB
C

// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2021 Facebook */
#include <vmlinux.h>
#include <bpf/bpf_helpers.h>
#include "../test_kmods/bpf_testmod_kfunc.h"
struct syscall_test_args {
__u8 data[16];
size_t size;
};
SEC("?syscall")
int kfunc_syscall_test_fail(struct syscall_test_args *args)
{
bpf_kfunc_call_test_mem_len_pass1(&args->data, sizeof(*args) + 1);
return 0;
}
SEC("?syscall")
int kfunc_syscall_test_null_fail(struct syscall_test_args *args)
{
/* Must be called with args as a NULL pointer
* we do not check for it to have the verifier consider that
* the pointer might not be null, and so we can load it.
*
* So the following can not be added:
*
* if (args)
* return -22;
*/
bpf_kfunc_call_test_mem_len_pass1(args, sizeof(*args));
return 0;
}
SEC("?tc")
int kfunc_call_test_get_mem_fail_rdonly(struct __sk_buff *skb)
{
struct prog_test_ref_kfunc *pt;
unsigned long s = 0;
int *p = NULL;
int ret = 0;
pt = bpf_kfunc_call_test_acquire(&s);
if (pt) {
p = bpf_kfunc_call_test_get_rdonly_mem(pt, 2 * sizeof(int));
if (p)
p[0] = 42; /* this is a read-only buffer, so -EACCES */
else
ret = -1;
bpf_kfunc_call_test_release(pt);
}
return ret;
}
SEC("?tc")
int kfunc_call_test_get_mem_fail_use_after_free(struct __sk_buff *skb)
{
struct prog_test_ref_kfunc *pt;
unsigned long s = 0;
int *p = NULL;
int ret = 0;
pt = bpf_kfunc_call_test_acquire(&s);
if (pt) {
p = bpf_kfunc_call_test_get_rdwr_mem(pt, 2 * sizeof(int));
if (p) {
p[0] = 42;
ret = p[1]; /* 108 */
} else {
ret = -1;
}
bpf_kfunc_call_test_release(pt);
}
if (p)
ret = p[0]; /* p is not valid anymore */
return ret;
}
SEC("?tc")
int kfunc_call_test_get_mem_fail_oob(struct __sk_buff *skb)
{
struct prog_test_ref_kfunc *pt;
unsigned long s = 0;
int *p = NULL;
int ret = 0;
pt = bpf_kfunc_call_test_acquire(&s);
if (pt) {
p = bpf_kfunc_call_test_get_rdonly_mem(pt, 2 * sizeof(int));
if (p)
ret = p[2 * sizeof(int)]; /* oob access, so -EACCES */
else
ret = -1;
bpf_kfunc_call_test_release(pt);
}
return ret;
}
int not_const_size = 2 * sizeof(int);
SEC("?tc")
int kfunc_call_test_get_mem_fail_not_const(struct __sk_buff *skb)
{
struct prog_test_ref_kfunc *pt;
unsigned long s = 0;
int *p = NULL;
int ret = 0;
pt = bpf_kfunc_call_test_acquire(&s);
if (pt) {
p = bpf_kfunc_call_test_get_rdonly_mem(pt, not_const_size); /* non const size, -EINVAL */
if (p)
ret = p[0];
else
ret = -1;
bpf_kfunc_call_test_release(pt);
}
return ret;
}
SEC("?tc")
int kfunc_call_test_mem_acquire_fail(struct __sk_buff *skb)
{
struct prog_test_ref_kfunc *pt;
unsigned long s = 0;
int *p = NULL;
int ret = 0;
pt = bpf_kfunc_call_test_acquire(&s);
if (pt) {
/* we are failing on this one, because we are not acquiring a PTR_TO_BTF_ID (a struct ptr) */
p = bpf_kfunc_call_test_acq_rdonly_mem(pt, 2 * sizeof(int));
if (p)
ret = p[0];
else
ret = -1;
bpf_kfunc_call_int_mem_release(p);
bpf_kfunc_call_test_release(pt);
}
return ret;
}
SEC("?tc")
int kfunc_call_test_pointer_arg_type_mismatch(struct __sk_buff *skb)
{
bpf_kfunc_call_test_pass_ctx((void *)10);
return 0;
}
char _license[] SEC("license") = "GPL";