mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-19 04:14:49 +08:00
selftests/bpf: Bad_struct_ops test
When loading struct_ops programs kernel requires BTF id of the struct_ops type and member index for attachment point inside that type. This makes impossible to use same BPF program in several struct_ops maps that have different struct_ops type. Check if libbpf rejects such BPF objects files. Signed-off-by: Eduard Zingerman <eddyz87@gmail.com> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Acked-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/bpf/20240306104529.6453-7-eddyz87@gmail.com
This commit is contained in:
parent
c8617e8bcf
commit
c1b93c07b3
@ -611,6 +611,29 @@ struct bpf_struct_ops bpf_bpf_testmod_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int bpf_dummy_reg2(void *kdata)
|
||||
{
|
||||
struct bpf_testmod_ops2 *ops = kdata;
|
||||
|
||||
ops->test_1();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct bpf_testmod_ops2 __bpf_testmod_ops2 = {
|
||||
.test_1 = bpf_testmod_test_1,
|
||||
};
|
||||
|
||||
struct bpf_struct_ops bpf_testmod_ops2 = {
|
||||
.verifier_ops = &bpf_testmod_verifier_ops,
|
||||
.init = bpf_testmod_ops_init,
|
||||
.init_member = bpf_testmod_ops_init_member,
|
||||
.reg = bpf_dummy_reg2,
|
||||
.unreg = bpf_dummy_unreg,
|
||||
.cfi_stubs = &__bpf_testmod_ops2,
|
||||
.name = "bpf_testmod_ops2",
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
extern int bpf_fentry_test1(int a);
|
||||
|
||||
static int bpf_testmod_init(void)
|
||||
@ -622,6 +645,7 @@ static int bpf_testmod_init(void)
|
||||
ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &bpf_testmod_kfunc_set);
|
||||
ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL, &bpf_testmod_kfunc_set);
|
||||
ret = ret ?: register_bpf_struct_ops(&bpf_bpf_testmod_ops, bpf_testmod_ops);
|
||||
ret = ret ?: register_bpf_struct_ops(&bpf_testmod_ops2, bpf_testmod_ops2);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (bpf_fentry_test1(0) < 0)
|
||||
|
@ -89,4 +89,8 @@ struct bpf_testmod_ops {
|
||||
int (*tramp_40)(int value);
|
||||
};
|
||||
|
||||
struct bpf_testmod_ops2 {
|
||||
int (*test_1)(void);
|
||||
};
|
||||
|
||||
#endif /* _BPF_TESTMOD_H */
|
||||
|
35
tools/testing/selftests/bpf/prog_tests/bad_struct_ops.c
Normal file
35
tools/testing/selftests/bpf/prog_tests/bad_struct_ops.c
Normal file
@ -0,0 +1,35 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <test_progs.h>
|
||||
#include "bad_struct_ops.skel.h"
|
||||
|
||||
static void invalid_prog_reuse(void)
|
||||
{
|
||||
struct bad_struct_ops *skel;
|
||||
char *log = NULL;
|
||||
int err;
|
||||
|
||||
skel = bad_struct_ops__open();
|
||||
if (!ASSERT_OK_PTR(skel, "bad_struct_ops__open"))
|
||||
return;
|
||||
|
||||
if (start_libbpf_log_capture())
|
||||
goto cleanup;
|
||||
|
||||
err = bad_struct_ops__load(skel);
|
||||
log = stop_libbpf_log_capture();
|
||||
ASSERT_ERR(err, "bad_struct_ops__load should fail");
|
||||
ASSERT_HAS_SUBSTR(log,
|
||||
"struct_ops init_kern testmod_2 func ptr test_1: invalid reuse of prog test_1",
|
||||
"expected init_kern message");
|
||||
|
||||
cleanup:
|
||||
free(log);
|
||||
bad_struct_ops__destroy(skel);
|
||||
}
|
||||
|
||||
void test_bad_struct_ops(void)
|
||||
{
|
||||
if (test__start_subtest("invalid_prog_reuse"))
|
||||
invalid_prog_reuse();
|
||||
}
|
25
tools/testing/selftests/bpf/progs/bad_struct_ops.c
Normal file
25
tools/testing/selftests/bpf/progs/bad_struct_ops.c
Normal file
@ -0,0 +1,25 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <vmlinux.h>
|
||||
#include <bpf/bpf_helpers.h>
|
||||
#include <bpf/bpf_tracing.h>
|
||||
#include "../bpf_testmod/bpf_testmod.h"
|
||||
|
||||
char _license[] SEC("license") = "GPL";
|
||||
|
||||
SEC("struct_ops/test_1")
|
||||
int BPF_PROG(test_1) { return 0; }
|
||||
|
||||
SEC("struct_ops/test_2")
|
||||
int BPF_PROG(test_2) { return 0; }
|
||||
|
||||
SEC(".struct_ops.link")
|
||||
struct bpf_testmod_ops testmod_1 = {
|
||||
.test_1 = (void *)test_1,
|
||||
.test_2 = (void *)test_2
|
||||
};
|
||||
|
||||
SEC(".struct_ops.link")
|
||||
struct bpf_testmod_ops2 testmod_2 = {
|
||||
.test_1 = (void *)test_1
|
||||
};
|
Loading…
Reference in New Issue
Block a user