]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
selftests/sched_ext: Add non_scx_kfunc_deny test
authorCheng-Yang Chou <yphbchou0911@gmail.com>
Mon, 20 Apr 2026 09:28:48 +0000 (17:28 +0800)
committerTejun Heo <tj@kernel.org>
Mon, 20 Apr 2026 17:57:29 +0000 (07:57 -1000)
Verify that the BPF verifier rejects a non-SCX struct_ops program
(tcp_congestion_ops) that attempts to call an SCX kfunc (scx_bpf_kick_cpu).
The test expects the load to fail with -EACCES from scx_kfunc_context_filter.

Signed-off-by: Cheng-Yang Chou <yphbchou0911@gmail.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
tools/testing/selftests/sched_ext/Makefile
tools/testing/selftests/sched_ext/non_scx_kfunc_deny.bpf.c [new file with mode: 0644]
tools/testing/selftests/sched_ext/non_scx_kfunc_deny.c [new file with mode: 0644]

index 789037be44c7f3576d361d9dd0280a0c0d334680..5d2dffca0e918ef2199ed9dc15440743f71a9aad 100644 (file)
@@ -175,6 +175,7 @@ auto-test-targets :=                        \
        maximal                         \
        maybe_null                      \
        minimal                         \
+       non_scx_kfunc_deny              \
        numa                            \
        allowed_cpus                    \
        peek_dsq                        \
diff --git a/tools/testing/selftests/sched_ext/non_scx_kfunc_deny.bpf.c b/tools/testing/selftests/sched_ext/non_scx_kfunc_deny.bpf.c
new file mode 100644 (file)
index 0000000..9f16d39
--- /dev/null
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Verify that context-sensitive SCX kfuncs (even "unlocked" ones) are
+ * restricted to only SCX struct_ops programs. Non-SCX struct_ops programs,
+ * such as TCP congestion control programs, should be rejected by the BPF
+ * verifier when attempting to call these kfuncs.
+ *
+ * Copyright (C) 2026 Ching-Chun (Jim) Huang <jserv@ccns.ncku.edu.tw>
+ * Copyright (C) 2026 Cheng-Yang Chou <yphbchou0911@gmail.com>
+ */
+
+#include <vmlinux.h>
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_tracing.h>
+
+/* SCX kfunc from scx_kfunc_ids_any set */
+void scx_bpf_kick_cpu(s32 cpu, u64 flags) __ksym;
+
+SEC("struct_ops/ssthresh")
+__u32 BPF_PROG(tcp_ca_ssthresh, struct sock *sk)
+{
+       /*
+        * This call should be rejected by the verifier because this is a
+        * TCP congestion control program (non-SCX struct_ops).
+        */
+       scx_bpf_kick_cpu(0, 0);
+       return 2;
+}
+
+SEC("struct_ops/cong_avoid")
+void BPF_PROG(tcp_ca_cong_avoid, struct sock *sk, __u32 ack, __u32 acked) {}
+
+SEC("struct_ops/undo_cwnd")
+__u32 BPF_PROG(tcp_ca_undo_cwnd, struct sock *sk) { return 2; }
+
+SEC(".struct_ops")
+struct tcp_congestion_ops tcp_non_scx_ca = {
+       .ssthresh   = (void *)tcp_ca_ssthresh,
+       .cong_avoid = (void *)tcp_ca_cong_avoid,
+       .undo_cwnd  = (void *)tcp_ca_undo_cwnd,
+       .name       = "tcp_kfunc_deny",
+};
+
+char _license[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/sched_ext/non_scx_kfunc_deny.c b/tools/testing/selftests/sched_ext/non_scx_kfunc_deny.c
new file mode 100644 (file)
index 0000000..1c03157
--- /dev/null
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Verify that context-sensitive SCX kfuncs (even "unlocked" ones) are
+ * restricted to only SCX struct_ops programs. Non-SCX struct_ops programs,
+ * such as TCP congestion control programs, should be rejected by the BPF
+ * verifier when attempting to call these kfuncs.
+ *
+ * Copyright (C) 2026 Ching-Chun (Jim) Huang <jserv@ccns.ncku.edu.tw>
+ * Copyright (C) 2026 Cheng-Yang Chou <yphbchou0911@gmail.com>
+ */
+
+#include <bpf/bpf.h>
+#include <scx/common.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include "non_scx_kfunc_deny.bpf.skel.h"
+#include "scx_test.h"
+
+static enum scx_test_status run(void *ctx)
+{
+       struct non_scx_kfunc_deny *skel;
+       int err;
+
+       skel = non_scx_kfunc_deny__open();
+       if (!skel) {
+               SCX_ERR("Failed to open skel");
+               return SCX_TEST_FAIL;
+       }
+
+       err = non_scx_kfunc_deny__load(skel);
+       non_scx_kfunc_deny__destroy(skel);
+
+       if (err == 0) {
+               SCX_ERR("non-SCX BPF program loaded when it should have been rejected");
+               return SCX_TEST_FAIL;
+       }
+
+       return SCX_TEST_PASS;
+}
+
+struct scx_test non_scx_kfunc_deny = {
+       .name = "non_scx_kfunc_deny",
+       .description = "Verify that non-SCX struct_ops programs cannot call SCX kfuncs",
+       .run = run,
+};
+REGISTER_SCX_TEST(&non_scx_kfunc_deny)