From: KP Singh <kpsingh@kernel.org>
To: bpf@vger.kernel.org, linux-security-module@vger.kernel.org
Cc: bboscaccy@linux.microsoft.com, paul@paul-moore.com,
kys@microsoft.com, ast@kernel.org, daniel@iogearbox.net,
andrii@kernel.org, KP Singh <kpsingh@kernel.org>
Subject: [PATCH v3 02/12] bpf: Implement exclusive map creation
Date: Wed, 13 Aug 2025 22:55:16 +0200 [thread overview]
Message-ID: <20250813205526.2992911-3-kpsingh@kernel.org> (raw)
In-Reply-To: <20250813205526.2992911-1-kpsingh@kernel.org>
Exclusive maps allow maps to only be accessed by program with a
program with a matching hash which is specified in the excl_prog_hash
attr.
For the signing use-case, this allows the trusted loader program
to load the map and verify the integrity
Signed-off-by: KP Singh <kpsingh@kernel.org>
---
include/linux/bpf.h | 1 +
include/uapi/linux/bpf.h | 2 ++
kernel/bpf/syscall.c | 32 ++++++++++++++++++++++++++++----
kernel/bpf/verifier.c | 6 ++++++
tools/include/uapi/linux/bpf.h | 2 ++
5 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index b98c5b5bf2a1..b23804733f2f 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -329,6 +329,7 @@ struct bpf_map {
atomic64_t sleepable_refcnt;
s64 __percpu *elem_count;
u64 cookie; /* write-once */
+ char *excl_prog_sha;
};
static inline const char *btf_field_type_name(enum btf_field_type type)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 233de8677382..7873ba7b9468 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -1522,6 +1522,8 @@ union bpf_attr {
* If provided, map_flags should have BPF_F_TOKEN_FD flag set.
*/
__s32 map_token_fd;
+ __u32 excl_prog_hash_size;
+ __aligned_u64 excl_prog_hash;
};
struct { /* anonymous struct used by BPF_MAP_*_ELEM and BPF_MAP_FREEZE commands */
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 0fbfa8532c39..943811165510 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -860,6 +860,7 @@ static void bpf_map_free(struct bpf_map *map)
* the free of values or special fields allocated from bpf memory
* allocator.
*/
+ kfree(map->excl_prog_sha);
migrate_disable();
map->ops->map_free(map);
migrate_enable();
@@ -1338,9 +1339,9 @@ static bool bpf_net_capable(void)
return capable(CAP_NET_ADMIN) || capable(CAP_SYS_ADMIN);
}
-#define BPF_MAP_CREATE_LAST_FIELD map_token_fd
+#define BPF_MAP_CREATE_LAST_FIELD excl_prog_hash
/* called via syscall */
-static int map_create(union bpf_attr *attr, bool kernel)
+static int map_create(union bpf_attr *attr, bpfptr_t uattr)
{
const struct bpf_map_ops *ops;
struct bpf_token *token = NULL;
@@ -1534,7 +1535,30 @@ static int map_create(union bpf_attr *attr, bool kernel)
attr->btf_vmlinux_value_type_id;
}
- err = security_bpf_map_create(map, attr, token, kernel);
+ if (attr->excl_prog_hash) {
+ bpfptr_t uprog_hash = make_bpfptr(attr->excl_prog_hash, uattr.is_kernel);
+
+ if (attr->excl_prog_hash_size != SHA256_DIGEST_SIZE) {
+ err = -EINVAL;
+ goto free_map;
+ }
+
+ map->excl_prog_sha = kzalloc(SHA256_DIGEST_SIZE, GFP_KERNEL);
+ if (!map->excl_prog_sha) {
+ err = -ENOMEM;
+ goto free_map;
+ }
+
+ if (copy_from_bpfptr(map->excl_prog_sha, uprog_hash,
+ SHA256_DIGEST_SIZE)) {
+ err = -EFAULT;
+ goto free_map;
+ }
+ } else if (attr->excl_prog_hash_size) {
+ return -EINVAL;
+ }
+
+ err = security_bpf_map_create(map, attr, token, uattr.is_kernel);
if (err)
goto free_map_sec;
@@ -6008,7 +6032,7 @@ static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr, unsigned int size)
switch (cmd) {
case BPF_MAP_CREATE:
- err = map_create(&attr, uattr.is_kernel);
+ err = map_create(&attr, uattr);
break;
case BPF_MAP_LOOKUP_ELEM:
err = map_lookup_elem(&attr);
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 3a3982fe20d4..2dd4449b946b 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -20360,6 +20360,12 @@ static int check_map_prog_compatibility(struct bpf_verifier_env *env,
{
enum bpf_prog_type prog_type = resolve_prog_type(prog);
+ if (map->excl_prog_sha &&
+ memcmp(map->excl_prog_sha, prog->digest, SHA256_DIGEST_SIZE)) {
+ verbose(env, "program's hash doesn't match map's excl_prog_hash\n");
+ return -EACCES;
+ }
+
if (btf_record_has_field(map->record, BPF_LIST_HEAD) ||
btf_record_has_field(map->record, BPF_RB_ROOT)) {
if (is_tracing_prog_type(prog_type)) {
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 233de8677382..7873ba7b9468 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -1522,6 +1522,8 @@ union bpf_attr {
* If provided, map_flags should have BPF_F_TOKEN_FD flag set.
*/
__s32 map_token_fd;
+ __u32 excl_prog_hash_size;
+ __aligned_u64 excl_prog_hash;
};
struct { /* anonymous struct used by BPF_MAP_*_ELEM and BPF_MAP_FREEZE commands */
--
2.43.0
next prev parent reply other threads:[~2025-08-13 20:55 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-13 20:55 [PATCH v3 00/12] Signed BPF programs KP Singh
2025-08-13 20:55 ` [PATCH v3 01/12] bpf: Update the bpf_prog_calc_tag to use SHA256 KP Singh
2025-08-13 20:55 ` KP Singh [this message]
2025-08-13 20:55 ` [PATCH v3 03/12] libbpf: Implement SHA256 internal helper KP Singh
2025-08-14 18:46 ` Andrii Nakryiko
2025-08-13 20:55 ` [PATCH v3 04/12] libbpf: Support exclusive map creation KP Singh
2025-08-14 18:46 ` Andrii Nakryiko
2025-08-13 20:55 ` [PATCH v3 05/12] selftests/bpf: Add tests for exclusive maps KP Singh
2025-08-13 20:55 ` [PATCH v3 06/12] bpf: Return hashes of maps in BPF_OBJ_GET_INFO_BY_FD KP Singh
2025-08-14 18:46 ` Andrii Nakryiko
2025-08-13 20:55 ` [PATCH v3 07/12] bpf: Move the signature kfuncs to helpers.c KP Singh
2025-08-13 20:55 ` [PATCH v3 08/12] bpf: Implement signature verification for BPF programs KP Singh
2025-08-13 21:02 ` Paul Moore
2025-08-13 21:37 ` KP Singh
2025-08-13 22:17 ` Paul Moore
2025-08-19 19:19 ` Paul Moore
2025-09-03 16:28 ` Paul Moore
2025-08-13 20:55 ` [PATCH v3 09/12] libbpf: Update light skeleton for signing KP Singh
2025-08-14 18:46 ` Andrii Nakryiko
2025-08-13 20:55 ` [PATCH v3 10/12] libbpf: Embed and verify the metadata hash in the loader KP Singh
2025-08-13 20:55 ` [PATCH v3 11/12] bpftool: Add support for signing BPF programs KP Singh
2025-08-14 16:50 ` Blaise Boscaccy
2025-08-17 2:16 ` KP Singh
2025-08-18 20:37 ` Blaise Boscaccy
2025-08-13 20:55 ` [PATCH v3 12/12] selftests/bpf: Enable signature verification for some lskel tests KP Singh
2025-08-15 8:26 ` [syzbot ci] Re: Signed BPF programs syzbot ci
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=20250813205526.2992911-3-kpsingh@kernel.org \
--to=kpsingh@kernel.org \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bboscaccy@linux.microsoft.com \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=kys@microsoft.com \
--cc=linux-security-module@vger.kernel.org \
--cc=paul@paul-moore.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;
as well as URLs for NNTP newsgroup(s).