From: Weiming Shi <bestswngs@gmail.com>
To: Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Andrii Nakryiko <andrii@kernel.org>,
Eduard Zingerman <eddyz87@gmail.com>,
Kumar Kartikeya Dwivedi <memxor@gmail.com>
Cc: Martin KaFai Lau <martin.lau@linux.dev>,
Song Liu <song@kernel.org>,
Yonghong Song <yonghong.song@linux.dev>,
Jiri Olsa <jolsa@kernel.org>,
bpf@vger.kernel.org, Xiang Mei <xmei5@asu.edu>,
Weiming Shi <bestswngs@gmail.com>
Subject: [PATCH bpf v3 2/2] selftests/bpf: add test for negative CO-RE accessor index rejection
Date: Sun, 5 Apr 2026 00:12:21 +0800 [thread overview]
Message-ID: <20260404161221.961828-3-bestswngs@gmail.com> (raw)
In-Reply-To: <20260404161221.961828-1-bestswngs@gmail.com>
Add a selftest to verify that the kernel rejects BPF programs containing
CO-RE relocations with negative accessor indices. The test constructs a
minimal BTF blob with a struct type and a CO-RE relocation whose access
string is "0:-1". Without the fix in the previous patch, this triggers
an out-of-bounds read in bpf_core_parse_spec(); with the fix, the
program load fails cleanly with -EINVAL.
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
---
.../selftests/bpf/prog_tests/core_reloc_raw.c | 94 +++++++++++++++++++
1 file changed, 94 insertions(+)
diff --git a/tools/testing/selftests/bpf/prog_tests/core_reloc_raw.c b/tools/testing/selftests/bpf/prog_tests/core_reloc_raw.c
index a18d3680fb16..f7bf6c237d59 100644
--- a/tools/testing/selftests/bpf/prog_tests/core_reloc_raw.c
+++ b/tools/testing/selftests/bpf/prog_tests/core_reloc_raw.c
@@ -118,8 +118,102 @@ static void test_bad_local_id(void)
close(btf_fd);
}
+/* Check that verifier rejects BPF program containing CO-RE relocation
+ * with a negative accessor index (e.g. "0:-1").
+ */
+static void test_negative_accessor(void)
+{
+ struct test_btf {
+ struct btf_header hdr;
+ __u32 types[18];
+ char strings[20];
+ } raw_btf = {
+ .hdr = {
+ .magic = BTF_MAGIC,
+ .version = BTF_VERSION,
+ .hdr_len = sizeof(struct btf_header),
+ .type_off = 0,
+ .type_len = sizeof(raw_btf.types),
+ .str_off = offsetof(struct test_btf, strings) -
+ offsetof(struct test_btf, types),
+ .str_len = sizeof(raw_btf.strings),
+ },
+ .types = {
+ /* [1] int */
+ BTF_TYPE_INT_ENC(1, BTF_INT_SIGNED, 0, 32, 4),
+ /* [2] struct s { int x; } */
+ BTF_STRUCT_ENC(5, 1, 4),
+ BTF_MEMBER_ENC(7, 1, 0),
+ /* [3] int (*)(int a) */
+ BTF_FUNC_PROTO_ENC(1, 1),
+ BTF_FUNC_PROTO_ARG_ENC(13, 1),
+ /* [4] FUNC 'foo' */
+ BTF_FUNC_ENC(9, 3),
+ },
+ /* offsets: 0:NUL 1:"int" 5:"s" 7:"x" 9:"foo" 13:"a" 15:"0:-1" */
+ .strings = "\0int\0s\0x\0foo\0a\0" "0:-1",
+ };
+ __u32 log_level = 1 | 2 | 4;
+ LIBBPF_OPTS(bpf_btf_load_opts, opts,
+ .log_buf = log,
+ .log_size = sizeof(log),
+ .log_level = log_level,
+ );
+ struct bpf_insn insns[] = {
+ BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ };
+ struct bpf_func_info funcs[] = {
+ { .insn_off = 0, .type_id = 4 }
+ };
+ struct bpf_core_relo relos[] = {
+ {
+ .insn_off = 0,
+ .type_id = 2, /* struct s */
+ .access_str_off = 15, /* "0:-1" */
+ .kind = BPF_CORE_FIELD_BYTE_OFFSET,
+ }
+ };
+ union bpf_attr attr;
+ int prog_fd = -1;
+ int btf_fd = -1;
+
+ btf_fd = bpf_btf_load(&raw_btf, sizeof(raw_btf), &opts);
+ if (!ASSERT_GE(btf_fd, 0, "btf_load"))
+ return;
+
+ log[0] = 0;
+ memset(&attr, 0, sizeof(attr));
+ attr.prog_btf_fd = btf_fd;
+ attr.prog_type = BPF_TRACE_RAW_TP;
+ attr.license = (__u64)"GPL";
+ attr.insns = (__u64)&insns;
+ attr.insn_cnt = sizeof(insns) / sizeof(*insns);
+ attr.log_buf = (__u64)log;
+ attr.log_size = sizeof(log);
+ attr.log_level = log_level;
+ attr.func_info = (__u64)funcs;
+ attr.func_info_cnt = sizeof(funcs) / sizeof(*funcs);
+ attr.func_info_rec_size = sizeof(*funcs);
+ attr.core_relos = (__u64)relos;
+ attr.core_relo_cnt = sizeof(relos) / sizeof(*relos);
+ attr.core_relo_rec_size = sizeof(*relos);
+ prog_fd = sys_bpf_prog_load(&attr, sizeof(attr), 1);
+ if (prog_fd >= 0) {
+ PRINT_FAIL("sys_bpf_prog_load() expected to fail\n");
+ goto out;
+ }
+ ASSERT_HAS_SUBSTR(log, "failed: -22", "prog_load_log");
+
+out:
+ close(prog_fd);
+ close(btf_fd);
+}
+
void test_core_reloc_raw(void)
{
if (test__start_subtest("bad_local_id"))
test_bad_local_id();
+ if (test__start_subtest("negative_accessor"))
+ test_negative_accessor();
}
--
2.43.0
next prev parent reply other threads:[~2026-04-04 16:12 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-04 16:12 [PATCH bpf v3 0/2] bpf: reject negative CO-RE accessor indices Weiming Shi
2026-04-04 16:12 ` [PATCH bpf v3 1/2] bpf: reject negative CO-RE accessor indices in bpf_core_parse_spec() Weiming Shi
2026-04-04 18:07 ` Emil Tsalapatis
2026-04-06 15:01 ` Paul Chaignon
2026-04-04 16:12 ` Weiming Shi [this message]
2026-04-04 18:12 ` [PATCH bpf v3 2/2] selftests/bpf: add test for negative CO-RE accessor index rejection Emil Tsalapatis
2026-04-06 15:03 ` Paul Chaignon
2026-04-04 18:06 ` [PATCH bpf v3 0/2] bpf: reject negative CO-RE accessor indices Emil Tsalapatis
2026-04-07 15:30 ` patchwork-bot+netdevbpf
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=20260404161221.961828-3-bestswngs@gmail.com \
--to=bestswngs@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=jolsa@kernel.org \
--cc=martin.lau@linux.dev \
--cc=memxor@gmail.com \
--cc=song@kernel.org \
--cc=xmei5@asu.edu \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox