public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH bpf v2 1/2] bpf: Fix same-register dst/src OOB read and pointer leak in sock_ops
@ 2026-04-06  3:12 Jiayuan Chen
  2026-04-06  3:12 ` [PATCH bpf v2 2/2] selftests/bpf: Add tests for sock_ops ctx access with same src/dst register Jiayuan Chen
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Jiayuan Chen @ 2026-04-06  3:12 UTC (permalink / raw)
  To: bpf
  Cc: Jiayuan Chen, Quan Sun, Yinhao Hu, Kaiyan Mei, Dongliang Mu,
	Emil Tsalapatis, Alexei Starovoitov, Daniel Borkmann,
	Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman,
	Kumar Kartikeya Dwivedi, Song Liu, Yonghong Song, Jiri Olsa,
	John Fastabend, Stanislav Fomichev, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Shuah Khan,
	linux-kernel, netdev, linux-kselftest

When a BPF sock_ops program accesses ctx fields with dst_reg == src_reg,
the SOCK_OPS_GET_SK() and SOCK_OPS_GET_FIELD() macros fail to zero the
destination register in the !fullsock / !locked_tcp_sock path.

Both macros borrow a temporary register to check is_fullsock /
is_locked_tcp_sock when dst_reg == src_reg, because dst_reg holds the
ctx pointer. When the check is false (e.g., TCP_NEW_SYN_RECV state with
a request_sock), dst_reg should be zeroed but is not, leaving the stale
ctx pointer:

 - SOCK_OPS_GET_SK: dst_reg retains the ctx pointer, passes NULL checks
   as PTR_TO_SOCKET_OR_NULL, and can be used as a bogus socket pointer,
   leading to stack-out-of-bounds access in helpers like
   bpf_skc_to_tcp6_sock().

 - SOCK_OPS_GET_FIELD: dst_reg retains the ctx pointer which the
   verifier believes is a SCALAR_VALUE, leaking a kernel pointer.

Fix both macros by:
 - Changing JMP_A(1) to JMP_A(2) in the fullsock path to skip the
   added instruction.
 - Adding BPF_MOV64_IMM(si->dst_reg, 0) after the temp register
   restore in the !fullsock path, placed after the restore because
   dst_reg == src_reg means we need src_reg intact to read ctx->temp.

Fixes: 84f44df664e9 ("bpf: sock_ops sk access may stomp registers when dst_reg = src_reg")
Reported-by: Quan Sun <2022090917019@std.uestc.edu.cn>
Reported-by: Yinhao Hu <dddddd@hust.edu.cn>
Reported-by: Kaiyan Mei <M202472210@hust.edu.cn>
Reported-by: Dongliang Mu <dzm91@hust.edu.cn>
Closes: https://lore.kernel.org/bpf/6fe1243e-149b-4d3b-99c7-fcc9e2f75787@std.uestc.edu.cn/T/#u
Suggested-by: Emil Tsalapatis <emil@etsalapatis.com>
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
---
---
 net/core/filter.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/net/core/filter.c b/net/core/filter.c
index 78b548158fb05..53ce06ed4a88e 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -10581,10 +10581,11 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
 				      si->dst_reg, si->dst_reg,		      \
 				      offsetof(OBJ, OBJ_FIELD));	      \
 		if (si->dst_reg == si->src_reg)	{			      \
-			*insn++ = BPF_JMP_A(1);				      \
+			*insn++ = BPF_JMP_A(2);				      \
 			*insn++ = BPF_LDX_MEM(BPF_DW, reg, si->src_reg,	      \
 				      offsetof(struct bpf_sock_ops_kern,      \
 				      temp));				      \
+			*insn++ = BPF_MOV64_IMM(si->dst_reg, 0);	      \
 		}							      \
 	} while (0)
 
@@ -10618,10 +10619,11 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
 				      si->dst_reg, si->src_reg,		      \
 				      offsetof(struct bpf_sock_ops_kern, sk));\
 		if (si->dst_reg == si->src_reg)	{			      \
-			*insn++ = BPF_JMP_A(1);				      \
+			*insn++ = BPF_JMP_A(2);				      \
 			*insn++ = BPF_LDX_MEM(BPF_DW, reg, si->src_reg,	      \
 				      offsetof(struct bpf_sock_ops_kern,      \
 				      temp));				      \
+			*insn++ = BPF_MOV64_IMM(si->dst_reg, 0);	      \
 		}							      \
 	} while (0)
 
-- 
2.43.0


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

* [PATCH bpf v2 2/2] selftests/bpf: Add tests for sock_ops ctx access with same src/dst register
  2026-04-06  3:12 [PATCH bpf v2 1/2] bpf: Fix same-register dst/src OOB read and pointer leak in sock_ops Jiayuan Chen
@ 2026-04-06  3:12 ` Jiayuan Chen
  2026-04-06 16:47   ` sun jian
  2026-04-06 23:01   ` Martin KaFai Lau
  2026-04-06  3:47 ` [PATCH bpf v2 1/2] bpf: Fix same-register dst/src OOB read and pointer leak in sock_ops bot+bpf-ci
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 9+ messages in thread
From: Jiayuan Chen @ 2026-04-06  3:12 UTC (permalink / raw)
  To: bpf
  Cc: Jiayuan Chen, Martin KaFai Lau, Daniel Borkmann, John Fastabend,
	Stanislav Fomichev, Alexei Starovoitov, Andrii Nakryiko,
	Eduard Zingerman, Kumar Kartikeya Dwivedi, Song Liu,
	Yonghong Song, Jiri Olsa, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Shuah Khan,
	linux-kernel, netdev, linux-kselftest

Add selftests to verify SOCK_OPS_GET_SK() and SOCK_OPS_GET_FIELD()
correctly return NULL/zero when dst_reg == src_reg and is_fullsock == 0.

Three subtests are included:
 - get_sk: ctx->sk with same src/dst register (SOCK_OPS_GET_SK)
 - get_field: ctx->snd_cwnd with same src/dst register (SOCK_OPS_GET_FIELD)
 - get_sk_diff_reg: ctx->sk with different src/dst register (baseline)

Each BPF program uses inline asm (__naked) to force specific register
allocation, reads is_fullsock first, then loads the field using the same
(or different) register. The test triggers TCP_NEW_SYN_RECV via a TCP
handshake and checks that the result is NULL/zero when is_fullsock == 0.

Test:
	./test_progs -a sock_ops_get_sk -v
	test_sock_ops_get_sk:PASS:join_cgroup 0 nsec
	test_sock_ops_get_sk:PASS:skel_open_load 0 nsec
	run_sock_ops_test:PASS:prog_attach 0 nsec
	run_sock_ops_test:PASS:start_server 0 nsec
	run_sock_ops_test:PASS:connect_to_fd 0 nsec
	test_sock_ops_get_sk:PASS:null_seen 0 nsec
	test_sock_ops_get_sk:PASS:bug_not_detected 0 nsec
	#419/1   sock_ops_get_sk/get_sk:OK
	run_sock_ops_test:PASS:prog_attach 0 nsec
	run_sock_ops_test:PASS:start_server 0 nsec
	run_sock_ops_test:PASS:connect_to_fd 0 nsec
	test_sock_ops_get_sk:PASS:field_null_seen 0 nsec
	test_sock_ops_get_sk:PASS:field_bug_not_detected 0 nsec
	#419/2   sock_ops_get_sk/get_field:OK
	run_sock_ops_test:PASS:prog_attach 0 nsec
	run_sock_ops_test:PASS:start_server 0 nsec
	run_sock_ops_test:PASS:connect_to_fd 0 nsec
	test_sock_ops_get_sk:PASS:diff_reg_null_seen 0 nsec
	test_sock_ops_get_sk:PASS:diff_reg_bug_not_detected 0 nsec
	#419/3   sock_ops_get_sk/get_sk_diff_reg:OK
	#419     sock_ops_get_sk:OK
	Summary: 1/3 PASSED, 0 SKIPPED, 0 FAILED

Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
---
 .../bpf/prog_tests/sock_ops_get_sk.c          |  77 ++++++++++++
 .../selftests/bpf/progs/sock_ops_get_sk.c     | 117 ++++++++++++++++++
 2 files changed, 194 insertions(+)
 create mode 100644 tools/testing/selftests/bpf/prog_tests/sock_ops_get_sk.c
 create mode 100644 tools/testing/selftests/bpf/progs/sock_ops_get_sk.c

diff --git a/tools/testing/selftests/bpf/prog_tests/sock_ops_get_sk.c b/tools/testing/selftests/bpf/prog_tests/sock_ops_get_sk.c
new file mode 100644
index 0000000000000..e086f7abb197e
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/sock_ops_get_sk.c
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <test_progs.h>
+#include "cgroup_helpers.h"
+#include "network_helpers.h"
+#include "sock_ops_get_sk.skel.h"
+
+/* See progs/sock_ops_get_sk.c for the bug description. */
+static void run_sock_ops_test(struct sock_ops_get_sk *skel, int cgroup_fd,
+			      int prog_fd)
+{
+	int server_fd, client_fd, err;
+
+	err = bpf_prog_attach(prog_fd, cgroup_fd, BPF_CGROUP_SOCK_OPS, 0);
+	if (!ASSERT_OK(err, "prog_attach"))
+		return;
+
+	server_fd = start_server(AF_INET, SOCK_STREAM, NULL, 0, 0);
+	if (!ASSERT_GE(server_fd, 0, "start_server"))
+		goto detach;
+
+	/* Trigger TCP handshake which causes TCP_NEW_SYN_RECV state where
+	 * is_fullsock == 0 and is_locked_tcp_sock == 0.
+	 */
+	client_fd = connect_to_fd(server_fd, 0);
+	if (!ASSERT_GE(client_fd, 0, "connect_to_fd"))
+		goto close_server;
+
+	close(client_fd);
+
+close_server:
+	close(server_fd);
+detach:
+	bpf_prog_detach(cgroup_fd, BPF_CGROUP_SOCK_OPS);
+}
+
+void test_sock_ops_get_sk(void)
+{
+	struct sock_ops_get_sk *skel;
+	int cgroup_fd;
+
+	cgroup_fd = test__join_cgroup("/sock_ops_get_sk");
+	if (!ASSERT_GE(cgroup_fd, 0, "join_cgroup"))
+		return;
+
+	skel = sock_ops_get_sk__open_and_load();
+	if (!ASSERT_OK_PTR(skel, "skel_open_load"))
+		goto close_cgroup;
+
+	/* Test SOCK_OPS_GET_SK with same src/dst register */
+	if (test__start_subtest("get_sk")) {
+		run_sock_ops_test(skel, cgroup_fd,
+				  bpf_program__fd(skel->progs.sock_ops_get_sk_same_reg));
+		ASSERT_EQ(skel->bss->null_seen, 1, "null_seen");
+		ASSERT_EQ(skel->bss->bug_detected, 0, "bug_not_detected");
+	}
+
+	/* Test SOCK_OPS_GET_FIELD with same src/dst register */
+	if (test__start_subtest("get_field")) {
+		run_sock_ops_test(skel, cgroup_fd,
+				  bpf_program__fd(skel->progs.sock_ops_get_field_same_reg));
+		ASSERT_EQ(skel->bss->field_null_seen, 1, "field_null_seen");
+		ASSERT_EQ(skel->bss->field_bug_detected, 0, "field_bug_not_detected");
+	}
+
+	/* Test SOCK_OPS_GET_SK with different src/dst register */
+	if (test__start_subtest("get_sk_diff_reg")) {
+		run_sock_ops_test(skel, cgroup_fd,
+				  bpf_program__fd(skel->progs.sock_ops_get_sk_diff_reg));
+		ASSERT_EQ(skel->bss->diff_reg_null_seen, 1, "diff_reg_null_seen");
+		ASSERT_EQ(skel->bss->diff_reg_bug_detected, 0, "diff_reg_bug_not_detected");
+	}
+
+	sock_ops_get_sk__destroy(skel);
+close_cgroup:
+	close(cgroup_fd);
+}
diff --git a/tools/testing/selftests/bpf/progs/sock_ops_get_sk.c b/tools/testing/selftests/bpf/progs/sock_ops_get_sk.c
new file mode 100644
index 0000000000000..3a0689f8ce7ca
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/sock_ops_get_sk.c
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include "vmlinux.h"
+#include <bpf/bpf_helpers.h>
+#include "bpf_misc.h"
+
+/*
+ * Test the SOCK_OPS_GET_SK() and SOCK_OPS_GET_FIELD() macros in
+ * sock_ops_convert_ctx_access() when dst_reg == src_reg.
+ *
+ * When dst_reg == src_reg, the macros borrow a temporary register to load
+ * is_fullsock / is_locked_tcp_sock, because dst_reg holds the ctx pointer
+ * and cannot be clobbered before ctx->sk / ctx->field is read. If
+ * is_fullsock == 0 (e.g., TCP_NEW_SYN_RECV with a request_sock), the macro
+ * must still zero dst_reg so the verifier's PTR_TO_SOCKET_OR_NULL /
+ * SCALAR_VALUE type is correct at runtime. A missing clear leaves a stale
+ * ctx pointer in dst_reg that passes NULL checks (GET_SK) or leaks a kernel
+ * address as a scalar (GET_FIELD).
+ *
+ * When dst_reg != src_reg, dst_reg itself is used to load is_fullsock, so
+ * the JEQ (dst_reg == 0) naturally leaves it zeroed on the !fullsock path.
+ */
+
+int bug_detected;
+int null_seen;
+
+SEC("sockops")
+__naked void sock_ops_get_sk_same_reg(void)
+{
+	asm volatile (
+		"r7 = *(u32 *)(r1 + %[is_fullsock_off]);"
+		"r1 = *(u64 *)(r1 + %[sk_off]);"
+		"if r7 != 0 goto 2f;"
+		"if r1 == 0 goto 1f;"
+		"r1 = %[bug_detected] ll;"
+		"r2 = 1;"
+		"*(u32 *)(r1 + 0) = r2;"
+		"goto 2f;"
+	"1:"
+		"r1 = %[null_seen] ll;"
+		"r2 = 1;"
+		"*(u32 *)(r1 + 0) = r2;"
+	"2:"
+		"r0 = 1;"
+		"exit;"
+		:
+		: __imm_const(is_fullsock_off, offsetof(struct bpf_sock_ops, is_fullsock)),
+		  __imm_const(sk_off, offsetof(struct bpf_sock_ops, sk)),
+		  __imm_addr(bug_detected),
+		  __imm_addr(null_seen)
+		: __clobber_all);
+}
+
+/* SOCK_OPS_GET_FIELD: same-register, is_locked_tcp_sock == 0 path. */
+int field_bug_detected;
+int field_null_seen;
+
+SEC("sockops")
+__naked void sock_ops_get_field_same_reg(void)
+{
+	asm volatile (
+		"r7 = *(u32 *)(r1 + %[is_fullsock_off]);"
+		"r1 = *(u32 *)(r1 + %[snd_cwnd_off]);"
+		"if r7 != 0 goto 2f;"
+		"if r1 == 0 goto 1f;"
+		"r1 = %[field_bug_detected] ll;"
+		"r2 = 1;"
+		"*(u32 *)(r1 + 0) = r2;"
+		"goto 2f;"
+	"1:"
+		"r1 = %[field_null_seen] ll;"
+		"r2 = 1;"
+		"*(u32 *)(r1 + 0) = r2;"
+	"2:"
+		"r0 = 1;"
+		"exit;"
+		:
+		: __imm_const(is_fullsock_off, offsetof(struct bpf_sock_ops, is_fullsock)),
+		  __imm_const(snd_cwnd_off, offsetof(struct bpf_sock_ops, snd_cwnd)),
+		  __imm_addr(field_bug_detected),
+		  __imm_addr(field_null_seen)
+		: __clobber_all);
+}
+
+/* SOCK_OPS_GET_SK: different-register, is_fullsock == 0 path. */
+int diff_reg_bug_detected;
+int diff_reg_null_seen;
+
+SEC("sockops")
+__naked void sock_ops_get_sk_diff_reg(void)
+{
+	asm volatile (
+		"r7 = r1;"
+		"r6 = *(u32 *)(r7 + %[is_fullsock_off]);"
+		"r2 = *(u64 *)(r7 + %[sk_off]);"
+		"if r6 != 0 goto 2f;"
+		"if r2 == 0 goto 1f;"
+		"r1 = %[diff_reg_bug_detected] ll;"
+		"r3 = 1;"
+		"*(u32 *)(r1 + 0) = r3;"
+		"goto 2f;"
+	"1:"
+		"r1 = %[diff_reg_null_seen] ll;"
+		"r3 = 1;"
+		"*(u32 *)(r1 + 0) = r3;"
+	"2:"
+		"r0 = 1;"
+		"exit;"
+		:
+		: __imm_const(is_fullsock_off, offsetof(struct bpf_sock_ops, is_fullsock)),
+		  __imm_const(sk_off, offsetof(struct bpf_sock_ops, sk)),
+		  __imm_addr(diff_reg_bug_detected),
+		  __imm_addr(diff_reg_null_seen)
+		: __clobber_all);
+}
+
+char _license[] SEC("license") = "GPL";
-- 
2.43.0


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

* Re: [PATCH bpf v2 1/2] bpf: Fix same-register dst/src OOB read and pointer leak in sock_ops
  2026-04-06  3:12 [PATCH bpf v2 1/2] bpf: Fix same-register dst/src OOB read and pointer leak in sock_ops Jiayuan Chen
  2026-04-06  3:12 ` [PATCH bpf v2 2/2] selftests/bpf: Add tests for sock_ops ctx access with same src/dst register Jiayuan Chen
@ 2026-04-06  3:47 ` bot+bpf-ci
  2026-04-06  4:54   ` Jiayuan Chen
  2026-04-06 16:06 ` sun jian
  2026-04-06 23:03 ` Martin KaFai Lau
  3 siblings, 1 reply; 9+ messages in thread
From: bot+bpf-ci @ 2026-04-06  3:47 UTC (permalink / raw)
  To: jiayuan.chen, bpf
  Cc: jiayuan.chen, 2022090917019, dddddd, M202472210, dzm91, emil, ast,
	daniel, andrii, martin.lau, eddyz87, memxor, song, yonghong.song,
	jolsa, john.fastabend, sdf, davem, edumazet, kuba, pabeni, horms,
	shuah, linux-kernel, netdev, linux-kselftest, ast, andrii, daniel,
	martin.lau, eddyz87, yonghong.song, clm, ihor.solodrai

[-- Attachment #1: Type: text/plain, Size: 982 bytes --]

> Fixes: 84f44df664e9 ("bpf: sock_ops sk access may stomp registers when dst_reg = src_reg")

This Fixes: tag covers the SOCK_OPS_GET_SK() portion of the fix,
since 84f44df664e9 introduced that macro. However, the identical
bug in SOCK_OPS_GET_FIELD() was introduced by an earlier commit:

  fd09af010788 ("bpf: sock_ops ctx access may stomp registers in corner case")

That commit added the dst_reg == src_reg handling to
SOCK_OPS_GET_FIELD() with the same missing zeroing in the
!fullsock path. Should this also carry:

  Fixes: fd09af010788 ("bpf: sock_ops ctx access may stomp registers in corner case")

Without it, kernels that have fd09af010788 but not 84f44df664e9
would not receive the SOCK_OPS_GET_FIELD() fix via stable backport.


---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md

CI run summary: https://github.com/kernel-patches/bpf/actions/runs/24017481706

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

* Re: [PATCH bpf v2 1/2] bpf: Fix same-register dst/src OOB read and pointer leak in sock_ops
  2026-04-06  3:47 ` [PATCH bpf v2 1/2] bpf: Fix same-register dst/src OOB read and pointer leak in sock_ops bot+bpf-ci
@ 2026-04-06  4:54   ` Jiayuan Chen
  2026-04-06 23:09     ` Martin KaFai Lau
  0 siblings, 1 reply; 9+ messages in thread
From: Jiayuan Chen @ 2026-04-06  4:54 UTC (permalink / raw)
  To: bot+bpf-ci, bpf
  Cc: 2022090917019, dddddd, M202472210, dzm91, emil, ast, daniel,
	andrii, martin.lau, eddyz87, memxor, song, yonghong.song, jolsa,
	john.fastabend, sdf, davem, edumazet, kuba, pabeni, horms, shuah,
	linux-kernel, netdev, linux-kselftest, martin.lau, clm,
	ihor.solodrai


On 4/6/26 11:47 AM, bot+bpf-ci@kernel.org wrote:
> This Fixes: tag covers the SOCK_OPS_GET_SK() portion of the fix,
> since 84f44df664e9 introduced that macro. However, the identical
> bug in SOCK_OPS_GET_FIELD() was introduced by an earlier commit:
>
>    fd09af010788 ("bpf: sock_ops ctx access may stomp registers in corner case")
>
> That commit added the dst_reg == src_reg handling to
> SOCK_OPS_GET_FIELD() with the same missing zeroing in the
> !fullsock path. Should this also carry:
>
>    Fixes: fd09af010788 ("bpf: sock_ops ctx access may stomp registers in corner case")
>
> Without it, kernels that have fd09af010788 but not 84f44df664e9
> would not receive the SOCK_OPS_GET_FIELD() fix via stable backport.
>
>
> ---
> AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
> See:https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
>
> CI run summary:https://github.com/kernel-patches/bpf/actions/runs/24017481706
Well, it's true. However, fd09af010788 and 84f44df664e9 are from the
same patchset (same author, same minute), so any stable branch carrying
one will have both. That's why I only included a single Fixes tag.

But if you prefer carrying both explicitly, I'm happy to add it in next 
version.

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

* Re: [PATCH bpf v2 1/2] bpf: Fix same-register dst/src OOB read and pointer leak in sock_ops
  2026-04-06  3:12 [PATCH bpf v2 1/2] bpf: Fix same-register dst/src OOB read and pointer leak in sock_ops Jiayuan Chen
  2026-04-06  3:12 ` [PATCH bpf v2 2/2] selftests/bpf: Add tests for sock_ops ctx access with same src/dst register Jiayuan Chen
  2026-04-06  3:47 ` [PATCH bpf v2 1/2] bpf: Fix same-register dst/src OOB read and pointer leak in sock_ops bot+bpf-ci
@ 2026-04-06 16:06 ` sun jian
  2026-04-06 23:03 ` Martin KaFai Lau
  3 siblings, 0 replies; 9+ messages in thread
From: sun jian @ 2026-04-06 16:06 UTC (permalink / raw)
  To: Jiayuan Chen
  Cc: bpf, Quan Sun, Yinhao Hu, Kaiyan Mei, Dongliang Mu,
	Emil Tsalapatis, Alexei Starovoitov, Daniel Borkmann,
	Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman,
	Kumar Kartikeya Dwivedi, Song Liu, Yonghong Song, Jiri Olsa,
	John Fastabend, Stanislav Fomichev, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Shuah Khan,
	linux-kernel, netdev, linux-kselftest

On Mon, Apr 6, 2026 at 11:14 AM Jiayuan Chen <jiayuan.chen@linux.dev> wrote:
>
> When a BPF sock_ops program accesses ctx fields with dst_reg == src_reg,
> the SOCK_OPS_GET_SK() and SOCK_OPS_GET_FIELD() macros fail to zero the
> destination register in the !fullsock / !locked_tcp_sock path.
>
> Both macros borrow a temporary register to check is_fullsock /
> is_locked_tcp_sock when dst_reg == src_reg, because dst_reg holds the
> ctx pointer. When the check is false (e.g., TCP_NEW_SYN_RECV state with
> a request_sock), dst_reg should be zeroed but is not, leaving the stale
> ctx pointer:
>
>  - SOCK_OPS_GET_SK: dst_reg retains the ctx pointer, passes NULL checks
>    as PTR_TO_SOCKET_OR_NULL, and can be used as a bogus socket pointer,
>    leading to stack-out-of-bounds access in helpers like
>    bpf_skc_to_tcp6_sock().
>
>  - SOCK_OPS_GET_FIELD: dst_reg retains the ctx pointer which the
>    verifier believes is a SCALAR_VALUE, leaking a kernel pointer.
>
> Fix both macros by:
>  - Changing JMP_A(1) to JMP_A(2) in the fullsock path to skip the
>    added instruction.
>  - Adding BPF_MOV64_IMM(si->dst_reg, 0) after the temp register
>    restore in the !fullsock path, placed after the restore because
>    dst_reg == src_reg means we need src_reg intact to read ctx->temp.
>
> Fixes: 84f44df664e9 ("bpf: sock_ops sk access may stomp registers when dst_reg = src_reg")
> Reported-by: Quan Sun <2022090917019@std.uestc.edu.cn>
> Reported-by: Yinhao Hu <dddddd@hust.edu.cn>
> Reported-by: Kaiyan Mei <M202472210@hust.edu.cn>
> Reported-by: Dongliang Mu <dzm91@hust.edu.cn>
> Closes: https://lore.kernel.org/bpf/6fe1243e-149b-4d3b-99c7-fcc9e2f75787@std.uestc.edu.cn/T/#u
> Suggested-by: Emil Tsalapatis <emil@etsalapatis.com>
> Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
> ---
> ---
>  net/core/filter.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/net/core/filter.c b/net/core/filter.c
> index 78b548158fb05..53ce06ed4a88e 100644
> --- a/net/core/filter.c
> +++ b/net/core/filter.c
> @@ -10581,10 +10581,11 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
>                                       si->dst_reg, si->dst_reg,               \
>                                       offsetof(OBJ, OBJ_FIELD));              \
>                 if (si->dst_reg == si->src_reg) {                             \
> -                       *insn++ = BPF_JMP_A(1);                               \
> +                       *insn++ = BPF_JMP_A(2);                               \
>                         *insn++ = BPF_LDX_MEM(BPF_DW, reg, si->src_reg,       \
>                                       offsetof(struct bpf_sock_ops_kern,      \
>                                       temp));                                 \
> +                       *insn++ = BPF_MOV64_IMM(si->dst_reg, 0);              \
>                 }                                                             \
>         } while (0)
>
> @@ -10618,10 +10619,11 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
>                                       si->dst_reg, si->src_reg,               \
>                                       offsetof(struct bpf_sock_ops_kern, sk));\
>                 if (si->dst_reg == si->src_reg) {                             \
> -                       *insn++ = BPF_JMP_A(1);                               \
> +                       *insn++ = BPF_JMP_A(2);                               \
>                         *insn++ = BPF_LDX_MEM(BPF_DW, reg, si->src_reg,       \
>                                       offsetof(struct bpf_sock_ops_kern,      \
>                                       temp));                                 \
> +                       *insn++ = BPF_MOV64_IMM(si->dst_reg, 0);              \
>                 }                                                             \
>         } while (0)
>
> --
> 2.43.0
>
>
Reviewed-by Sun Jian <sun.jian.kdev@gmail.com>

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

* Re: [PATCH bpf v2 2/2] selftests/bpf: Add tests for sock_ops ctx access with same src/dst register
  2026-04-06  3:12 ` [PATCH bpf v2 2/2] selftests/bpf: Add tests for sock_ops ctx access with same src/dst register Jiayuan Chen
@ 2026-04-06 16:47   ` sun jian
  2026-04-06 23:01   ` Martin KaFai Lau
  1 sibling, 0 replies; 9+ messages in thread
From: sun jian @ 2026-04-06 16:47 UTC (permalink / raw)
  To: Jiayuan Chen
  Cc: bpf, Martin KaFai Lau, Daniel Borkmann, John Fastabend,
	Stanislav Fomichev, Alexei Starovoitov, Andrii Nakryiko,
	Eduard Zingerman, Kumar Kartikeya Dwivedi, Song Liu,
	Yonghong Song, Jiri Olsa, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Shuah Khan,
	linux-kernel, netdev, linux-kselftest

On Mon, Apr 6, 2026 at 11:15 AM Jiayuan Chen <jiayuan.chen@linux.dev> wrote:
>
> Add selftests to verify SOCK_OPS_GET_SK() and SOCK_OPS_GET_FIELD()
> correctly return NULL/zero when dst_reg == src_reg and is_fullsock == 0.
>
> Three subtests are included:
>  - get_sk: ctx->sk with same src/dst register (SOCK_OPS_GET_SK)
>  - get_field: ctx->snd_cwnd with same src/dst register (SOCK_OPS_GET_FIELD)
>  - get_sk_diff_reg: ctx->sk with different src/dst register (baseline)
>
> Each BPF program uses inline asm (__naked) to force specific register
> allocation, reads is_fullsock first, then loads the field using the same
> (or different) register. The test triggers TCP_NEW_SYN_RECV via a TCP
> handshake and checks that the result is NULL/zero when is_fullsock == 0.
>
> Test:
>         ./test_progs -a sock_ops_get_sk -v
>         test_sock_ops_get_sk:PASS:join_cgroup 0 nsec
>         test_sock_ops_get_sk:PASS:skel_open_load 0 nsec
>         run_sock_ops_test:PASS:prog_attach 0 nsec
>         run_sock_ops_test:PASS:start_server 0 nsec
>         run_sock_ops_test:PASS:connect_to_fd 0 nsec
>         test_sock_ops_get_sk:PASS:null_seen 0 nsec
>         test_sock_ops_get_sk:PASS:bug_not_detected 0 nsec
>         #419/1   sock_ops_get_sk/get_sk:OK
>         run_sock_ops_test:PASS:prog_attach 0 nsec
>         run_sock_ops_test:PASS:start_server 0 nsec
>         run_sock_ops_test:PASS:connect_to_fd 0 nsec
>         test_sock_ops_get_sk:PASS:field_null_seen 0 nsec
>         test_sock_ops_get_sk:PASS:field_bug_not_detected 0 nsec
>         #419/2   sock_ops_get_sk/get_field:OK
>         run_sock_ops_test:PASS:prog_attach 0 nsec
>         run_sock_ops_test:PASS:start_server 0 nsec
>         run_sock_ops_test:PASS:connect_to_fd 0 nsec
>         test_sock_ops_get_sk:PASS:diff_reg_null_seen 0 nsec
>         test_sock_ops_get_sk:PASS:diff_reg_bug_not_detected 0 nsec
>         #419/3   sock_ops_get_sk/get_sk_diff_reg:OK
>         #419     sock_ops_get_sk:OK
>         Summary: 1/3 PASSED, 0 SKIPPED, 0 FAILED
>
> Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
> ---
>  .../bpf/prog_tests/sock_ops_get_sk.c          |  77 ++++++++++++
>  .../selftests/bpf/progs/sock_ops_get_sk.c     | 117 ++++++++++++++++++
>  2 files changed, 194 insertions(+)
>  create mode 100644 tools/testing/selftests/bpf/prog_tests/sock_ops_get_sk.c
>  create mode 100644 tools/testing/selftests/bpf/progs/sock_ops_get_sk.c
>
> diff --git a/tools/testing/selftests/bpf/prog_tests/sock_ops_get_sk.c b/tools/testing/selftests/bpf/prog_tests/sock_ops_get_sk.c
> new file mode 100644
> index 0000000000000..e086f7abb197e
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/prog_tests/sock_ops_get_sk.c
> @@ -0,0 +1,77 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include <test_progs.h>
> +#include "cgroup_helpers.h"
> +#include "network_helpers.h"
> +#include "sock_ops_get_sk.skel.h"
> +
> +/* See progs/sock_ops_get_sk.c for the bug description. */
> +static void run_sock_ops_test(struct sock_ops_get_sk *skel, int cgroup_fd,
> +                             int prog_fd)
> +{
> +       int server_fd, client_fd, err;
> +
> +       err = bpf_prog_attach(prog_fd, cgroup_fd, BPF_CGROUP_SOCK_OPS, 0);
> +       if (!ASSERT_OK(err, "prog_attach"))
> +               return;
> +
> +       server_fd = start_server(AF_INET, SOCK_STREAM, NULL, 0, 0);
> +       if (!ASSERT_GE(server_fd, 0, "start_server"))
> +               goto detach;
> +
> +       /* Trigger TCP handshake which causes TCP_NEW_SYN_RECV state where
> +        * is_fullsock == 0 and is_locked_tcp_sock == 0.
> +        */
> +       client_fd = connect_to_fd(server_fd, 0);
> +       if (!ASSERT_GE(client_fd, 0, "connect_to_fd"))
> +               goto close_server;
> +
> +       close(client_fd);
> +
> +close_server:
> +       close(server_fd);
> +detach:
> +       bpf_prog_detach(cgroup_fd, BPF_CGROUP_SOCK_OPS);
> +}
> +
> +void test_sock_ops_get_sk(void)
> +{
> +       struct sock_ops_get_sk *skel;
> +       int cgroup_fd;
> +
> +       cgroup_fd = test__join_cgroup("/sock_ops_get_sk");
> +       if (!ASSERT_GE(cgroup_fd, 0, "join_cgroup"))
> +               return;
> +
> +       skel = sock_ops_get_sk__open_and_load();
> +       if (!ASSERT_OK_PTR(skel, "skel_open_load"))
> +               goto close_cgroup;
> +
> +       /* Test SOCK_OPS_GET_SK with same src/dst register */
> +       if (test__start_subtest("get_sk")) {
> +               run_sock_ops_test(skel, cgroup_fd,
> +                                 bpf_program__fd(skel->progs.sock_ops_get_sk_same_reg));
> +               ASSERT_EQ(skel->bss->null_seen, 1, "null_seen");
> +               ASSERT_EQ(skel->bss->bug_detected, 0, "bug_not_detected");
> +       }
> +
> +       /* Test SOCK_OPS_GET_FIELD with same src/dst register */
> +       if (test__start_subtest("get_field")) {
> +               run_sock_ops_test(skel, cgroup_fd,
> +                                 bpf_program__fd(skel->progs.sock_ops_get_field_same_reg));
> +               ASSERT_EQ(skel->bss->field_null_seen, 1, "field_null_seen");
> +               ASSERT_EQ(skel->bss->field_bug_detected, 0, "field_bug_not_detected");
> +       }
> +
> +       /* Test SOCK_OPS_GET_SK with different src/dst register */
> +       if (test__start_subtest("get_sk_diff_reg")) {
> +               run_sock_ops_test(skel, cgroup_fd,
> +                                 bpf_program__fd(skel->progs.sock_ops_get_sk_diff_reg));
> +               ASSERT_EQ(skel->bss->diff_reg_null_seen, 1, "diff_reg_null_seen");
> +               ASSERT_EQ(skel->bss->diff_reg_bug_detected, 0, "diff_reg_bug_not_detected");
> +       }
> +
> +       sock_ops_get_sk__destroy(skel);
> +close_cgroup:
> +       close(cgroup_fd);
> +}
> diff --git a/tools/testing/selftests/bpf/progs/sock_ops_get_sk.c b/tools/testing/selftests/bpf/progs/sock_ops_get_sk.c
> new file mode 100644
> index 0000000000000..3a0689f8ce7ca
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/progs/sock_ops_get_sk.c
> @@ -0,0 +1,117 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include "vmlinux.h"
> +#include <bpf/bpf_helpers.h>
> +#include "bpf_misc.h"
> +
> +/*
> + * Test the SOCK_OPS_GET_SK() and SOCK_OPS_GET_FIELD() macros in
> + * sock_ops_convert_ctx_access() when dst_reg == src_reg.
> + *
> + * When dst_reg == src_reg, the macros borrow a temporary register to load
> + * is_fullsock / is_locked_tcp_sock, because dst_reg holds the ctx pointer
> + * and cannot be clobbered before ctx->sk / ctx->field is read. If
> + * is_fullsock == 0 (e.g., TCP_NEW_SYN_RECV with a request_sock), the macro
> + * must still zero dst_reg so the verifier's PTR_TO_SOCKET_OR_NULL /
> + * SCALAR_VALUE type is correct at runtime. A missing clear leaves a stale
> + * ctx pointer in dst_reg that passes NULL checks (GET_SK) or leaks a kernel
> + * address as a scalar (GET_FIELD).
> + *
> + * When dst_reg != src_reg, dst_reg itself is used to load is_fullsock, so
> + * the JEQ (dst_reg == 0) naturally leaves it zeroed on the !fullsock path.
> + */
> +
> +int bug_detected;
> +int null_seen;
> +
> +SEC("sockops")
> +__naked void sock_ops_get_sk_same_reg(void)
> +{
> +       asm volatile (
> +               "r7 = *(u32 *)(r1 + %[is_fullsock_off]);"
> +               "r1 = *(u64 *)(r1 + %[sk_off]);"
> +               "if r7 != 0 goto 2f;"
> +               "if r1 == 0 goto 1f;"
> +               "r1 = %[bug_detected] ll;"
> +               "r2 = 1;"
> +               "*(u32 *)(r1 + 0) = r2;"
> +               "goto 2f;"
> +       "1:"
> +               "r1 = %[null_seen] ll;"
> +               "r2 = 1;"
> +               "*(u32 *)(r1 + 0) = r2;"
> +       "2:"
> +               "r0 = 1;"
> +               "exit;"
> +               :
> +               : __imm_const(is_fullsock_off, offsetof(struct bpf_sock_ops, is_fullsock)),
> +                 __imm_const(sk_off, offsetof(struct bpf_sock_ops, sk)),
> +                 __imm_addr(bug_detected),
> +                 __imm_addr(null_seen)
> +               : __clobber_all);
> +}
> +
> +/* SOCK_OPS_GET_FIELD: same-register, is_locked_tcp_sock == 0 path. */
> +int field_bug_detected;
> +int field_null_seen;
> +
> +SEC("sockops")
> +__naked void sock_ops_get_field_same_reg(void)
> +{
> +       asm volatile (
> +               "r7 = *(u32 *)(r1 + %[is_fullsock_off]);"
> +               "r1 = *(u32 *)(r1 + %[snd_cwnd_off]);"
> +               "if r7 != 0 goto 2f;"
> +               "if r1 == 0 goto 1f;"
> +               "r1 = %[field_bug_detected] ll;"
> +               "r2 = 1;"
> +               "*(u32 *)(r1 + 0) = r2;"
> +               "goto 2f;"
> +       "1:"
> +               "r1 = %[field_null_seen] ll;"
> +               "r2 = 1;"
> +               "*(u32 *)(r1 + 0) = r2;"
> +       "2:"
> +               "r0 = 1;"
> +               "exit;"
> +               :
> +               : __imm_const(is_fullsock_off, offsetof(struct bpf_sock_ops, is_fullsock)),
> +                 __imm_const(snd_cwnd_off, offsetof(struct bpf_sock_ops, snd_cwnd)),
> +                 __imm_addr(field_bug_detected),
> +                 __imm_addr(field_null_seen)
> +               : __clobber_all);
> +}
> +
> +/* SOCK_OPS_GET_SK: different-register, is_fullsock == 0 path. */
> +int diff_reg_bug_detected;
> +int diff_reg_null_seen;
> +
> +SEC("sockops")
> +__naked void sock_ops_get_sk_diff_reg(void)
> +{
> +       asm volatile (
> +               "r7 = r1;"
> +               "r6 = *(u32 *)(r7 + %[is_fullsock_off]);"
> +               "r2 = *(u64 *)(r7 + %[sk_off]);"
> +               "if r6 != 0 goto 2f;"
> +               "if r2 == 0 goto 1f;"
> +               "r1 = %[diff_reg_bug_detected] ll;"
> +               "r3 = 1;"
> +               "*(u32 *)(r1 + 0) = r3;"
> +               "goto 2f;"
> +       "1:"
> +               "r1 = %[diff_reg_null_seen] ll;"
> +               "r3 = 1;"
> +               "*(u32 *)(r1 + 0) = r3;"
> +       "2:"
> +               "r0 = 1;"
> +               "exit;"
> +               :
> +               : __imm_const(is_fullsock_off, offsetof(struct bpf_sock_ops, is_fullsock)),
> +                 __imm_const(sk_off, offsetof(struct bpf_sock_ops, sk)),
> +                 __imm_addr(diff_reg_bug_detected),
> +                 __imm_addr(diff_reg_null_seen)
> +               : __clobber_all);
> +}
> +
> +char _license[] SEC("license") = "GPL";
> --
> 2.43.0
>
>

Reviewed-by: Sun Jian <sun.jian.kdev@gmail.com>

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

* Re: [PATCH bpf v2 2/2] selftests/bpf: Add tests for sock_ops ctx access with same src/dst register
  2026-04-06  3:12 ` [PATCH bpf v2 2/2] selftests/bpf: Add tests for sock_ops ctx access with same src/dst register Jiayuan Chen
  2026-04-06 16:47   ` sun jian
@ 2026-04-06 23:01   ` Martin KaFai Lau
  1 sibling, 0 replies; 9+ messages in thread
From: Martin KaFai Lau @ 2026-04-06 23:01 UTC (permalink / raw)
  To: Jiayuan Chen
  Cc: bpf, Daniel Borkmann, John Fastabend, Stanislav Fomichev,
	Alexei Starovoitov, Andrii Nakryiko, Eduard Zingerman,
	Kumar Kartikeya Dwivedi, Song Liu, Yonghong Song, Jiri Olsa,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Shuah Khan, linux-kernel, netdev, linux-kselftest

On Mon, Apr 06, 2026 at 11:12:51AM +0800, Jiayuan Chen wrote:
> diff --git a/tools/testing/selftests/bpf/prog_tests/sock_ops_get_sk.c b/tools/testing/selftests/bpf/prog_tests/sock_ops_get_sk.c
> new file mode 100644
> index 0000000000000..e086f7abb197e
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/prog_tests/sock_ops_get_sk.c
> @@ -0,0 +1,77 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include <test_progs.h>
> +#include "cgroup_helpers.h"
> +#include "network_helpers.h"
> +#include "sock_ops_get_sk.skel.h"
> +
> +/* See progs/sock_ops_get_sk.c for the bug description. */
> +static void run_sock_ops_test(struct sock_ops_get_sk *skel, int cgroup_fd,

skel is not used. sashiko has flagged it also.

pw-bot: cr

> +			      int prog_fd)
> +{
> +	int server_fd, client_fd, err;
> +
> +	err = bpf_prog_attach(prog_fd, cgroup_fd, BPF_CGROUP_SOCK_OPS, 0);
> +	if (!ASSERT_OK(err, "prog_attach"))
> +		return;
> +
> +	server_fd = start_server(AF_INET, SOCK_STREAM, NULL, 0, 0);
> +	if (!ASSERT_GE(server_fd, 0, "start_server"))
> +		goto detach;
> +
> +	/* Trigger TCP handshake which causes TCP_NEW_SYN_RECV state where
> +	 * is_fullsock == 0 and is_locked_tcp_sock == 0.
> +	 */
> +	client_fd = connect_to_fd(server_fd, 0);
> +	if (!ASSERT_GE(client_fd, 0, "connect_to_fd"))
> +		goto close_server;
> +
> +	close(client_fd);
> +
> +close_server:
> +	close(server_fd);
> +detach:
> +	bpf_prog_detach(cgroup_fd, BPF_CGROUP_SOCK_OPS);
> +}
> +
> +void test_sock_ops_get_sk(void)

Add a "ns" in the naming so that test_progs will start a new netns.

Like 'void test_ns_sock_ops_get_sk(void)'.

> +{
> +	struct sock_ops_get_sk *skel;
> +	int cgroup_fd;
> +
> +	cgroup_fd = test__join_cgroup("/sock_ops_get_sk");
> +	if (!ASSERT_GE(cgroup_fd, 0, "join_cgroup"))

nit. Use ASSERT_OK_FD check. Same for the other fd checks in this file.

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

* Re: [PATCH bpf v2 1/2] bpf: Fix same-register dst/src OOB read and pointer leak in sock_ops
  2026-04-06  3:12 [PATCH bpf v2 1/2] bpf: Fix same-register dst/src OOB read and pointer leak in sock_ops Jiayuan Chen
                   ` (2 preceding siblings ...)
  2026-04-06 16:06 ` sun jian
@ 2026-04-06 23:03 ` Martin KaFai Lau
  3 siblings, 0 replies; 9+ messages in thread
From: Martin KaFai Lau @ 2026-04-06 23:03 UTC (permalink / raw)
  To: Jiayuan Chen
  Cc: bpf, Quan Sun, Yinhao Hu, Kaiyan Mei, Dongliang Mu,
	Emil Tsalapatis, Alexei Starovoitov, Daniel Borkmann,
	Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi,
	Song Liu, Yonghong Song, Jiri Olsa, John Fastabend,
	Stanislav Fomichev, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Shuah Khan, linux-kernel, netdev,
	linux-kselftest

On Mon, Apr 06, 2026 at 11:12:50AM +0800, Jiayuan Chen wrote:
> diff --git a/net/core/filter.c b/net/core/filter.c
> index 78b548158fb05..53ce06ed4a88e 100644
> --- a/net/core/filter.c
> +++ b/net/core/filter.c
> @@ -10581,10 +10581,11 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
>  				      si->dst_reg, si->dst_reg,		      \
>  				      offsetof(OBJ, OBJ_FIELD));	      \
>  		if (si->dst_reg == si->src_reg)	{			      \
> -			*insn++ = BPF_JMP_A(1);				      \
> +			*insn++ = BPF_JMP_A(2);				      \
>  			*insn++ = BPF_LDX_MEM(BPF_DW, reg, si->src_reg,	      \
>  				      offsetof(struct bpf_sock_ops_kern,      \
>  				      temp));				      \
> +			*insn++ = BPF_MOV64_IMM(si->dst_reg, 0);	      \
>  		}							      \
>  	} while (0)
>  
> @@ -10618,10 +10619,11 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
>  				      si->dst_reg, si->src_reg,		      \
>  				      offsetof(struct bpf_sock_ops_kern, sk));\
>  		if (si->dst_reg == si->src_reg)	{			      \
> -			*insn++ = BPF_JMP_A(1);				      \
> +			*insn++ = BPF_JMP_A(2);				      \
>  			*insn++ = BPF_LDX_MEM(BPF_DW, reg, si->src_reg,	      \
>  				      offsetof(struct bpf_sock_ops_kern,      \
>  				      temp));				      \
> +			*insn++ = BPF_MOV64_IMM(si->dst_reg, 0);	      \

Acked-by: Martin KaFai Lau <martin.lau@kernel.org>

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

* Re: [PATCH bpf v2 1/2] bpf: Fix same-register dst/src OOB read and pointer leak in sock_ops
  2026-04-06  4:54   ` Jiayuan Chen
@ 2026-04-06 23:09     ` Martin KaFai Lau
  0 siblings, 0 replies; 9+ messages in thread
From: Martin KaFai Lau @ 2026-04-06 23:09 UTC (permalink / raw)
  To: Jiayuan Chen
  Cc: bot+bpf-ci, bpf, 2022090917019, dddddd, M202472210, dzm91, emil,
	ast, daniel, andrii, eddyz87, memxor, song, yonghong.song, jolsa,
	john.fastabend, sdf, davem, edumazet, kuba, pabeni, horms, shuah,
	linux-kernel, netdev, linux-kselftest, martin.lau, clm,
	ihor.solodrai

On Mon, Apr 06, 2026 at 12:54:04PM +0800, Jiayuan Chen wrote:
> 
> On 4/6/26 11:47 AM, bot+bpf-ci@kernel.org wrote:
> > This Fixes: tag covers the SOCK_OPS_GET_SK() portion of the fix,
> > since 84f44df664e9 introduced that macro. However, the identical
> > bug in SOCK_OPS_GET_FIELD() was introduced by an earlier commit:
> > 
> >    fd09af010788 ("bpf: sock_ops ctx access may stomp registers in corner case")
> > 
> > That commit added the dst_reg == src_reg handling to
> > SOCK_OPS_GET_FIELD() with the same missing zeroing in the
> > !fullsock path. Should this also carry:
> > 
> >    Fixes: fd09af010788 ("bpf: sock_ops ctx access may stomp registers in corner case")
> > 
> > Without it, kernels that have fd09af010788 but not 84f44df664e9
> > would not receive the SOCK_OPS_GET_FIELD() fix via stable backport.
> > 
> > 
> > ---
> > AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
> > See:https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
> > 
> > CI run summary:https://github.com/kernel-patches/bpf/actions/runs/24017481706
> Well, it's true. However, fd09af010788 and 84f44df664e9 are from the
> same patchset (same author, same minute), so any stable branch carrying
> one will have both. That's why I only included a single Fixes tag.
> 
> But if you prefer carrying both explicitly, I'm happy to add it in next
> version.

Please list both in the Fixes tags so that it is clear both bugs will
be fixed. Thanks.

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

end of thread, other threads:[~2026-04-06 23:10 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-06  3:12 [PATCH bpf v2 1/2] bpf: Fix same-register dst/src OOB read and pointer leak in sock_ops Jiayuan Chen
2026-04-06  3:12 ` [PATCH bpf v2 2/2] selftests/bpf: Add tests for sock_ops ctx access with same src/dst register Jiayuan Chen
2026-04-06 16:47   ` sun jian
2026-04-06 23:01   ` Martin KaFai Lau
2026-04-06  3:47 ` [PATCH bpf v2 1/2] bpf: Fix same-register dst/src OOB read and pointer leak in sock_ops bot+bpf-ci
2026-04-06  4:54   ` Jiayuan Chen
2026-04-06 23:09     ` Martin KaFai Lau
2026-04-06 16:06 ` sun jian
2026-04-06 23:03 ` Martin KaFai Lau

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