public inbox for bpf@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH bpf] bpf: tail calls do not modify packet data
@ 2025-10-29 10:58 Martin Teichmann
  2025-10-31 19:24 ` Eduard Zingerman
  0 siblings, 1 reply; 43+ messages in thread
From: Martin Teichmann @ 2025-10-29 10:58 UTC (permalink / raw)
  To: bpf; +Cc: Martin Teichmann

The bpf verifier checks whether packet data is modified within a helper
function, and if so invalidates the pointer to that data. Currently the
verifier always invalidates if the helper function called is a tail
call, as it cannot tell whether the called function does or does not
modify the packet data.

However, in this case, the fact that the packet might be modified is
irrelevant in the code following the helper call, as the tail call only
returns if there is nothing to execute, otherwise the calling
(sub)program will return directly after the tail call finished.

So it is this (sub)program for which the pointer to packet data needs to
be invalidated.

Fortunately, there are already two distinct points in the code for
invalidating packet pointers directly after a helper call, and for
entire (sub)programs. This commit assures that the pointer is only
invalidated in the relevant case.

Note that this is a regression bug: taking care of tail calls only
became necessary when subprograms were introduced, before commit
1a4607ffba35 using a packet pointer after a tail call was working fine,
as it should.

Fixes: 1a4607ffba35 ("bpf: consider that tail calls invalidate packet pointers")
Signed-off-by: Martin Teichmann <martin.teichmann@xfel.eu>
---
 kernel/bpf/verifier.c                          |  3 ++-
 net/core/filter.c                              |  2 --
 .../selftests/bpf/progs/verifier_sock.c        | 18 ++++++++++++++++--
 3 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 6d175849e57a..4bc36a1efe93 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -17879,7 +17879,8 @@ static int visit_insn(int t, struct bpf_verifier_env *env)
 			 */
 			if (ret == 0 && fp->might_sleep)
 				mark_subprog_might_sleep(env, t);
-			if (bpf_helper_changes_pkt_data(insn->imm))
+			if (bpf_helper_changes_pkt_data(insn->imm)
+					|| insn->imm == BPF_FUNC_tail_call)
 				mark_subprog_changes_pkt_data(env, t);
 		} else if (insn->src_reg == BPF_PSEUDO_KFUNC_CALL) {
 			struct bpf_kfunc_call_arg_meta meta;
diff --git a/net/core/filter.c b/net/core/filter.c
index 9d67a34a6650..71a1cfed49f1 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -8038,8 +8038,6 @@ bool bpf_helper_changes_pkt_data(enum bpf_func_id func_id)
 	case BPF_FUNC_xdp_adjust_head:
 	case BPF_FUNC_xdp_adjust_meta:
 	case BPF_FUNC_xdp_adjust_tail:
-	/* tail-called program could call any of the above */
-	case BPF_FUNC_tail_call:
 		return true;
 	default:
 		return false;
diff --git a/tools/testing/selftests/bpf/progs/verifier_sock.c b/tools/testing/selftests/bpf/progs/verifier_sock.c
index 2b4610b53382..3e22b4f8aec4 100644
--- a/tools/testing/selftests/bpf/progs/verifier_sock.c
+++ b/tools/testing/selftests/bpf/progs/verifier_sock.c
@@ -1117,10 +1117,10 @@ int tail_call(struct __sk_buff *sk)
 	return 0;
 }
 
-/* Tail calls invalidate packet pointers. */
+/* Tail calls in sub-programs invalidate packet pointers. */
 SEC("tc")
 __failure __msg("invalid mem access")
-int invalidate_pkt_pointers_by_tail_call(struct __sk_buff *sk)
+int invalidate_pkt_pointers_by_indirect_tail_call(struct __sk_buff *sk)
 {
 	int *p = (void *)(long)sk->data;
 
@@ -1131,4 +1131,18 @@ int invalidate_pkt_pointers_by_tail_call(struct __sk_buff *sk)
 	return TCX_PASS;
 }
 
+/* Direct tail calls do not invalidate packet pointers. */
+SEC("tc")
+__success
+int invalidate_pkt_pointers_by_tail_call(struct __sk_buff *sk)
+{
+	int *p = (void *)(long)sk->data;
+
+	if ((void *)(p + 1) > (void *)(long)sk->data_end)
+		return TCX_DROP;
+	bpf_tail_call_static(sk, &jmp_table, 0);
+	*p = 42; /* this is NOT unsafe: tail calls don't return */
+	return TCX_PASS;
+}
+
 char _license[] SEC("license") = "GPL";
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 43+ messages in thread

end of thread, other threads:[~2025-12-12  2:07 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-29 10:58 [PATCH bpf] bpf: tail calls do not modify packet data Martin Teichmann
2025-10-31 19:24 ` Eduard Zingerman
2025-11-03  8:56   ` Teichmann, Martin
2025-11-03 17:34     ` Eduard Zingerman
2025-11-04 12:54       ` Teichmann, Martin
2025-11-04 13:30   ` [PATCH v2 bpf] bpf: properly verify tail call behavior Martin Teichmann
2025-11-04 13:58     ` bot+bpf-ci
2025-11-04 18:05       ` Alexei Starovoitov
2025-11-04 22:30     ` Eduard Zingerman
2025-11-05 17:40   ` [PATCH v3 bpf-next 0/2] " Martin Teichmann
2025-11-05 19:08     ` Eduard Zingerman
2025-11-06 10:52       ` [PATCH v4 " Martin Teichmann
2025-11-06 10:52       ` [PATCH v4 bpf-next 1/2] " Martin Teichmann
2025-11-06 10:52       ` [PATCH v4 bpf-next 2/2] bpf: test the proper verification of tail calls Martin Teichmann
2025-11-06 19:50         ` Eduard Zingerman
2025-11-10 15:18           ` [PATCH v4 bpf-next 0/2] bpf: properly verify tail call behavior Martin Teichmann
2025-11-10 15:18           ` [PATCH v4 bpf-next 1/2] " Martin Teichmann
2025-11-10 20:28             ` Eduard Zingerman
2025-11-10 23:39               ` Eduard Zingerman
2025-11-13 11:46               ` Teichmann, Martin
2025-11-13 16:09                 ` Alexei Starovoitov
2025-11-18 13:39               ` [PATCH v5 bpf-next 0/4] " Martin Teichmann
2025-11-18 13:39               ` [PATCH v5 bpf-next 1/4] " Martin Teichmann
2025-11-18 19:34                 ` Eduard Zingerman
2025-11-19 16:03                   ` [PATCH v6 bpf-next 0/4] " Martin Teichmann
2025-11-19 16:03                   ` [PATCH v6 bpf-next 1/4] " Martin Teichmann
2025-11-22  2:00                     ` patchwork-bot+netdevbpf
2025-11-19 16:03                   ` [PATCH v6 bpf-next 2/4] bpf: test the proper verification of tail calls Martin Teichmann
2025-11-19 16:03                   ` [PATCH v6 bpf-next 3/4] bpf: correct stack liveness for " Martin Teichmann
2025-11-19 16:33                     ` bot+bpf-ci
2025-12-12  2:06                     ` Chris Mason
2025-11-19 16:03                   ` [PATCH v6 bpf-next 4/4] bpf: test the correct stack liveness of " Martin Teichmann
2025-11-18 13:39               ` [PATCH v5 bpf-next 2/4] bpf: test the proper verification " Martin Teichmann
2025-11-18 22:47                 ` Eduard Zingerman
2025-11-18 13:39               ` [PATCH v5 bpf-next 3/4] bpf: correct stack liveness for " Martin Teichmann
2025-11-18 22:54                 ` Eduard Zingerman
2025-11-18 13:39               ` [PATCH v5 bpf-next 4/4] bpf: test the correct stack liveness of " Martin Teichmann
2025-11-18 22:55                 ` Eduard Zingerman
2025-11-19  0:13                   ` Alexei Starovoitov
2025-11-10 15:18           ` [PATCH v4 bpf-next 2/2] bpf: test the proper verification " Martin Teichmann
2025-11-10 20:32             ` Eduard Zingerman
2025-11-05 17:40   ` [PATCH v3 bpf-next 1/2] bpf: properly verify tail call behavior Martin Teichmann
2025-11-05 17:40   ` [PATCH v3 bpf-next 2/2] bpf: test the proper verification of tail calls Martin Teichmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox