mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-27 04:47:05 +00:00
selftests/bpf: add freplace of BTF-unreliable main prog test
Add a test validating that freplace'ing another main (entry) BPF program fails if the target BPF program doesn't have valid/expected func proto BTF. We extend fexit_bpf2bpf test to allow to specify expected log message for negative test cases (where freplace program is expected to fail to load). Acked-by: Eduard Zingerman <eddyz87@gmail.com> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/r/20231215011334.2307144-11-andrii@kernel.org Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
0a0ffcac92
commit
f0a5056222
4 changed files with 69 additions and 3 deletions
|
@ -348,7 +348,8 @@ static void test_func_sockmap_update(void)
|
|||
}
|
||||
|
||||
static void test_obj_load_failure_common(const char *obj_file,
|
||||
const char *target_obj_file)
|
||||
const char *target_obj_file,
|
||||
const char *exp_msg)
|
||||
{
|
||||
/*
|
||||
* standalone test that asserts failure to load freplace prog
|
||||
|
@ -356,6 +357,7 @@ static void test_obj_load_failure_common(const char *obj_file,
|
|||
*/
|
||||
struct bpf_object *obj = NULL, *pkt_obj;
|
||||
struct bpf_program *prog;
|
||||
char log_buf[64 * 1024];
|
||||
int err, pkt_fd;
|
||||
__u32 duration = 0;
|
||||
|
||||
|
@ -374,11 +376,21 @@ static void test_obj_load_failure_common(const char *obj_file,
|
|||
err = bpf_program__set_attach_target(prog, pkt_fd, NULL);
|
||||
ASSERT_OK(err, "set_attach_target");
|
||||
|
||||
log_buf[0] = '\0';
|
||||
if (exp_msg)
|
||||
bpf_program__set_log_buf(prog, log_buf, sizeof(log_buf));
|
||||
if (env.verbosity > VERBOSE_NONE)
|
||||
bpf_program__set_log_level(prog, 2);
|
||||
|
||||
/* It should fail to load the program */
|
||||
err = bpf_object__load(obj);
|
||||
if (env.verbosity > VERBOSE_NONE && exp_msg) /* we overtook log */
|
||||
printf("VERIFIER LOG:\n================\n%s\n================\n", log_buf);
|
||||
if (CHECK(!err, "bpf_obj_load should fail", "err %d\n", err))
|
||||
goto close_prog;
|
||||
|
||||
if (exp_msg)
|
||||
ASSERT_HAS_SUBSTR(log_buf, exp_msg, "fail_msg");
|
||||
close_prog:
|
||||
bpf_object__close(obj);
|
||||
bpf_object__close(pkt_obj);
|
||||
|
@ -388,14 +400,24 @@ static void test_func_replace_return_code(void)
|
|||
{
|
||||
/* test invalid return code in the replaced program */
|
||||
test_obj_load_failure_common("./freplace_connect_v4_prog.bpf.o",
|
||||
"./connect4_prog.bpf.o");
|
||||
"./connect4_prog.bpf.o", NULL);
|
||||
}
|
||||
|
||||
static void test_func_map_prog_compatibility(void)
|
||||
{
|
||||
/* test with spin lock map value in the replaced program */
|
||||
test_obj_load_failure_common("./freplace_attach_probe.bpf.o",
|
||||
"./test_attach_probe.bpf.o");
|
||||
"./test_attach_probe.bpf.o", NULL);
|
||||
}
|
||||
|
||||
static void test_func_replace_unreliable(void)
|
||||
{
|
||||
/* freplace'ing unreliable main prog should fail with error
|
||||
* "Cannot replace static functions"
|
||||
*/
|
||||
test_obj_load_failure_common("freplace_unreliable_prog.bpf.o",
|
||||
"./verifier_btf_unreliable_prog.bpf.o",
|
||||
"Cannot replace static functions");
|
||||
}
|
||||
|
||||
static void test_func_replace_global_func(void)
|
||||
|
@ -563,6 +585,8 @@ void serial_test_fexit_bpf2bpf(void)
|
|||
test_func_replace_return_code();
|
||||
if (test__start_subtest("func_map_prog_compatibility"))
|
||||
test_func_map_prog_compatibility();
|
||||
if (test__start_subtest("func_replace_unreliable"))
|
||||
test_func_replace_unreliable();
|
||||
if (test__start_subtest("func_replace_multi"))
|
||||
test_func_replace_multi();
|
||||
if (test__start_subtest("fmod_ret_freplace"))
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "verifier_bpf_get_stack.skel.h"
|
||||
#include "verifier_bswap.skel.h"
|
||||
#include "verifier_btf_ctx_access.skel.h"
|
||||
#include "verifier_btf_unreliable_prog.skel.h"
|
||||
#include "verifier_cfg.skel.h"
|
||||
#include "verifier_cgroup_inv_retcode.skel.h"
|
||||
#include "verifier_cgroup_skb.skel.h"
|
||||
|
@ -125,6 +126,7 @@ void test_verifier_bounds_mix_sign_unsign(void) { RUN(verifier_bounds_mix_sign_u
|
|||
void test_verifier_bpf_get_stack(void) { RUN(verifier_bpf_get_stack); }
|
||||
void test_verifier_bswap(void) { RUN(verifier_bswap); }
|
||||
void test_verifier_btf_ctx_access(void) { RUN(verifier_btf_ctx_access); }
|
||||
void test_verifier_btf_unreliable_prog(void) { RUN(verifier_btf_unreliable_prog); }
|
||||
void test_verifier_cfg(void) { RUN(verifier_cfg); }
|
||||
void test_verifier_cgroup_inv_retcode(void) { RUN(verifier_cgroup_inv_retcode); }
|
||||
void test_verifier_cgroup_skb(void) { RUN(verifier_cgroup_skb); }
|
||||
|
|
20
tools/testing/selftests/bpf/progs/freplace_unreliable_prog.c
Normal file
20
tools/testing/selftests/bpf/progs/freplace_unreliable_prog.c
Normal file
|
@ -0,0 +1,20 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (c) 2020 Facebook
|
||||
|
||||
#include "vmlinux.h"
|
||||
#include <bpf/bpf_helpers.h>
|
||||
#include <bpf/bpf_tracing.h>
|
||||
|
||||
SEC("freplace/btf_unreliable_kprobe")
|
||||
/* context type is what BPF verifier expects for kprobe context, but target
|
||||
* program has `stuct whatever *ctx` argument, so freplace operation will be
|
||||
* rejected with the following message:
|
||||
*
|
||||
* arg0 replace_btf_unreliable_kprobe(struct pt_regs *) doesn't match btf_unreliable_kprobe(struct whatever *)
|
||||
*/
|
||||
int replace_btf_unreliable_kprobe(bpf_user_pt_regs_t *ctx)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
char _license[] SEC("license") = "GPL";
|
|
@ -0,0 +1,20 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (c) 2017 Facebook
|
||||
|
||||
#include "vmlinux.h"
|
||||
#include <bpf/bpf_helpers.h>
|
||||
#include <bpf/bpf_tracing.h>
|
||||
#include <bpf/bpf_core_read.h>
|
||||
#include "bpf_misc.h"
|
||||
|
||||
struct whatever {};
|
||||
|
||||
SEC("kprobe")
|
||||
__success __log_level(2)
|
||||
/* context type is wrong, making it impossible to freplace this program */
|
||||
int btf_unreliable_kprobe(struct whatever *ctx)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
char _license[] SEC("license") = "GPL";
|
Loading…
Reference in a new issue