From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
To: bpf@vger.kernel.org
Cc: 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>,
Nicholas Carlini <npc@anthropic.com>,
kkd@meta.com, kernel-team@meta.com
Subject: [PATCH bpf-next v5 09/10] selftests/bpf: Check callback map value lock identity
Date: Wed, 16 Sep 2026 23:20:56 +0200 [thread overview]
Message-ID: <20260916212102.597335-10-memxor@gmail.com> (raw)
In-Reply-To: <20260916212102.597335-1-memxor@gmail.com>
Add a verifier test which retains a map value from an outer callback and
then acquires a lock through an inner callback value before attempting to
release the outer callback value. Both values can denote different elements,
so the verifier must reject the mismatched unlock.
Also exercise callbacks reached through two inner-map lookups. The lookup
results share inner_map_meta but may refer to different one-element arrays,
so their callback values must retain distinct lock identities.
Extend the existing spin_lock failure table and reuse its array and
inner-map fixtures to keep these cases alongside the other lock identity
tests. Update the nested callback reference-leak expectation for the extra
callback value ID.
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
---
.../selftests/bpf/prog_tests/cb_refs.c | 2 +-
.../selftests/bpf/prog_tests/spin_lock.c | 2 +
.../selftests/bpf/progs/test_spin_lock_fail.c | 67 ++++++++++++++++++-
3 files changed, 68 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/cb_refs.c b/tools/testing/selftests/bpf/prog_tests/cb_refs.c
index 78566b817fd7..490e15e7126d 100644
--- a/tools/testing/selftests/bpf/prog_tests/cb_refs.c
+++ b/tools/testing/selftests/bpf/prog_tests/cb_refs.c
@@ -13,7 +13,7 @@ struct {
} cb_refs_tests[] = {
{ "underflow_prog", "release kfunc bpf_kfunc_call_test_release expects referenced PTR_TO_BTF_ID passed to R1" },
{ "leak_prog", "Possibly NULL pointer passed to helper R2" },
- { "nested_cb", "Unreleased reference id=4 alloc_insn=2" }, /* alloc_insn=2{4,5} */
+ { "nested_cb", "Unreleased reference id=5 alloc_insn=2" }, /* alloc_insn=2{4,5} */
{ "non_cb_transfer_ref", "Unreleased reference id=4 alloc_insn=1" }, /* alloc_insn=1{1,2} */
};
diff --git a/tools/testing/selftests/bpf/prog_tests/spin_lock.c b/tools/testing/selftests/bpf/prog_tests/spin_lock.c
index 5c3579438427..e368370262c8 100644
--- a/tools/testing/selftests/bpf/prog_tests/spin_lock.c
+++ b/tools/testing/selftests/bpf/prog_tests/spin_lock.c
@@ -54,6 +54,8 @@ static struct {
{ "lock_global_sleepable_helper_subprog", "global function calls are not allowed while holding a lock" },
{ "lock_global_sleepable_kfunc_subprog", "global function calls are not allowed while holding a lock" },
{ "lock_global_sleepable_subprog_indirect", "global function calls are not allowed while holding a lock" },
+ { "callback_value_lock_identity", "bpf_spin_unlock of different lock" },
+ { "callback_inner_map_value_lock_identity", "bpf_spin_unlock of different lock" },
};
static int match_regex(const char *pattern, const char *string)
diff --git a/tools/testing/selftests/bpf/progs/test_spin_lock_fail.c b/tools/testing/selftests/bpf/progs/test_spin_lock_fail.c
index f678ee6bd7ea..55282f20fa32 100644
--- a/tools/testing/selftests/bpf/progs/test_spin_lock_fail.c
+++ b/tools/testing/selftests/bpf/progs/test_spin_lock_fail.c
@@ -14,17 +14,18 @@ struct array_map {
__type(key, int);
__type(value, struct foo);
__uint(max_entries, 1);
-} array_map SEC(".maps");
+} array_map SEC(".maps"), array_map_b SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
- __uint(max_entries, 1);
+ __uint(max_entries, 2);
__type(key, int);
__type(value, int);
__array(values, struct array_map);
} map_of_maps SEC(".maps") = {
.values = {
[0] = &array_map,
+ [1] = &array_map_b,
},
};
@@ -314,4 +315,66 @@ int lock_global_sleepable_subprog_indirect(struct __sk_buff *ctx)
return ret;
}
+struct {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 2);
+ __type(key, int);
+ __type(value, struct foo);
+} callback_array_map SEC(".maps");
+
+struct callback_ctx {
+ struct foo *value;
+};
+
+static long lock_different_value(struct bpf_map *map, int *key,
+ struct foo *value, struct callback_ctx *ctx)
+{
+ bpf_spin_lock(&value->lock);
+ bpf_spin_unlock(&ctx->value->lock);
+ return 0;
+}
+
+static long nest_lock_different_value(struct bpf_map *map, int *key,
+ struct foo *value, void *data)
+{
+ struct callback_ctx ctx = { .value = value };
+
+ bpf_for_each_map_elem(&callback_array_map, lock_different_value, &ctx, 0);
+ return 0;
+}
+
+SEC("?tc")
+int callback_value_lock_identity(void *ctx)
+{
+ bpf_for_each_map_elem(&callback_array_map, nest_lock_different_value, NULL, 0);
+ return 0;
+}
+
+static long nest_lock_different_inner_value(struct bpf_map *map, int *key,
+ struct foo *value, void *data)
+{
+ struct callback_ctx ctx = { .value = value };
+ int inner_key = 1;
+ void *inner_map;
+
+ inner_map = bpf_map_lookup_elem(&map_of_maps, &inner_key);
+ if (!inner_map)
+ return 0;
+ bpf_for_each_map_elem(inner_map, lock_different_value, &ctx, 0);
+ return 0;
+}
+
+SEC("?tc")
+int callback_inner_map_value_lock_identity(void *ctx)
+{
+ int inner_key = 0;
+ void *inner_map;
+
+ inner_map = bpf_map_lookup_elem(&map_of_maps, &inner_key);
+ if (!inner_map)
+ return 0;
+ bpf_for_each_map_elem(inner_map, nest_lock_different_inner_value, NULL, 0);
+ return 0;
+}
+
char _license[] SEC("license") = "GPL";
--
2.53.0
next prev parent reply other threads:[~2026-09-16 21:21 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-16 21:20 [PATCH bpf-next v5 00/10] Misc bug fixes - part 5 Kumar Kartikeya Dwivedi
2026-09-16 21:20 ` [PATCH bpf-next v5 01/10] bpf: Make post-verification instruction rewrites killable Kumar Kartikeya Dwivedi
2026-09-16 21:20 ` [PATCH bpf-next v5 02/10] bpf: Preserve packet pointer class displacement in regsafe() Kumar Kartikeya Dwivedi
2026-09-16 21:20 ` [PATCH bpf-next v5 03/10] selftests/bpf: Test packet pointer class displacement pruning Kumar Kartikeya Dwivedi
2026-09-16 21:20 ` [PATCH bpf-next v5 04/10] bpf: Apply CO-RE relocations before subprogram validation Kumar Kartikeya Dwivedi
2026-09-16 21:20 ` [PATCH bpf-next v5 05/10] selftests/bpf: Test early in-kernel CO-RE relocation Kumar Kartikeya Dwivedi
2026-09-16 21:20 ` [PATCH bpf-next v5 06/10] bpf: Restrict CO-RE poisoning to relocatable instructions Kumar Kartikeya Dwivedi
2026-09-16 21:20 ` [PATCH bpf-next v5 07/10] selftests/bpf: Test CO-RE instruction poisoning restrictions Kumar Kartikeya Dwivedi
2026-09-16 21:20 ` [PATCH bpf-next v5 08/10] bpf: Assign lock identity to callback map values Kumar Kartikeya Dwivedi
2026-09-16 21:20 ` Kumar Kartikeya Dwivedi [this message]
2026-09-17 0:50 ` [PATCH bpf-next v5 09/10] selftests/bpf: Check callback map value lock identity Alexei Starovoitov
2026-09-17 1:06 ` Kumar Kartikeya Dwivedi
2026-09-17 1:08 ` Alexei Starovoitov
2026-09-16 21:20 ` [PATCH bpf-next v5 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=20260916212102.597335-10-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