Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

bpf: Implement exclusive map creation

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>
Link: https://lore.kernel.org/r/20250914215141.15144-3-kpsingh@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

KP Singh and committed by
Alexei Starovoitov
baefdbdf 603b4416

+46 -4
+1
include/linux/bpf.h
··· 329 329 atomic64_t sleepable_refcnt; 330 330 s64 __percpu *elem_count; 331 331 u64 cookie; /* write-once */ 332 + char *excl_prog_sha; 332 333 }; 333 334 334 335 static inline const char *btf_field_type_name(enum btf_field_type type)
+6
include/uapi/linux/bpf.h
··· 1522 1522 * If provided, map_flags should have BPF_F_TOKEN_FD flag set. 1523 1523 */ 1524 1524 __s32 map_token_fd; 1525 + 1526 + /* Hash of the program that has exclusive access to the map. 1527 + */ 1528 + __aligned_u64 excl_prog_hash; 1529 + /* Size of the passed excl_prog_hash. */ 1530 + __u32 excl_prog_hash_size; 1525 1531 }; 1526 1532 1527 1533 struct { /* anonymous struct used by BPF_MAP_*_ELEM and BPF_MAP_FREEZE commands */
+27 -4
kernel/bpf/syscall.c
··· 860 860 * the free of values or special fields allocated from bpf memory 861 861 * allocator. 862 862 */ 863 + kfree(map->excl_prog_sha); 863 864 migrate_disable(); 864 865 map->ops->map_free(map); 865 866 migrate_enable(); ··· 1339 1338 return capable(CAP_NET_ADMIN) || capable(CAP_SYS_ADMIN); 1340 1339 } 1341 1340 1342 - #define BPF_MAP_CREATE_LAST_FIELD map_token_fd 1341 + #define BPF_MAP_CREATE_LAST_FIELD excl_prog_hash_size 1343 1342 /* called via syscall */ 1344 - static int map_create(union bpf_attr *attr, bool kernel) 1343 + static int map_create(union bpf_attr *attr, bpfptr_t uattr) 1345 1344 { 1346 1345 const struct bpf_map_ops *ops; 1347 1346 struct bpf_token *token = NULL; ··· 1535 1534 attr->btf_vmlinux_value_type_id; 1536 1535 } 1537 1536 1538 - err = security_bpf_map_create(map, attr, token, kernel); 1537 + if (attr->excl_prog_hash) { 1538 + bpfptr_t uprog_hash = make_bpfptr(attr->excl_prog_hash, uattr.is_kernel); 1539 + 1540 + if (attr->excl_prog_hash_size != SHA256_DIGEST_SIZE) { 1541 + err = -EINVAL; 1542 + goto free_map; 1543 + } 1544 + 1545 + map->excl_prog_sha = kzalloc(SHA256_DIGEST_SIZE, GFP_KERNEL); 1546 + if (!map->excl_prog_sha) { 1547 + err = -ENOMEM; 1548 + goto free_map; 1549 + } 1550 + 1551 + if (copy_from_bpfptr(map->excl_prog_sha, uprog_hash, SHA256_DIGEST_SIZE)) { 1552 + err = -EFAULT; 1553 + goto free_map; 1554 + } 1555 + } else if (attr->excl_prog_hash_size) { 1556 + return -EINVAL; 1557 + } 1558 + 1559 + err = security_bpf_map_create(map, attr, token, uattr.is_kernel); 1539 1560 if (err) 1540 1561 goto free_map_sec; 1541 1562 ··· 6031 6008 6032 6009 switch (cmd) { 6033 6010 case BPF_MAP_CREATE: 6034 - err = map_create(&attr, uattr.is_kernel); 6011 + err = map_create(&attr, uattr); 6035 6012 break; 6036 6013 case BPF_MAP_LOOKUP_ELEM: 6037 6014 err = map_lookup_elem(&attr);
+6
kernel/bpf/verifier.c
··· 20407 20407 { 20408 20408 enum bpf_prog_type prog_type = resolve_prog_type(prog); 20409 20409 20410 + if (map->excl_prog_sha && 20411 + memcmp(map->excl_prog_sha, prog->digest, SHA256_DIGEST_SIZE)) { 20412 + verbose(env, "program's hash doesn't match map's excl_prog_hash\n"); 20413 + return -EACCES; 20414 + } 20415 + 20410 20416 if (btf_record_has_field(map->record, BPF_LIST_HEAD) || 20411 20417 btf_record_has_field(map->record, BPF_RB_ROOT)) { 20412 20418 if (is_tracing_prog_type(prog_type)) {
+6
tools/include/uapi/linux/bpf.h
··· 1522 1522 * If provided, map_flags should have BPF_F_TOKEN_FD flag set. 1523 1523 */ 1524 1524 __s32 map_token_fd; 1525 + 1526 + /* Hash of the program that has exclusive access to the map. 1527 + */ 1528 + __aligned_u64 excl_prog_hash; 1529 + /* Size of the passed excl_prog_hash. */ 1530 + __u32 excl_prog_hash_size; 1525 1531 }; 1526 1532 1527 1533 struct { /* anonymous struct used by BPF_MAP_*_ELEM and BPF_MAP_FREEZE commands */