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 v2 02/13] bpf: Implement exclusive map creation
Date: Mon, 21 Jul 2025 23:19:47 +0200 [thread overview]
Message-ID: <20250721211958.1881379-3-kpsingh@kernel.org> (raw)
In-Reply-To: <20250721211958.1881379-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 06cb73df94b3..f1b259517bd6 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -311,6 +311,7 @@ struct bpf_map {
bool free_after_rcu_gp;
atomic64_t sleepable_refcnt;
s64 __percpu *elem_count;
+ 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 e63039817af3..6ebcb7e4afbb 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -858,6 +858,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();
@@ -1335,9 +1336,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;
@@ -1527,7 +1528,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);
+
+ map->excl_prog_sha = kzalloc(SHA256_DIGEST_SIZE, GFP_KERNEL);
+ if (!map->excl_prog_sha) {
+ err = -ENOMEM;
+ goto free_map;
+ }
+
+ if (attr->excl_prog_hash_size != SHA256_DIGEST_SIZE) {
+ err = -EINVAL;
+ 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;
@@ -6001,7 +6025,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 e2fcea860755..e062f9672da9 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -20321,6 +20321,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-07-21 21:20 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-21 21:19 [PATCH v2 00/13] Signed BPF programs KP Singh
2025-07-21 21:19 ` [PATCH v2 01/13] bpf: Update the bpf_prog_calc_tag to use SHA256 KP Singh
2025-07-21 21:19 ` KP Singh [this message]
2025-07-29 22:59 ` [PATCH v2 02/13] bpf: Implement exclusive map creation Fan Wu
2025-08-11 22:48 ` KP Singh
2025-07-21 21:19 ` [PATCH v2 03/13] libbpf: Implement SHA256 internal helper KP Singh
2025-07-21 21:19 ` [PATCH v2 04/13] libbpf: Support exclusive map creation KP Singh
2025-07-29 2:25 ` Alexei Starovoitov
2025-08-11 22:18 ` KP Singh
2025-07-21 21:19 ` [PATCH v2 05/13] selftests/bpf: Add tests for exclusive maps KP Singh
2025-07-21 21:19 ` [PATCH v2 06/13] bpf: Return hashes of maps in BPF_OBJ_GET_INFO_BY_FD KP Singh
2025-07-21 21:19 ` [PATCH v2 07/13] bpf: Move the signature kfuncs to helpers.c KP Singh
2025-07-23 16:47 ` James Bottomley
2025-07-21 21:19 ` [PATCH v2 08/13] bpf: Implement signature verification for BPF programs KP Singh
2025-07-23 17:11 ` James Bottomley
2025-07-24 17:22 ` KP Singh
2025-07-31 15:57 ` Dan Carpenter
2025-08-11 22:22 ` KP Singh
2025-08-05 18:28 ` Blaise Boscaccy
2025-08-13 2:20 ` Paul Moore
2025-07-21 21:19 ` [PATCH v2 09/13] libbpf: Update light skeleton for signing KP Singh
2025-07-21 21:19 ` [PATCH v2 10/13] libbpf: Embed and verify the metadata hash in the loader KP Singh
2025-07-21 21:19 ` [PATCH v2 11/13] bpftool: Add support for signing BPF programs KP Singh
2025-07-22 15:51 ` Quentin Monnet
2025-07-24 17:07 ` KP Singh
2025-08-11 14:23 ` KP Singh
2025-08-11 14:39 ` Quentin Monnet
2025-07-21 21:19 ` [PATCH v2 12/13] selftests/bpf: Enable signature verification for all lskel tests KP Singh
2025-07-29 2:27 ` Alexei Starovoitov
2025-08-11 22:20 ` KP Singh
2025-07-21 21:19 ` [PATCH v2 13/13] selftests/bpf: Add test for signed programs KP Singh
2025-07-29 2:30 ` Alexei Starovoitov
2025-08-11 14:24 ` KP Singh
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=20250721211958.1881379-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).