All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
To: bpf@vger.kernel.org
Cc: Nicholas Carlini <npc@anthropic.com>,
	Alexei Starovoitov <ast@kernel.org>,
	Andrii Nakryiko <andrii@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Eduard Zingerman <eddyz87@gmail.com>,
	Emil Tsalapatis <emil@etsalapatis.com>,
	kkd@meta.com, kernel-team@meta.com
Subject: [PATCH bpf v1 03/10] bpf: Reject tail calls directly from callback frames
Date: Thu,  3 Sep 2026 16:44:21 +0200	[thread overview]
Message-ID: <20260903144433.1716731-4-memxor@gmail.com> (raw)
In-Reply-To: <20260903144433.1716731-1-memxor@gmail.com>

A tail call from a non-zero frame is modeled as a return from that frame.
The verifier makes R0 unknown and calls prepare_func_exit() for the taken
branch.

When the current frame is a synchronous callback, prepare_func_exit()
enforces the callback return-value contract and marks R0 precise. Since the
tail-call path synthesized R0 rather than deriving it from an instruction,
precision backtracking reaches the callback-calling instruction with R0
still requested and triggers the "callback unexpected regs" verifier bug.
A CAP_BPF task can therefore cause a WARN and an -EFAULT BPF_PROG_LOAD.

Tail calls reachable from callbacks are already rejected later by
check_max_stack_depth(). Reject a tail call made directly by a callback
before constructing the inconsistent return state, using the existing
diagnostic. Tail calls from ordinary subprograms keep their current
behavior.

Fixes: e3245f899043 ("bpf: properly verify tail call behavior")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
---
 kernel/bpf/verifier.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 7d8ddb1bee00..f540279ff4ab 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -11228,6 +11228,17 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn
 		if (env->cur_state->curframe) {
 			struct bpf_verifier_state *branch;
 
+			/*
+			 * A taken tail call is modeled as a return from the current
+			 * frame. A callback frame cannot be left that way because
+			 * prepare_func_exit() would apply its return contract to the
+			 * unknown R0 synthesized below. Stack-depth validation rejects
+			 * this construct anyway.
+			 */
+			if (cur_func(env)->in_callback_fn) {
+				verbose(env, "cannot tail call within callback\n");
+				return -EINVAL;
+			}
 			mark_reg_scratched(env, BPF_REG_0);
 			branch = push_stack(env, env->insn_idx + 1, env->insn_idx, false);
 			if (IS_ERR(branch))
-- 
2.53.0


  parent reply	other threads:[~2026-09-03 14:44 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-03 14:44 [PATCH bpf v1 00/10] Misc bug fixes - part 1 Kumar Kartikeya Dwivedi
2026-09-03 14:44 ` [PATCH bpf v1 01/10] bpf: Mark signal tracepoint siginfo arguments as scalar Kumar Kartikeya Dwivedi
2026-09-03 15:52   ` bot+bpf-ci
2026-09-03 16:47     ` Alexei Starovoitov
2026-09-03 14:44 ` [PATCH bpf v1 02/10] selftests/bpf: Cover signal tracepoint siginfo sentinels Kumar Kartikeya Dwivedi
2026-09-03 15:52   ` bot+bpf-ci
2026-09-03 14:44 ` Kumar Kartikeya Dwivedi [this message]
2026-09-03 15:21   ` [PATCH bpf v1 03/10] bpf: Reject tail calls directly from callback frames sashiko-bot
2026-09-03 15:36     ` Kumar Kartikeya Dwivedi
2026-09-03 14:44 ` [PATCH bpf v1 04/10] selftests/bpf: Test direct tail calls from callbacks Kumar Kartikeya Dwivedi
2026-09-03 14:44 ` [PATCH bpf v1 05/10] bpf: Reject resilient lock operations in rbtree callbacks Kumar Kartikeya Dwivedi
2026-09-03 15:31   ` sashiko-bot
2026-09-03 15:36     ` Kumar Kartikeya Dwivedi
2026-09-03 14:44 ` [PATCH bpf v1 06/10] selftests/bpf: Reject resilient unlock in rbtree callback Kumar Kartikeya Dwivedi
2026-09-03 15:52   ` bot+bpf-ci
2026-09-03 14:44 ` [PATCH bpf v1 07/10] bpf: Mark sched_process_wait argument as nullable Kumar Kartikeya Dwivedi
2026-09-03 15:52   ` bot+bpf-ci
2026-09-03 14:44 ` [PATCH bpf v1 08/10] selftests/bpf: Test sched_process_wait nullable argument Kumar Kartikeya Dwivedi
2026-09-03 14:44 ` [PATCH bpf v1 09/10] bpf: Mark syscall helpers as sleepable Kumar Kartikeya Dwivedi
2026-09-03 15:51   ` sashiko-bot
2026-09-03 15:54     ` Kumar Kartikeya Dwivedi
2026-09-03 15:52   ` bot+bpf-ci
2026-09-03 14:44 ` [PATCH bpf v1 10/10] selftests/bpf: Check syscall helpers in timer callbacks Kumar Kartikeya Dwivedi
2026-09-03 16:50 ` [PATCH bpf v1 00/10] Misc bug fixes - part 1 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=20260903144433.1716731-4-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 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.