[PATCH bpf-next 2/2] selftests/bpf: Verify calling core kfuncs from BPF_PROG_TYPE_SYCALL

From: David Vernet
Date: Wed Apr 03 2024 - 21:03:53 EST


Now that we can call some kfuncs from BPF_PROG_TYPE_SYSCALL progs, let's
add some selftests that verify as much. As a bonus, let's also verify
that we can't call the progs from raw tracepoints.

Signed-off-by: David Vernet <void@xxxxxxxxxxxxx>
---
.../selftests/bpf/prog_tests/cgrp_kfunc.c | 1 +
.../selftests/bpf/prog_tests/task_kfunc.c | 1 +
.../selftests/bpf/progs/cgrp_kfunc_common.h | 21 +++++++++++++++++++
.../selftests/bpf/progs/cgrp_kfunc_failure.c | 4 ++++
.../selftests/bpf/progs/cgrp_kfunc_success.c | 4 ++++
.../selftests/bpf/progs/cpumask_common.h | 19 +++++++++++++++++
.../selftests/bpf/progs/cpumask_failure.c | 4 ++++
.../selftests/bpf/progs/cpumask_success.c | 3 +++
.../selftests/bpf/progs/task_kfunc_common.h | 18 ++++++++++++++++
.../selftests/bpf/progs/task_kfunc_failure.c | 4 ++++
.../selftests/bpf/progs/task_kfunc_success.c | 4 ++++
11 files changed, 83 insertions(+)

diff --git a/tools/testing/selftests/bpf/prog_tests/cgrp_kfunc.c b/tools/testing/selftests/bpf/prog_tests/cgrp_kfunc.c
index adda85f97058..73f0ec4f4eb7 100644
--- a/tools/testing/selftests/bpf/prog_tests/cgrp_kfunc.c
+++ b/tools/testing/selftests/bpf/prog_tests/cgrp_kfunc.c
@@ -102,6 +102,7 @@ void test_cgrp_kfunc(void)
run_success_test(success_tests[i]);
}

+ RUN_TESTS(cgrp_kfunc_success);
RUN_TESTS(cgrp_kfunc_failure);

cleanup:
diff --git a/tools/testing/selftests/bpf/prog_tests/task_kfunc.c b/tools/testing/selftests/bpf/prog_tests/task_kfunc.c
index d4579f735398..3db4c8601b70 100644
--- a/tools/testing/selftests/bpf/prog_tests/task_kfunc.c
+++ b/tools/testing/selftests/bpf/prog_tests/task_kfunc.c
@@ -94,5 +94,6 @@ void test_task_kfunc(void)
run_success_test(success_tests[i]);
}

+ RUN_TESTS(task_kfunc_success);
RUN_TESTS(task_kfunc_failure);
}
diff --git a/tools/testing/selftests/bpf/progs/cgrp_kfunc_common.h b/tools/testing/selftests/bpf/progs/cgrp_kfunc_common.h
index 22914a70db54..b9972ce4e4dc 100644
--- a/tools/testing/selftests/bpf/progs/cgrp_kfunc_common.h
+++ b/tools/testing/selftests/bpf/progs/cgrp_kfunc_common.h
@@ -27,6 +27,27 @@ struct cgroup *bpf_cgroup_from_id(u64 cgid) __ksym;
void bpf_rcu_read_lock(void) __ksym;
void bpf_rcu_read_unlock(void) __ksym;

+#define CGRP_KFUNC_LOAD_TEST(__name) \
+int BPF_PROG(cgroup_kfunc_load_test_##__name) \
+{ \
+ struct cgroup *cgrp, *ref; \
+ \
+ cgrp = bpf_cgroup_from_id(0); \
+ if (!cgrp) \
+ return 0; \
+ ref = bpf_cgroup_acquire(cgrp); \
+ if (!ref) { \
+ bpf_cgroup_release(cgrp); \
+ return 0; \
+ } \
+ \
+ bpf_cgroup_release(ref); \
+ bpf_cgroup_release(cgrp); \
+ \
+ return 0; \
+}
+
+
static inline struct __cgrps_kfunc_map_value *cgrps_kfunc_map_value_lookup(struct cgroup *cgrp)
{
s32 id;
diff --git a/tools/testing/selftests/bpf/progs/cgrp_kfunc_failure.c b/tools/testing/selftests/bpf/progs/cgrp_kfunc_failure.c
index 9fe9c4a4e8f6..ff67d4632dfa 100644
--- a/tools/testing/selftests/bpf/progs/cgrp_kfunc_failure.c
+++ b/tools/testing/selftests/bpf/progs/cgrp_kfunc_failure.c
@@ -245,3 +245,7 @@ int BPF_PROG(cgrp_kfunc_release_unacquired, struct cgroup *cgrp, const char *pat

return 0;
}
+
+SEC("raw_tp")
+__failure __msg("calling kernel function")
+CGRP_KFUNC_LOAD_TEST(raw_tp)
diff --git a/tools/testing/selftests/bpf/progs/cgrp_kfunc_success.c b/tools/testing/selftests/bpf/progs/cgrp_kfunc_success.c
index 5354455a01be..ff1beb29f3f5 100644
--- a/tools/testing/selftests/bpf/progs/cgrp_kfunc_success.c
+++ b/tools/testing/selftests/bpf/progs/cgrp_kfunc_success.c
@@ -5,6 +5,7 @@
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_helpers.h>

+#include "bpf_misc.h"
#include "cgrp_kfunc_common.h"

char _license[] SEC("license") = "GPL";
@@ -221,3 +222,6 @@ int BPF_PROG(test_cgrp_from_id, struct cgroup *cgrp, const char *path)

return 0;
}
+
+SEC("syscall") __success
+CGRP_KFUNC_LOAD_TEST(syscall)
diff --git a/tools/testing/selftests/bpf/progs/cpumask_common.h b/tools/testing/selftests/bpf/progs/cpumask_common.h
index c705d8112a35..5178d62c5c9f 100644
--- a/tools/testing/selftests/bpf/progs/cpumask_common.h
+++ b/tools/testing/selftests/bpf/progs/cpumask_common.h
@@ -60,6 +60,25 @@ u32 bpf_cpumask_weight(const struct cpumask *cpumask) __ksym __weak;
void bpf_rcu_read_lock(void) __ksym __weak;
void bpf_rcu_read_unlock(void) __ksym __weak;

+#define CPUMASK_KFUNC_LOAD_TEST(__name) \
+int BPF_PROG(cpumask_kfunc_load_test_##__name) \
+{ \
+ struct bpf_cpumask *alloc, *ref; \
+ \
+ alloc = bpf_cpumask_create(); \
+ if (!alloc) \
+ return 0; \
+ \
+ ref = bpf_cpumask_acquire(alloc); \
+ if (ref) \
+ bpf_cpumask_release(ref); \
+ bpf_cpumask_set_cpu(0, alloc); \
+ bpf_cpumask_test_cpu(0, (const struct cpumask *)alloc); \
+ bpf_cpumask_release(alloc); \
+ \
+ return 0; \
+}
+
static inline const struct cpumask *cast(struct bpf_cpumask *cpumask)
{
return (const struct cpumask *)cpumask;
diff --git a/tools/testing/selftests/bpf/progs/cpumask_failure.c b/tools/testing/selftests/bpf/progs/cpumask_failure.c
index a9bf6ea336cf..55815df8000f 100644
--- a/tools/testing/selftests/bpf/progs/cpumask_failure.c
+++ b/tools/testing/selftests/bpf/progs/cpumask_failure.c
@@ -190,3 +190,7 @@ int BPF_PROG(test_global_mask_rcu_no_null_check, struct task_struct *task, u64 c

return 0;
}
+
+SEC("raw_tp")
+__failure __msg("calling kernel function")
+CPUMASK_KFUNC_LOAD_TEST(raw_tp)
diff --git a/tools/testing/selftests/bpf/progs/cpumask_success.c b/tools/testing/selftests/bpf/progs/cpumask_success.c
index 7a1e64c6c065..a4f32a5a26d1 100644
--- a/tools/testing/selftests/bpf/progs/cpumask_success.c
+++ b/tools/testing/selftests/bpf/progs/cpumask_success.c
@@ -525,3 +525,6 @@ int BPF_PROG(test_refcount_null_tracking, struct task_struct *task, u64 clone_fl
bpf_cpumask_release(mask2);
return 0;
}
+
+SEC("syscall") __success
+CPUMASK_KFUNC_LOAD_TEST(syscall)
diff --git a/tools/testing/selftests/bpf/progs/task_kfunc_common.h b/tools/testing/selftests/bpf/progs/task_kfunc_common.h
index 41f2d44f49cb..2278325ca902 100644
--- a/tools/testing/selftests/bpf/progs/task_kfunc_common.h
+++ b/tools/testing/selftests/bpf/progs/task_kfunc_common.h
@@ -26,6 +26,24 @@ struct task_struct *bpf_task_from_pid(s32 pid) __ksym;
void bpf_rcu_read_lock(void) __ksym;
void bpf_rcu_read_unlock(void) __ksym;

+#define TASK_KFUNC_LOAD_TEST(__name) \
+int BPF_PROG(task_kfunc_load_test_##__name) \
+{ \
+ struct task_struct *current, *ref_1, *ref_2; \
+ \
+ current = bpf_get_current_task_btf(); \
+ ref_1 = bpf_task_from_pid(current->pid); \
+ if (!ref_1) \
+ return 0; \
+ \
+ ref_2 = bpf_task_acquire(ref_1); \
+ if (ref_2) \
+ bpf_task_release(ref_2); \
+ bpf_task_release(ref_1); \
+ \
+ return 0; \
+}
+
static inline struct __tasks_kfunc_map_value *tasks_kfunc_map_value_lookup(struct task_struct *p)
{
s32 pid;
diff --git a/tools/testing/selftests/bpf/progs/task_kfunc_failure.c b/tools/testing/selftests/bpf/progs/task_kfunc_failure.c
index ad88a3796ddf..57ec25463d80 100644
--- a/tools/testing/selftests/bpf/progs/task_kfunc_failure.c
+++ b/tools/testing/selftests/bpf/progs/task_kfunc_failure.c
@@ -324,3 +324,7 @@ int BPF_PROG(task_kfunc_release_in_map, struct task_struct *task, u64 clone_flag

return 0;
}
+
+SEC("raw_tp")
+__failure __msg("calling kernel function")
+TASK_KFUNC_LOAD_TEST(raw_tp)
diff --git a/tools/testing/selftests/bpf/progs/task_kfunc_success.c b/tools/testing/selftests/bpf/progs/task_kfunc_success.c
index 70df695312dc..203ff461a92c 100644
--- a/tools/testing/selftests/bpf/progs/task_kfunc_success.c
+++ b/tools/testing/selftests/bpf/progs/task_kfunc_success.c
@@ -5,6 +5,7 @@
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_helpers.h>

+#include "bpf_misc.h"
#include "task_kfunc_common.h"

char _license[] SEC("license") = "GPL";
@@ -314,3 +315,6 @@ int BPF_PROG(task_kfunc_acquire_trusted_walked, struct task_struct *task, u64 cl

return 0;
}
+
+SEC("syscall") __success
+TASK_KFUNC_LOAD_TEST(syscall)
--
2.44.0