All of lore.kernel.org
 help / color / mirror / Atom feed
From: Leon Hwang <leon.hwang@linux.dev>
To: bpf@vger.kernel.org
Cc: Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	John Fastabend <john.fastabend@gmail.com>,
	Andrii Nakryiko <andrii@kernel.org>,
	Martin KaFai Lau <martin.lau@linux.dev>,
	Eduard Zingerman <eddyz87@gmail.com>, Song Liu <song@kernel.org>,
	Yonghong Song <yonghong.song@linux.dev>,
	KP Singh <kpsingh@kernel.org>,
	Stanislav Fomichev <sdf@fomichev.me>, Hao Luo <haoluo@google.com>,
	Jiri Olsa <jolsa@kernel.org>, Shuah Khan <shuah@kernel.org>,
	"David S . Miller" <davem@davemloft.net>,
	Jakub Kicinski <kuba@kernel.org>,
	Jesper Dangaard Brouer <hawk@kernel.org>,
	Leon Hwang <leon.hwang@linux.dev>,
	Toke Hoiland-Jorgensen <toke@redhat.com>,
	Lorenzo Bianconi <lorenzo@kernel.org>,
	linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org,
	netdev@vger.kernel.org, kernel-patches-bot@fb.com
Subject: [PATCH bpf-next 3/3] selftests/bpf: Add tests to verify freplace compatibility
Date: Tue, 24 Mar 2026 23:04:44 +0800	[thread overview]
Message-ID: <20260324150444.68166-4-leon.hwang@linux.dev> (raw)
In-Reply-To: <20260324150444.68166-1-leon.hwang@linux.dev>

Add tests to verify the issues:

* xdp_has_frags: The backwards compatibility can be broken via freplace.
* kprobe_write_ctx: It can be abused to modify struct pt_regs of kernel
  functions via kprobe_write_ctx=true freplace progs.

Without the fixes, the issues are verified:

xdp_has_frags=true freplace prog is allowed to attach to
xdp_has_frags=false XDP prog.

kprobe_write_ctx=true freplace prog is allowed to attach to
kprobe_write_ctx=false kprobe prog. Then, the first arg of
bpf_fentry_test1 will be set as 0, and bpf_prog_test_run_opts() gets
-EFAULT instead of 0.

With the fixes, the issues are rejected by verifier:

 Extension program cannot have different xdp_has_frags value with target prog
 #134/1   freplace_compatible/xdp_has_frags:OK
 Extension program cannot have different kprobe_write_ctx value with target prog
 #134/2   freplace_compatible/kprobe_write_ctx:OK

Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
---
 .../bpf/prog_tests/freplace_compatible.c      | 124 ++++++++++++++++++
 .../selftests/bpf/progs/freplace_compatible.c |  40 ++++++
 2 files changed, 164 insertions(+)
 create mode 100644 tools/testing/selftests/bpf/prog_tests/freplace_compatible.c
 create mode 100644 tools/testing/selftests/bpf/progs/freplace_compatible.c

diff --git a/tools/testing/selftests/bpf/prog_tests/freplace_compatible.c b/tools/testing/selftests/bpf/prog_tests/freplace_compatible.c
new file mode 100644
index 000000000000..251e17ef4e52
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/freplace_compatible.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <test_progs.h>
+#include "freplace_compatible.skel.h"
+
+static void test_xdp_has_frags(void)
+{
+	struct freplace_compatible *skel_xdp, *skel_ext = NULL;
+	struct bpf_program *prog_xdp, *prog_ext;
+	struct bpf_link *link = NULL;
+	char buff[128] = {};
+	int err, prog_fd;
+	__u32 flags;
+	LIBBPF_OPTS(bpf_test_run_opts, topts,
+		.data_in = buff,
+		.data_size_in = sizeof(buff),
+		.repeat = 1,
+	);
+
+	skel_xdp = freplace_compatible__open();
+	if (!ASSERT_OK_PTR(skel_xdp, "freplace_compatible__open xdp"))
+		return;
+
+	prog_xdp = skel_xdp->progs.xdp;
+	bpf_program__set_autoload(prog_xdp, true);
+
+	err = freplace_compatible__load(skel_xdp);
+	if (!ASSERT_OK(err, "freplace_compatible__load xdp"))
+		goto out;
+
+	skel_ext = freplace_compatible__open();
+	if (!ASSERT_OK_PTR(skel_ext, "freplace_compatible__open ext"))
+		goto out;
+
+	prog_ext = skel_ext->progs.freplace_xdp;
+	bpf_program__set_autoload(prog_ext, true);
+
+	flags = bpf_program__flags(prog_ext) | BPF_F_XDP_HAS_FRAGS;
+	bpf_program__set_flags(prog_ext, flags);
+
+	prog_fd = bpf_program__fd(prog_xdp);
+	bpf_program__set_attach_target(prog_ext, prog_fd, "xdp");
+
+	err = freplace_compatible__load(skel_ext);
+	ASSERT_ERR(err, "freplace_compatible__load ext");
+
+	link = bpf_program__attach_freplace(prog_ext, prog_fd, "xdp");
+	ASSERT_ERR_PTR(link, "bpf_program__attach_freplace");
+
+	err = bpf_prog_test_run_opts(prog_fd, &topts);
+	if (!ASSERT_OK(err, "bpf_prog_test_run_opts"))
+		goto out;
+
+	ASSERT_EQ(topts.retval, XDP_PASS, "xdp retval");
+
+out:
+	bpf_link__destroy(link);
+	freplace_compatible__destroy(skel_ext);
+	freplace_compatible__destroy(skel_xdp);
+}
+
+#ifdef __x86_64__
+static void test_kprobe_write_ctx(void)
+{
+	struct freplace_compatible *skel_kprobe, *skel_ext = NULL;
+	struct bpf_program *prog_kprobe, *prog_ext, *prog_fentry;
+	struct bpf_link *link_kprobe = NULL, *link_ext = NULL;
+	int err;
+	LIBBPF_OPTS(bpf_kprobe_opts, kprobe_opts);
+	LIBBPF_OPTS(bpf_test_run_opts, topts);
+
+	skel_kprobe = freplace_compatible__open();
+	if (!ASSERT_OK_PTR(skel_kprobe, "freplace_compatible__open kprobe"))
+		return;
+
+	prog_kprobe = skel_kprobe->progs.kprobe;
+	bpf_program__set_autoload(prog_kprobe, true);
+
+	prog_fentry = skel_kprobe->progs.fentry;
+	bpf_program__set_autoload(prog_fentry, true);
+
+	err = freplace_compatible__load(skel_kprobe);
+	if (!ASSERT_OK(err, "freplace_compatible__load kprobe"))
+		goto out;
+
+	skel_ext = freplace_compatible__open();
+	if (!ASSERT_OK_PTR(skel_ext, "freplace_compatible__open ext"))
+		goto out;
+
+	prog_ext = skel_ext->progs.freplace_kprobe;
+	bpf_program__set_autoload(prog_ext, true);
+
+	bpf_program__set_attach_target(prog_ext, bpf_program__fd(prog_kprobe), "kprobe");
+
+	err = freplace_compatible__load(skel_ext);
+	ASSERT_ERR(err, "freplace_compatible__load ext");
+
+	link_ext = bpf_program__attach_freplace(prog_ext, 0, NULL);
+	ASSERT_ERR_PTR(link_ext, "bpf_program__attach_freplace");
+
+	link_kprobe = bpf_program__attach_kprobe_opts(prog_kprobe, "bpf_fentry_test1",
+						      &kprobe_opts);
+	if (!ASSERT_OK_PTR(link_kprobe, "bpf_program__attach_kprobe_opts"))
+		goto out;
+
+	err = bpf_prog_test_run_opts(bpf_program__fd(prog_fentry), &topts);
+	ASSERT_OK(err, "bpf_prog_test_run_opts");
+
+out:
+	bpf_link__destroy(link_ext);
+	bpf_link__destroy(link_kprobe);
+	freplace_compatible__destroy(skel_ext);
+	freplace_compatible__destroy(skel_kprobe);
+}
+#endif
+
+void test_freplace_compatible(void)
+{
+	if (test__start_subtest("xdp_has_frags"))
+		test_xdp_has_frags();
+#ifdef __x86_64__
+	if (test__start_subtest("kprobe_write_ctx"))
+		test_kprobe_write_ctx();
+#endif
+}
diff --git a/tools/testing/selftests/bpf/progs/freplace_compatible.c b/tools/testing/selftests/bpf/progs/freplace_compatible.c
new file mode 100644
index 000000000000..f13b4878268b
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/freplace_compatible.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <vmlinux.h>
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_tracing.h>
+
+SEC("?xdp")
+int xdp(struct xdp_md *ctx)
+{
+	return XDP_PASS;
+}
+
+SEC("?freplace")
+int freplace_xdp(struct xdp_md *ctx)
+{
+	return 0xFF;
+}
+
+#if defined(__TARGET_ARCH_x86)
+SEC("?kprobe")
+int kprobe(struct pt_regs *regs)
+{
+	return 0;
+}
+
+SEC("?freplace")
+int freplace_kprobe(struct pt_regs *regs)
+{
+	regs->di = 0;
+	return 0;
+}
+
+SEC("?fentry/bpf_fentry_test1")
+int BPF_PROG(fentry)
+{
+	return 0;
+}
+#endif
+
+char _license[] SEC("license") = "GPL";
+
-- 
2.53.0


      parent reply	other threads:[~2026-03-24 15:05 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-24 15:04 [PATCH bpf-next 0/3] bpf: Enhance freplace compatibility Leon Hwang
2026-03-24 15:04 ` [PATCH bpf-next 1/3] bpf: Disallow freplace on XDP with mismatched xdp_has_frags values Leon Hwang
2026-03-24 16:18   ` Toke Høiland-Jørgensen
2026-03-25  1:42     ` Leon Hwang
2026-03-25 10:38       ` Toke Høiland-Jørgensen
2026-03-26 19:42   ` Jakub Kicinski
2026-03-27  6:42     ` Leon Hwang
2026-03-28  0:12       ` Jakub Kicinski
2026-03-30  5:20         ` Leon Hwang
2026-03-24 15:04 ` [PATCH bpf-next 2/3] bpf: Disallow freplace on kprobe with mismatched kprobe_write_ctx values Leon Hwang
2026-03-25 12:51   ` Jiri Olsa
2026-03-25 13:54     ` Leon Hwang
2026-03-27 20:41   ` Jiri Olsa
2026-03-30  5:51     ` Leon Hwang
2026-03-24 15:04 ` Leon Hwang [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260324150444.68166-4-leon.hwang@linux.dev \
    --to=leon.hwang@linux.dev \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=eddyz87@gmail.com \
    --cc=haoluo@google.com \
    --cc=hawk@kernel.org \
    --cc=john.fastabend@gmail.com \
    --cc=jolsa@kernel.org \
    --cc=kernel-patches-bot@fb.com \
    --cc=kpsingh@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=lorenzo@kernel.org \
    --cc=martin.lau@linux.dev \
    --cc=netdev@vger.kernel.org \
    --cc=sdf@fomichev.me \
    --cc=shuah@kernel.org \
    --cc=song@kernel.org \
    --cc=toke@redhat.com \
    --cc=yonghong.song@linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.