Skip to content

Commit 11f7b3e

Browse files
committed
selftests/bpf: Add tests for raw_tp null handling
JIRA: https://issues.redhat.com/browse/RHEL-85485 Conflicts: use `syscall(SYS_gettid)` instead of `sys_gettid()` due to missing upstream commit 0e2fb01 ("selftests/bpf: Clean up open-coded gettid syscall invocations"). commit d798ce3 Author: Kumar Kartikeya Dwivedi <memxor@gmail.com> Date: Mon Nov 4 09:19:59 2024 -0800 selftests/bpf: Add tests for raw_tp null handling Ensure that trusted PTR_TO_BTF_ID accesses perform PROBE_MEM handling in raw_tp program. Without the previous fix, this selftest crashes the kernel due to a NULL-pointer dereference. Also ensure that dead code elimination does not kick in for checks on the pointer. Reviewed-by: Jiri Olsa <jolsa@kernel.org> Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Link: https://lore.kernel.org/r/20241104171959.2938862-4-memxor@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Viktor Malik <vmalik@redhat.com>
1 parent 75d5b07 commit 11f7b3e

File tree

4 files changed

+68
-0
lines changed

4 files changed

+68
-0
lines changed

tools/testing/selftests/bpf/bpf_testmod/bpf_testmod-events.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@ DECLARE_TRACE(bpf_testmod_test_nullable_bare,
4040
TP_ARGS(ctx__nullable)
4141
);
4242

43+
struct sk_buff;
44+
45+
DECLARE_TRACE(bpf_testmod_test_raw_tp_null,
46+
TP_PROTO(struct sk_buff *skb),
47+
TP_ARGS(skb)
48+
);
49+
50+
4351
#undef BPF_TESTMOD_DECLARE_TRACE
4452
#ifdef DECLARE_TRACE_WRITABLE
4553
#define BPF_TESTMOD_DECLARE_TRACE(call, proto, args, size) \

tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,8 @@ bpf_testmod_test_read(struct file *file, struct kobject *kobj,
368368

369369
(void)bpf_testmod_test_arg_ptr_to_struct(&struct_arg1_2);
370370

371+
(void)trace_bpf_testmod_test_raw_tp_null(NULL);
372+
371373
struct_arg3 = kmalloc((sizeof(struct bpf_testmod_struct_arg_3) +
372374
sizeof(int)), GFP_KERNEL);
373375
if (struct_arg3 != NULL) {
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */
3+
4+
#include <test_progs.h>
5+
#include "raw_tp_null.skel.h"
6+
#include <sys/syscall.h>
7+
8+
void test_raw_tp_null(void)
9+
{
10+
struct raw_tp_null *skel;
11+
12+
skel = raw_tp_null__open_and_load();
13+
if (!ASSERT_OK_PTR(skel, "raw_tp_null__open_and_load"))
14+
return;
15+
16+
skel->bss->tid = syscall(SYS_gettid);
17+
18+
if (!ASSERT_OK(raw_tp_null__attach(skel), "raw_tp_null__attach"))
19+
goto end;
20+
21+
ASSERT_OK(trigger_module_test_read(2), "trigger testmod read");
22+
ASSERT_EQ(skel->bss->i, 3, "invocations");
23+
24+
end:
25+
raw_tp_null__destroy(skel);
26+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */
3+
4+
#include <vmlinux.h>
5+
#include <bpf/bpf_tracing.h>
6+
7+
char _license[] SEC("license") = "GPL";
8+
9+
int tid;
10+
int i;
11+
12+
SEC("tp_btf/bpf_testmod_test_raw_tp_null")
13+
int BPF_PROG(test_raw_tp_null, struct sk_buff *skb)
14+
{
15+
struct task_struct *task = bpf_get_current_task_btf();
16+
17+
if (task->pid != tid)
18+
return 0;
19+
20+
i = i + skb->mark + 1;
21+
/* The compiler may move the NULL check before this deref, which causes
22+
* the load to fail as deref of scalar. Prevent that by using a barrier.
23+
*/
24+
barrier();
25+
/* If dead code elimination kicks in, the increment below will
26+
* be removed. For raw_tp programs, we mark input arguments as
27+
* PTR_MAYBE_NULL, so branch prediction should never kick in.
28+
*/
29+
if (!skb)
30+
i += 2;
31+
return 0;
32+
}

0 commit comments

Comments
 (0)