From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
To: bpf@vger.kernel.org
Cc: Andrii Nakryiko <andrii@kernel.org>,
Alexei Starovoitov <ast@kernel.org>,
Eduard Zingerman <eddyz87@gmail.com>,
Daniel Borkmann <daniel@iogearbox.net>,
Emil Tsalapatis <emil@etsalapatis.com>,
Nicholas Carlini <npc@anthropic.com>,
kkd@meta.com, kernel-team@meta.com
Subject: [PATCH bpf v6 04/10] bpf: Apply CO-RE relocations before subprogram validation
Date: Thu, 17 Sep 2026 13:11:16 +0200 [thread overview]
Message-ID: <20260917111127.3780880-5-memxor@gmail.com> (raw)
In-Reply-To: <20260917111127.3780880-1-memxor@gmail.com>
check_subprogs() verifies that each subprogram ends in an exit or an
unconditional jump before in-kernel CO-RE relocations are applied. An
unresolved relocation can then replace that terminal instruction with an
invalid helper call. The resulting fall-through into another subprogram
breaks the CFG invariant used by postorder and stack liveness analysis,
which can write past their per-subprogram arrays.
Apply CO-RE relocations immediately after preparing the program BTF, before
subprogram discovery and validation. Keep func_info and line_info validation
after subprogram discovery because those records depend on the complete
subprogram layout.
Reject an ldimm64 first slot at the end of the instruction stream before
CO-RE can inspect its missing second slot. The regular instruction validation
already rejects this form, but now runs after relocation processing.
Include core_relo_cnt when deciding whether to prepare program BTF. A load
that supplied only CO-RE relocation metadata previously skipped both BTF
setup and relocation processing.
Fixes: fbd94c7afcf9 ("bpf: Pass a set of bpf_core_relo-s to prog_load command.")
Suggested-by: Andrii Nakryiko <andrii@kernel.org>
Suggested-by: Alexei Starovoitov <ast@kernel.org>
Suggested-by: Eduard Zingerman <eddyz87@gmail.com>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
---
include/linux/bpf_verifier.h | 2 ++
kernel/bpf/check_btf.c | 12 ++++--------
kernel/bpf/verifier.c | 12 +++++++++++-
3 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index 36b65797877d..bba5a727c651 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -1197,6 +1197,8 @@ static inline void bpf_trampoline_unpack_key(u64 key, u32 *obj_id, u32 *btf_id)
int bpf_prepare_btf_info(struct bpf_verifier_env *env,
const union bpf_attr *attr, bpfptr_t uattr);
+int bpf_check_core_relo(struct bpf_verifier_env *env,
+ const union bpf_attr *attr, bpfptr_t uattr);
int bpf_check_btf_info(struct bpf_verifier_env *env,
const union bpf_attr *attr, bpfptr_t uattr);
diff --git a/kernel/bpf/check_btf.c b/kernel/bpf/check_btf.c
index 0e8b3ccc7a5b..4c1ed842f661 100644
--- a/kernel/bpf/check_btf.c
+++ b/kernel/bpf/check_btf.c
@@ -338,9 +338,9 @@ static int check_btf_line(struct bpf_verifier_env *env,
#define MIN_CORE_RELO_SIZE sizeof(struct bpf_core_relo)
#define MAX_CORE_RELO_SIZE MAX_FUNCINFO_REC_SIZE
-static int check_core_relo(struct bpf_verifier_env *env,
- const union bpf_attr *attr,
- bpfptr_t uattr)
+int bpf_check_core_relo(struct bpf_verifier_env *env,
+ const union bpf_attr *attr,
+ bpfptr_t uattr)
{
u32 i, nr_core_relo, ncopy, expected_size, rec_size;
struct bpf_core_relo core_relo = {};
@@ -414,7 +414,7 @@ int bpf_prepare_btf_info(struct bpf_verifier_env *env,
struct btf *btf;
int err;
- if (!attr->func_info_cnt && !attr->line_info_cnt) {
+ if (!attr->func_info_cnt && !attr->line_info_cnt && !attr->core_relo_cnt) {
if (check_abnormal_return(env))
return -EINVAL;
return 0;
@@ -455,9 +455,5 @@ int bpf_check_btf_info(struct bpf_verifier_env *env,
if (err)
return err;
- err = check_core_relo(env, attr, uattr);
- if (err)
- return err;
-
return 0;
}
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 5d7080c260d8..33161dc64568 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -21199,6 +21199,11 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr,
ret = bpf_diag_init(env);
if (ret)
goto err_prep;
+ if (env->prog->insnsi[env->prog->len - 1].code == (BPF_LD | BPF_IMM | BPF_DW)) {
+ verbose(env, "invalid bpf_ld_imm64 insn\n");
+ ret = -EINVAL;
+ goto err_prep;
+ }
if (env->signature) {
ret = bpf_prog_calc_tag(env->prog);
if (ret < 0)
@@ -21274,6 +21279,11 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr,
if (ret < 0)
goto skip_full_check;
+ /* Apply CO-RE before validating the program's instruction layout. */
+ ret = bpf_check_core_relo(env, attr, uattr);
+ if (ret < 0)
+ goto skip_full_check;
+
/* Discover all subprograms before validating their layout and BTF. */
ret = add_subprogs(env);
if (ret < 0)
@@ -21283,7 +21293,7 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr,
if (ret < 0)
goto skip_full_check;
- /* Validate BTF against the complete subprogram layout and apply CO-RE. */
+ /* Validate BTF against the complete subprogram layout. */
ret = bpf_check_btf_info(env, attr, uattr);
if (ret < 0)
goto skip_full_check;
--
2.53.0
next prev parent reply other threads:[~2026-09-17 11:11 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-17 11:11 [PATCH bpf v6 00/10] Misc bug fixes - part 5 Kumar Kartikeya Dwivedi
2026-09-17 11:11 ` [PATCH bpf v6 01/10] bpf: Make post-verification instruction rewrites killable Kumar Kartikeya Dwivedi
2026-09-17 11:11 ` [PATCH bpf v6 02/10] bpf: Preserve packet pointer class displacement in regsafe() Kumar Kartikeya Dwivedi
2026-09-17 11:11 ` [PATCH bpf v6 03/10] selftests/bpf: Test packet pointer class displacement pruning Kumar Kartikeya Dwivedi
2026-09-17 11:11 ` Kumar Kartikeya Dwivedi [this message]
2026-09-17 12:29 ` [PATCH bpf v6 04/10] bpf: Apply CO-RE relocations before subprogram validation bot+bpf-ci
2026-09-17 11:11 ` [PATCH bpf v6 05/10] selftests/bpf: Test early in-kernel CO-RE relocation Kumar Kartikeya Dwivedi
2026-09-17 12:29 ` bot+bpf-ci
2026-09-17 11:11 ` [PATCH bpf v6 06/10] bpf: Restrict CO-RE poisoning to relocatable instructions Kumar Kartikeya Dwivedi
2026-09-17 12:29 ` bot+bpf-ci
2026-09-17 11:11 ` [PATCH bpf v6 07/10] selftests/bpf: Test CO-RE instruction poisoning restrictions Kumar Kartikeya Dwivedi
2026-09-17 11:11 ` [PATCH bpf v6 08/10] bpf: Assign lock identity to callback map values Kumar Kartikeya Dwivedi
2026-09-17 12:29 ` bot+bpf-ci
2026-09-17 11:11 ` [PATCH bpf v6 09/10] selftests/bpf: Check callback map value lock identity Kumar Kartikeya Dwivedi
2026-09-17 11:11 ` [PATCH bpf v6 10/10] libbpf: Reject truncated ldimm64 CO-RE relocations Kumar Kartikeya Dwivedi
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=20260917111127.3780880-5-memxor@gmail.com \
--to=memxor@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=emil@etsalapatis.com \
--cc=kernel-team@meta.com \
--cc=kkd@meta.com \
--cc=npc@anthropic.com \
/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