From 770f360c778d475bd919a0075bfec3519cfe2d61 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Wed, 20 May 2026 10:38:15 -0400 Subject: [PATCH] Drop bpf-sockmap-fix-af_unix-iter-deadlock.patch from 5.15 Signed-off-by: Sasha Levin --- ...-batching-algorithm-in-bpf-unix-iter.patch | 265 ------------------ ...tf-8-literals-in-bpf_bprintf_prepare.patch | 84 ------ ...-bpf-to-bpf-calls-and-callbacks-in-t.patch | 96 ------- ...ce-bug-in-convert_bpf_ld_abs-alignme.patch | 46 --- ...pf-sockmap-fix-af_unix-iter-deadlock.patch | 101 ------- ...map-take-state-lock-for-af_unix-iter.patch | 115 -------- queue-5.15/series | 6 - 7 files changed, 713 deletions(-) delete mode 100644 queue-5.15/bpf-af_unix-use-batching-algorithm-in-bpf-unix-iter.patch delete mode 100644 queue-5.15/bpf-allow-utf-8-literals-in-bpf_bprintf_prepare.patch delete mode 100644 queue-5.15/bpf-arm32-reject-bpf-to-bpf-calls-and-callbacks-in-t.patch delete mode 100644 queue-5.15/bpf-fix-precedence-bug-in-convert_bpf_ld_abs-alignme.patch delete mode 100644 queue-5.15/bpf-sockmap-fix-af_unix-iter-deadlock.patch delete mode 100644 queue-5.15/bpf-sockmap-take-state-lock-for-af_unix-iter.patch diff --git a/queue-5.15/bpf-af_unix-use-batching-algorithm-in-bpf-unix-iter.patch b/queue-5.15/bpf-af_unix-use-batching-algorithm-in-bpf-unix-iter.patch deleted file mode 100644 index a3d86491cc..0000000000 --- a/queue-5.15/bpf-af_unix-use-batching-algorithm-in-bpf-unix-iter.patch +++ /dev/null @@ -1,265 +0,0 @@ -From 4838980149184dc89c26fb7b43ca522a87881143 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 13 Jan 2022 09:28:46 +0900 -Subject: bpf: af_unix: Use batching algorithm in bpf unix iter. - -From: Kuniyuki Iwashima - -[ Upstream commit 855d8e77ffb05be6e54c34dababccb20318aec00 ] - -The commit 04c7820b776f ("bpf: tcp: Bpf iter batching and lock_sock") -introduces the batching algorithm to iterate TCP sockets with more -consistency. - -This patch uses the same algorithm to iterate AF_UNIX sockets. - -Signed-off-by: Kuniyuki Iwashima -Link: https://lore.kernel.org/r/20220113002849.4384-3-kuniyu@amazon.co.jp -Signed-off-by: Alexei Starovoitov -Stable-dep-of: 4d328dd69538 ("bpf, sockmap: Fix af_unix iter deadlock") -Signed-off-by: Sasha Levin ---- - net/unix/af_unix.c | 184 +++++++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 177 insertions(+), 7 deletions(-) - -diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c -index ea8fd8eb3ebc1..12a4c1542459c 100644 ---- a/net/unix/af_unix.c -+++ b/net/unix/af_unix.c -@@ -3300,6 +3300,15 @@ static const struct seq_operations unix_seq_ops = { - }; - - #if IS_BUILTIN(CONFIG_UNIX) && defined(CONFIG_BPF_SYSCALL) -+struct bpf_unix_iter_state { -+ struct seq_net_private p; -+ unsigned int cur_sk; -+ unsigned int end_sk; -+ unsigned int max_sk; -+ struct sock **batch; -+ bool st_bucket_done; -+}; -+ - struct bpf_iter__unix { - __bpf_md_ptr(struct bpf_iter_meta *, meta); - __bpf_md_ptr(struct unix_sock *, unix_sk); -@@ -3318,24 +3327,156 @@ static int unix_prog_seq_show(struct bpf_prog *prog, struct bpf_iter_meta *meta, - return bpf_iter_run_prog(prog, &ctx); - } - -+static int bpf_iter_unix_hold_batch(struct seq_file *seq, struct sock *start_sk) -+ -+{ -+ struct bpf_unix_iter_state *iter = seq->private; -+ unsigned int expected = 1; -+ struct sock *sk; -+ -+ sock_hold(start_sk); -+ iter->batch[iter->end_sk++] = start_sk; -+ -+ for (sk = sk_next(start_sk); sk; sk = sk_next(sk)) { -+ if (sock_net(sk) != seq_file_net(seq)) -+ continue; -+ -+ if (iter->end_sk < iter->max_sk) { -+ sock_hold(sk); -+ iter->batch[iter->end_sk++] = sk; -+ } -+ -+ expected++; -+ } -+ -+ spin_unlock(&unix_table_locks[start_sk->sk_hash]); -+ -+ return expected; -+} -+ -+static void bpf_iter_unix_put_batch(struct bpf_unix_iter_state *iter) -+{ -+ while (iter->cur_sk < iter->end_sk) -+ sock_put(iter->batch[iter->cur_sk++]); -+} -+ -+static int bpf_iter_unix_realloc_batch(struct bpf_unix_iter_state *iter, -+ unsigned int new_batch_sz) -+{ -+ struct sock **new_batch; -+ -+ new_batch = kvmalloc(sizeof(*new_batch) * new_batch_sz, -+ GFP_USER | __GFP_NOWARN); -+ if (!new_batch) -+ return -ENOMEM; -+ -+ bpf_iter_unix_put_batch(iter); -+ kvfree(iter->batch); -+ iter->batch = new_batch; -+ iter->max_sk = new_batch_sz; -+ -+ return 0; -+} -+ -+static struct sock *bpf_iter_unix_batch(struct seq_file *seq, -+ loff_t *pos) -+{ -+ struct bpf_unix_iter_state *iter = seq->private; -+ unsigned int expected; -+ bool resized = false; -+ struct sock *sk; -+ -+ if (iter->st_bucket_done) -+ *pos = set_bucket_offset(get_bucket(*pos) + 1, 1); -+ -+again: -+ /* Get a new batch */ -+ iter->cur_sk = 0; -+ iter->end_sk = 0; -+ -+ sk = unix_get_first(seq, pos); -+ if (!sk) -+ return NULL; /* Done */ -+ -+ expected = bpf_iter_unix_hold_batch(seq, sk); -+ -+ if (iter->end_sk == expected) { -+ iter->st_bucket_done = true; -+ return sk; -+ } -+ -+ if (!resized && !bpf_iter_unix_realloc_batch(iter, expected * 3 / 2)) { -+ resized = true; -+ goto again; -+ } -+ -+ return sk; -+} -+ -+static void *bpf_iter_unix_seq_start(struct seq_file *seq, loff_t *pos) -+{ -+ if (!*pos) -+ return SEQ_START_TOKEN; -+ -+ /* bpf iter does not support lseek, so it always -+ * continue from where it was stop()-ped. -+ */ -+ return bpf_iter_unix_batch(seq, pos); -+} -+ -+static void *bpf_iter_unix_seq_next(struct seq_file *seq, void *v, loff_t *pos) -+{ -+ struct bpf_unix_iter_state *iter = seq->private; -+ struct sock *sk; -+ -+ /* Whenever seq_next() is called, the iter->cur_sk is -+ * done with seq_show(), so advance to the next sk in -+ * the batch. -+ */ -+ if (iter->cur_sk < iter->end_sk) -+ sock_put(iter->batch[iter->cur_sk++]); -+ -+ ++*pos; -+ -+ if (iter->cur_sk < iter->end_sk) -+ sk = iter->batch[iter->cur_sk]; -+ else -+ sk = bpf_iter_unix_batch(seq, pos); -+ -+ return sk; -+} -+ - static int bpf_iter_unix_seq_show(struct seq_file *seq, void *v) - { - struct bpf_iter_meta meta; - struct bpf_prog *prog; - struct sock *sk = v; - uid_t uid; -+ bool slow; -+ int ret; - - if (v == SEQ_START_TOKEN) - return 0; - -+ slow = lock_sock_fast(sk); -+ -+ if (unlikely(sk_unhashed(sk))) { -+ ret = SEQ_SKIP; -+ goto unlock; -+ } -+ - uid = from_kuid_munged(seq_user_ns(seq), sock_i_uid(sk)); - meta.seq = seq; - prog = bpf_iter_get_info(&meta, false); -- return unix_prog_seq_show(prog, &meta, v, uid); -+ ret = unix_prog_seq_show(prog, &meta, v, uid); -+unlock: -+ unlock_sock_fast(sk, slow); -+ return ret; - } - - static void bpf_iter_unix_seq_stop(struct seq_file *seq, void *v) - { -+ struct bpf_unix_iter_state *iter = seq->private; - struct bpf_iter_meta meta; - struct bpf_prog *prog; - -@@ -3346,12 +3487,13 @@ static void bpf_iter_unix_seq_stop(struct seq_file *seq, void *v) - (void)unix_prog_seq_show(prog, &meta, v, 0); - } - -- unix_seq_stop(seq, v); -+ if (iter->cur_sk < iter->end_sk) -+ bpf_iter_unix_put_batch(iter); - } - - static const struct seq_operations bpf_iter_unix_seq_ops = { -- .start = unix_seq_start, -- .next = unix_seq_next, -+ .start = bpf_iter_unix_seq_start, -+ .next = bpf_iter_unix_seq_next, - .stop = bpf_iter_unix_seq_stop, - .show = bpf_iter_unix_seq_show, - }; -@@ -3400,11 +3542,39 @@ static struct pernet_operations unix_net_ops = { - DEFINE_BPF_ITER_FUNC(unix, struct bpf_iter_meta *meta, - struct unix_sock *unix_sk, uid_t uid) - -+#define INIT_BATCH_SZ 16 -+ -+static int bpf_iter_init_unix(void *priv_data, struct bpf_iter_aux_info *aux) -+{ -+ struct bpf_unix_iter_state *iter = priv_data; -+ int err; -+ -+ err = bpf_iter_init_seq_net(priv_data, aux); -+ if (err) -+ return err; -+ -+ err = bpf_iter_unix_realloc_batch(iter, INIT_BATCH_SZ); -+ if (err) { -+ bpf_iter_fini_seq_net(priv_data); -+ return err; -+ } -+ -+ return 0; -+} -+ -+static void bpf_iter_fini_unix(void *priv_data) -+{ -+ struct bpf_unix_iter_state *iter = priv_data; -+ -+ bpf_iter_fini_seq_net(priv_data); -+ kvfree(iter->batch); -+} -+ - static const struct bpf_iter_seq_info unix_seq_info = { - .seq_ops = &bpf_iter_unix_seq_ops, -- .init_seq_private = bpf_iter_init_seq_net, -- .fini_seq_private = bpf_iter_fini_seq_net, -- .seq_priv_size = sizeof(struct seq_net_private), -+ .init_seq_private = bpf_iter_init_unix, -+ .fini_seq_private = bpf_iter_fini_unix, -+ .seq_priv_size = sizeof(struct bpf_unix_iter_state), - }; - - static struct bpf_iter_reg unix_reg_info = { --- -2.53.0 - diff --git a/queue-5.15/bpf-allow-utf-8-literals-in-bpf_bprintf_prepare.patch b/queue-5.15/bpf-allow-utf-8-literals-in-bpf_bprintf_prepare.patch deleted file mode 100644 index f2c6d0366a..0000000000 --- a/queue-5.15/bpf-allow-utf-8-literals-in-bpf_bprintf_prepare.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 5c408c21d8be97c1a4ae88c010367b8623504665 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 16 Apr 2026 20:01:41 +0800 -Subject: bpf: allow UTF-8 literals in bpf_bprintf_prepare() - -From: Yihan Ding - -[ Upstream commit b960430ea8862ef37ce53c8bf74a8dc79d3f2404 ] - -bpf_bprintf_prepare() only needs ASCII parsing for conversion -specifiers. Plain text can safely carry bytes >= 0x80, so allow -UTF-8 literals outside '%' sequences while keeping ASCII control -bytes rejected and format specifiers ASCII-only. - -This keeps existing parsing rules for format directives unchanged, -while allowing helpers such as bpf_trace_printk() to emit UTF-8 -literal text. - -Update test_snprintf_negative() in the same commit so selftests keep -matching the new plain-text vs format-specifier split during bisection. - -Fixes: 48cac3f4a96d ("bpf: Implement formatted output helpers with bstr_printf") -Signed-off-by: Yihan Ding -Acked-by: Paul Chaignon -Link: https://lore.kernel.org/r/20260416120142.1420646-2-dingyihan@uniontech.com -Signed-off-by: Alexei Starovoitov -Signed-off-by: Sasha Levin ---- - kernel/bpf/helpers.c | 17 ++++++++++++++++- - .../testing/selftests/bpf/prog_tests/snprintf.c | 3 ++- - 2 files changed, 18 insertions(+), 2 deletions(-) - -diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c -index b40ca025d9a44..b4abe6aefef4c 100644 ---- a/kernel/bpf/helpers.c -+++ b/kernel/bpf/helpers.c -@@ -796,7 +796,13 @@ int bpf_bprintf_prepare(char *fmt, u32 fmt_size, const u64 *raw_args, - data->buf = buffers->buf; - - for (i = 0; i < fmt_size; i++) { -- if ((!isprint(fmt[i]) && !isspace(fmt[i])) || !isascii(fmt[i])) { -+ unsigned char c = fmt[i]; -+ -+ /* -+ * Permit bytes >= 0x80 in plain text so UTF-8 literals can pass -+ * through unchanged, while still rejecting ASCII control bytes. -+ */ -+ if (isascii(c) && !isprint(c) && !isspace(c)) { - err = -EINVAL; - goto out; - } -@@ -818,6 +824,15 @@ int bpf_bprintf_prepare(char *fmt, u32 fmt_size, const u64 *raw_args, - * always access fmt[i + 1], in the worst case it will be a 0 - */ - i++; -+ c = fmt[i]; -+ /* -+ * The format parser below only understands ASCII conversion -+ * specifiers and modifiers, so reject non-ASCII after '%'. -+ */ -+ if (!isascii(c)) { -+ err = -EINVAL; -+ goto out; -+ } - - /* skip optional "[0 +-][num]" width formatting field */ - while (fmt[i] == '0' || fmt[i] == '+' || fmt[i] == '-' || -diff --git a/tools/testing/selftests/bpf/prog_tests/snprintf.c b/tools/testing/selftests/bpf/prog_tests/snprintf.c -index 8fd1b4b29a0e0..14419b9407281 100644 ---- a/tools/testing/selftests/bpf/prog_tests/snprintf.c -+++ b/tools/testing/selftests/bpf/prog_tests/snprintf.c -@@ -116,7 +116,8 @@ void test_snprintf_negative(void) - ASSERT_ERR(load_single_snprintf("%--------"), "invalid specifier 5"); - ASSERT_ERR(load_single_snprintf("%lc"), "invalid specifier 6"); - ASSERT_ERR(load_single_snprintf("%llc"), "invalid specifier 7"); -- ASSERT_ERR(load_single_snprintf("\x80"), "non ascii character"); -+ ASSERT_OK(load_single_snprintf("\x80"), "non ascii plain text"); -+ ASSERT_ERR(load_single_snprintf("%\x80"), "non ascii in specifier"); - ASSERT_ERR(load_single_snprintf("\x1"), "non printable character"); - } - --- -2.53.0 - diff --git a/queue-5.15/bpf-arm32-reject-bpf-to-bpf-calls-and-callbacks-in-t.patch b/queue-5.15/bpf-arm32-reject-bpf-to-bpf-calls-and-callbacks-in-t.patch deleted file mode 100644 index d8a10d288e..0000000000 --- a/queue-5.15/bpf-arm32-reject-bpf-to-bpf-calls-and-callbacks-in-t.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 84dbf85f177c93739e33ca63d4f62e4bad2ea68d Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Fri, 17 Apr 2026 07:33:52 -0700 -Subject: bpf, arm32: Reject BPF-to-BPF calls and callbacks in the JIT - -From: Puranjay Mohan - -[ Upstream commit e1d486445af3c392628532229f7ce5f5cf7891b6 ] - -The ARM32 BPF JIT does not support BPF-to-BPF function calls -(BPF_PSEUDO_CALL) or callbacks (BPF_PSEUDO_FUNC), but it does -not reject them either. - -When a program with subprograms is loaded (e.g. libxdp's XDP -dispatcher uses __noinline__ subprograms, or any program using -callbacks like bpf_loop or bpf_for_each_map_elem), the verifier -invokes bpf_jit_subprogs() which calls bpf_int_jit_compile() -for each subprogram. - -For BPF_PSEUDO_CALL, since ARM32 does not reject it, the JIT -silently emits code using the wrong address computation: - - func = __bpf_call_base + imm - -where imm is a pc-relative subprogram offset, producing a bogus -function pointer. - -For BPF_PSEUDO_FUNC, the ldimm64 handler ignores src_reg and -loads the immediate as a normal 64-bit value without error. - -In both cases, build_body() reports success and a JIT image is -allocated. ARM32 lacks the jit_data/extra_pass mechanism needed -for the second JIT pass in bpf_jit_subprogs(). On the second -pass, bpf_int_jit_compile() performs a full fresh compilation, -allocating a new JIT binary and overwriting prog->bpf_func. The -first allocation is never freed. bpf_jit_subprogs() then detects -the function pointer changed and aborts with -ENOTSUPP, but the -original JIT binary has already been leaked. Each program -load/unload cycle leaks one JIT binary allocation, as reported -by kmemleak: - - unreferenced object 0xbf0a1000 (size 4096): - backtrace: - bpf_jit_binary_alloc+0x64/0xfc - bpf_int_jit_compile+0x14c/0x348 - bpf_jit_subprogs+0x4fc/0xa60 - -Fix this by rejecting both BPF_PSEUDO_CALL in the BPF_CALL -handler and BPF_PSEUDO_FUNC in the BPF_LD_IMM64 handler, falling -through to the existing 'notyet' path. This causes build_body() -to fail before any JIT binary is allocated, so -bpf_int_jit_compile() returns the original program unjitted. -bpf_jit_subprogs() then sees !prog->jited and cleanly falls -back to the interpreter with no leak. - -Acked-by: Daniel Borkmann -Fixes: 1c2a088a6626 ("bpf: x64: add JIT support for multi-function programs") -Reported-by: Jonas Rebmann -Closes: https://lore.kernel.org/bpf/b63e9174-7a3d-4e22-8294-16df07a4af89@pengutronix.de -Tested-by: Jonas Rebmann -Signed-off-by: Puranjay Mohan -Reviewed-by: Emil Tsalapatis -Link: https://lore.kernel.org/r/20260417143353.838911-1-puranjay@kernel.org -Signed-off-by: Alexei Starovoitov -Signed-off-by: Sasha Levin ---- - arch/arm/net/bpf_jit_32.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c -index a903b26cde409..4fd6dd29e3286 100644 ---- a/arch/arm/net/bpf_jit_32.c -+++ b/arch/arm/net/bpf_jit_32.c -@@ -1609,6 +1609,9 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) - { - u64 val = (u32)imm | (u64)insn[1].imm << 32; - -+ if (insn->src_reg == BPF_PSEUDO_FUNC) -+ goto notyet; -+ - emit_a32_mov_i64(dst, val, ctx); - - return 1; -@@ -1800,6 +1803,9 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) - const s8 *r5 = bpf2a32[BPF_REG_5]; - const u32 func = (u32)__bpf_call_base + (u32)imm; - -+ if (insn->src_reg == BPF_PSEUDO_CALL) -+ goto notyet; -+ - emit_a32_mov_r64(true, r0, r1, ctx); - emit_a32_mov_r64(true, r1, r2, ctx); - emit_push_r64(r5, ctx); --- -2.53.0 - diff --git a/queue-5.15/bpf-fix-precedence-bug-in-convert_bpf_ld_abs-alignme.patch b/queue-5.15/bpf-fix-precedence-bug-in-convert_bpf_ld_abs-alignme.patch deleted file mode 100644 index 2dbb404892..0000000000 --- a/queue-5.15/bpf-fix-precedence-bug-in-convert_bpf_ld_abs-alignme.patch +++ /dev/null @@ -1,46 +0,0 @@ -From d425f706928ecfb9aff1b9453bac44f07e26ebb6 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 16 Apr 2026 14:27:19 +0200 -Subject: bpf: Fix precedence bug in convert_bpf_ld_abs alignment check - -From: Daniel Borkmann - -[ Upstream commit e5f635edd393aeaa7cad9e42831d397e6e2e1eed ] - -Fix an operator precedence issue in convert_bpf_ld_abs() where the -expression offset + ip_align % size evaluates as offset + (ip_align % size) -due to % having higher precedence than +. That latter evaluation does -not make any sense. The intended check is (offset + ip_align) % size == 0 -to verify that the packet load offset is properly aligned for direct -access. - -With NET_IP_ALIGN == 2, the bug causes the inline fast-path for direct -packet loads to almost never be taken on !CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS -platforms. This forces nearly all cBPF BPF_LD_ABS packet loads through -the bpf_skb_load_helper slow path on the affected archs. - -Fixes: e0cea7ce988c ("bpf: implement ld_abs/ld_ind in native bpf") -Signed-off-by: Daniel Borkmann -Link: https://lore.kernel.org/r/20260416122719.661033-1-daniel@iogearbox.net -Signed-off-by: Alexei Starovoitov -Signed-off-by: Sasha Levin ---- - net/core/filter.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/net/core/filter.c b/net/core/filter.c -index 87447a7843b5a..3cab7f83fa661 100644 ---- a/net/core/filter.c -+++ b/net/core/filter.c -@@ -490,7 +490,7 @@ static bool convert_bpf_ld_abs(struct sock_filter *fp, struct bpf_insn **insnp) - ((unaligned_ok && offset >= 0) || - (!unaligned_ok && offset >= 0 && - offset + ip_align >= 0 && -- offset + ip_align % size == 0))) { -+ (offset + ip_align) % size == 0))) { - bool ldx_off_ok = offset <= S16_MAX; - - *insn++ = BPF_MOV64_REG(BPF_REG_TMP, BPF_REG_H); --- -2.53.0 - diff --git a/queue-5.15/bpf-sockmap-fix-af_unix-iter-deadlock.patch b/queue-5.15/bpf-sockmap-fix-af_unix-iter-deadlock.patch deleted file mode 100644 index d619ee41a2..0000000000 --- a/queue-5.15/bpf-sockmap-fix-af_unix-iter-deadlock.patch +++ /dev/null @@ -1,101 +0,0 @@ -From db102ee067218fe45cfd2c1f5c23c663cccc73d9 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 14 Apr 2026 16:13:16 +0200 -Subject: bpf, sockmap: Fix af_unix iter deadlock - -From: Michal Luczaj - -[ Upstream commit 4d328dd695383224aa750ddee6b4ad40c0f8d205 ] - -bpf_iter_unix_seq_show() may deadlock when lock_sock_fast() takes the fast -path and the iter prog attempts to update a sockmap. Which ends up spinning -at sock_map_update_elem()'s bh_lock_sock(): - -WARNING: possible recursive locking detected -test_progs/1393 is trying to acquire lock: -ffff88811ec25f58 (slock-AF_UNIX){+...}-{3:3}, at: sock_map_update_elem+0xdb/0x1f0 - -but task is already holding lock: -ffff88811ec25f58 (slock-AF_UNIX){+...}-{3:3}, at: __lock_sock_fast+0x37/0xe0 - -other info that might help us debug this: - Possible unsafe locking scenario: - - CPU0 - ---- - lock(slock-AF_UNIX); - lock(slock-AF_UNIX); - - *** DEADLOCK *** - - May be due to missing lock nesting notation - -4 locks held by test_progs/1393: - #0: ffff88814b59c790 (&p->lock){+.+.}-{4:4}, at: bpf_seq_read+0x59/0x10d0 - #1: ffff88811ec25fd8 (sk_lock-AF_UNIX){+.+.}-{0:0}, at: bpf_seq_read+0x42c/0x10d0 - #2: ffff88811ec25f58 (slock-AF_UNIX){+...}-{3:3}, at: __lock_sock_fast+0x37/0xe0 - #3: ffffffff85a6a7c0 (rcu_read_lock){....}-{1:3}, at: bpf_iter_run_prog+0x51d/0xb00 - -Call Trace: - dump_stack_lvl+0x5d/0x80 - print_deadlock_bug.cold+0xc0/0xce - __lock_acquire+0x130f/0x2590 - lock_acquire+0x14e/0x2b0 - _raw_spin_lock+0x30/0x40 - sock_map_update_elem+0xdb/0x1f0 - bpf_prog_2d0075e5d9b721cd_dump_unix+0x55/0x4f4 - bpf_iter_run_prog+0x5b9/0xb00 - bpf_iter_unix_seq_show+0x1f7/0x2e0 - bpf_seq_read+0x42c/0x10d0 - vfs_read+0x171/0xb20 - ksys_read+0xff/0x200 - do_syscall_64+0x6b/0x3a0 - entry_SYSCALL_64_after_hwframe+0x76/0x7e - -Fixes: 2c860a43dd77 ("bpf: af_unix: Implement BPF iterator for UNIX domain socket.") -Suggested-by: Kuniyuki Iwashima -Suggested-by: Martin KaFai Lau -Signed-off-by: Michal Luczaj -Signed-off-by: Martin KaFai Lau -Reviewed-by: Jiayuan Chen -Reviewed-by: Kuniyuki Iwashima -Link: https://patch.msgid.link/20260414-unix-proto-update-null-ptr-deref-v4-2-2af6fe97918e@rbox.co -Signed-off-by: Sasha Levin ---- - net/unix/af_unix.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c -index 12a4c1542459c..8584dc9592e05 100644 ---- a/net/unix/af_unix.c -+++ b/net/unix/af_unix.c -@@ -3452,15 +3452,14 @@ static int bpf_iter_unix_seq_show(struct seq_file *seq, void *v) - struct bpf_prog *prog; - struct sock *sk = v; - uid_t uid; -- bool slow; - int ret; - - if (v == SEQ_START_TOKEN) - return 0; - -- slow = lock_sock_fast(sk); -+ lock_sock(sk); - -- if (unlikely(sk_unhashed(sk))) { -+ if (unlikely(sock_flag(sk, SOCK_DEAD))) { - ret = SEQ_SKIP; - goto unlock; - } -@@ -3470,7 +3469,7 @@ static int bpf_iter_unix_seq_show(struct seq_file *seq, void *v) - prog = bpf_iter_get_info(&meta, false); - ret = unix_prog_seq_show(prog, &meta, v, uid); - unlock: -- unlock_sock_fast(sk, slow); -+ release_sock(sk); - return ret; - } - --- -2.53.0 - diff --git a/queue-5.15/bpf-sockmap-take-state-lock-for-af_unix-iter.patch b/queue-5.15/bpf-sockmap-take-state-lock-for-af_unix-iter.patch deleted file mode 100644 index 4544875984..0000000000 --- a/queue-5.15/bpf-sockmap-take-state-lock-for-af_unix-iter.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 87cdacf5177c6bde01797eaa0e08497b45904076 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 14 Apr 2026 16:13:19 +0200 -Subject: bpf, sockmap: Take state lock for af_unix iter - -From: Michal Luczaj - -[ Upstream commit 64c2f93fc3254d3bf5de4445fb732ee5c451edb6 ] - -When a BPF iterator program updates a sockmap, there is a race condition in -unix_stream_bpf_update_proto() where the `peer` pointer can become stale[1] -during a state transition TCP_ESTABLISHED -> TCP_CLOSE. - - CPU0 bpf CPU1 close - -------- ---------- -// unix_stream_bpf_update_proto() -sk_pair = unix_peer(sk) -if (unlikely(!sk_pair)) - return -EINVAL; - // unix_release_sock() - skpair = unix_peer(sk); - unix_peer(sk) = NULL; - sock_put(skpair) -sock_hold(sk_pair) // UaF - -More practically, this fix guarantees that the iterator program is -consistently provided with a unix socket that remains stable during -iterator execution. - -[1]: -BUG: KASAN: slab-use-after-free in unix_stream_bpf_update_proto+0x155/0x490 -Write of size 4 at addr ffff8881178c9a00 by task test_progs/2231 -Call Trace: - dump_stack_lvl+0x5d/0x80 - print_report+0x170/0x4f3 - kasan_report+0xe4/0x1c0 - kasan_check_range+0x125/0x200 - unix_stream_bpf_update_proto+0x155/0x490 - sock_map_link+0x71c/0xec0 - sock_map_update_common+0xbc/0x600 - sock_map_update_elem+0x19a/0x1f0 - bpf_prog_bbbf56096cdd4f01_selective_dump_unix+0x20c/0x217 - bpf_iter_run_prog+0x21e/0xae0 - bpf_iter_unix_seq_show+0x1e0/0x2a0 - bpf_seq_read+0x42c/0x10d0 - vfs_read+0x171/0xb20 - ksys_read+0xff/0x200 - do_syscall_64+0xf7/0x5e0 - entry_SYSCALL_64_after_hwframe+0x76/0x7e - -Allocated by task 2236: - kasan_save_stack+0x30/0x50 - kasan_save_track+0x14/0x30 - __kasan_slab_alloc+0x63/0x80 - kmem_cache_alloc_noprof+0x1d5/0x680 - sk_prot_alloc+0x59/0x210 - sk_alloc+0x34/0x470 - unix_create1+0x86/0x8a0 - unix_stream_connect+0x318/0x15b0 - __sys_connect+0xfd/0x130 - __x64_sys_connect+0x72/0xd0 - do_syscall_64+0xf7/0x5e0 - entry_SYSCALL_64_after_hwframe+0x76/0x7e - -Freed by task 2236: - kasan_save_stack+0x30/0x50 - kasan_save_track+0x14/0x30 - kasan_save_free_info+0x3b/0x70 - __kasan_slab_free+0x47/0x70 - kmem_cache_free+0x11c/0x590 - __sk_destruct+0x432/0x6e0 - unix_release_sock+0x9b3/0xf60 - unix_release+0x8a/0xf0 - __sock_release+0xb0/0x270 - sock_close+0x18/0x20 - __fput+0x36e/0xac0 - fput_close_sync+0xe5/0x1a0 - __x64_sys_close+0x7d/0xd0 - do_syscall_64+0xf7/0x5e0 - entry_SYSCALL_64_after_hwframe+0x76/0x7e - -Fixes: 2c860a43dd77 ("bpf: af_unix: Implement BPF iterator for UNIX domain socket.") -Suggested-by: Kuniyuki Iwashima -Signed-off-by: Michal Luczaj -Signed-off-by: Martin KaFai Lau -Reviewed-by: Kuniyuki Iwashima -Link: https://patch.msgid.link/20260414-unix-proto-update-null-ptr-deref-v4-5-2af6fe97918e@rbox.co -Signed-off-by: Sasha Levin ---- - net/unix/af_unix.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c -index 8584dc9592e05..a2a19c31ebddd 100644 ---- a/net/unix/af_unix.c -+++ b/net/unix/af_unix.c -@@ -3458,6 +3458,7 @@ static int bpf_iter_unix_seq_show(struct seq_file *seq, void *v) - return 0; - - lock_sock(sk); -+ unix_state_lock(sk); - - if (unlikely(sock_flag(sk, SOCK_DEAD))) { - ret = SEQ_SKIP; -@@ -3469,6 +3470,7 @@ static int bpf_iter_unix_seq_show(struct seq_file *seq, void *v) - prog = bpf_iter_get_info(&meta, false); - ret = unix_prog_seq_show(prog, &meta, v, uid); - unlock: -+ unix_state_unlock(sk); - release_sock(sk); - return ret; - } --- -2.53.0 - diff --git a/queue-5.15/series b/queue-5.15/series index 2709603c17..69b3fb6267 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -516,12 +516,6 @@ mtd-parsers-ofpart-call-of_node_put-only-in-ofpart_f.patch mtd-parsers-ofpart-call-of_node_get-for-dedicated-su.patch mtd-rawnand-sunxi-fix-sunxi_nfc_hw_ecc_read_extra_oo.patch hid-usbhid-fix-deadlock-in-hid_post_reset.patch -bpf-af_unix-use-batching-algorithm-in-bpf-unix-iter.patch -bpf-sockmap-fix-af_unix-iter-deadlock.patch -bpf-sockmap-take-state-lock-for-af_unix-iter.patch -bpf-fix-precedence-bug-in-convert_bpf_ld_abs-alignme.patch -bpf-allow-utf-8-literals-in-bpf_bprintf_prepare.patch -bpf-arm32-reject-bpf-to-bpf-calls-and-callbacks-in-t.patch pinctrl-pinctrl-pic32-fix-resource-leak.patch perf-branch-avoid-incrementing-null.patch perf-tools-cs-etm-fix-print-issue-for-coresight-debu.patch -- 2.47.3