1264d8fd2SDaniel Borkmann // SPDX-License-Identifier: GPL-2.0-only 2264d8fd2SDaniel Borkmann /* Copyright (c) 2026 Isovalent */ 3264d8fd2SDaniel Borkmann 4264d8fd2SDaniel Borkmann #include <linux/bpf.h> 5264d8fd2SDaniel Borkmann #include <linux/cred.h> 6264d8fd2SDaniel Borkmann #include <linux/err.h> 7264d8fd2SDaniel Borkmann #include <linux/init.h> 8264d8fd2SDaniel Borkmann #include <linux/key.h> 9264d8fd2SDaniel Borkmann #include <linux/moduleparam.h> 10264d8fd2SDaniel Borkmann #include <linux/slab.h> 11264d8fd2SDaniel Borkmann 12264d8fd2SDaniel Borkmann #undef MODULE_PARAM_PREFIX 13264d8fd2SDaniel Borkmann #define MODULE_PARAM_PREFIX "bpf." 14264d8fd2SDaniel Borkmann 15264d8fd2SDaniel Borkmann static struct key *bpf_keyring; 16264d8fd2SDaniel Borkmann 17264d8fd2SDaniel Borkmann static bool bpf_keyring_unsealed __ro_after_init; 18264d8fd2SDaniel Borkmann module_param_named(keyring_unsealed, bpf_keyring_unsealed, bool, 0444); 19264d8fd2SDaniel Borkmann MODULE_PARM_DESC(keyring_unsealed, "Leave the bpf keyring unsealed"); 20264d8fd2SDaniel Borkmann 21*abaa0835SDaniel Borkmann bool bpf_keyring_enforced(void) 22*abaa0835SDaniel Borkmann { 23*abaa0835SDaniel Borkmann return bpf_keyring_unsealed; 24*abaa0835SDaniel Borkmann } 25*abaa0835SDaniel Borkmann 26264d8fd2SDaniel Borkmann struct bpf_key *bpf_lookup_keyring(void) 27264d8fd2SDaniel Borkmann { 28264d8fd2SDaniel Borkmann struct bpf_key *bkey; 29264d8fd2SDaniel Borkmann 30264d8fd2SDaniel Borkmann if (!bpf_keyring) 31264d8fd2SDaniel Borkmann return NULL; 32264d8fd2SDaniel Borkmann if (!READ_ONCE(bpf_keyring->keys.nr_leaves_on_tree) || 33264d8fd2SDaniel Borkmann !READ_ONCE(bpf_keyring->restrict_link)) 34264d8fd2SDaniel Borkmann return NULL; 35264d8fd2SDaniel Borkmann 36264d8fd2SDaniel Borkmann bkey = kmalloc_obj(*bkey); 37264d8fd2SDaniel Borkmann if (!bkey) 38264d8fd2SDaniel Borkmann return NULL; 39264d8fd2SDaniel Borkmann 40264d8fd2SDaniel Borkmann bkey->key = bpf_keyring; 41264d8fd2SDaniel Borkmann bkey->has_ref = false; 42264d8fd2SDaniel Borkmann return bkey; 43264d8fd2SDaniel Borkmann } 44264d8fd2SDaniel Borkmann 45264d8fd2SDaniel Borkmann static int __init bpf_keyring_init(void) 46264d8fd2SDaniel Borkmann { 47264d8fd2SDaniel Borkmann struct key *keyring; 48264d8fd2SDaniel Borkmann 49264d8fd2SDaniel Borkmann keyring = keyring_alloc(".bpf", 50264d8fd2SDaniel Borkmann GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, 51264d8fd2SDaniel Borkmann current_cred(), KEY_POS_SEARCH | 52264d8fd2SDaniel Borkmann KEY_USR_VIEW | KEY_USR_READ | 53264d8fd2SDaniel Borkmann KEY_USR_WRITE | KEY_USR_SEARCH | 54264d8fd2SDaniel Borkmann KEY_USR_SETATTR, KEY_ALLOC_NOT_IN_QUOTA, 55264d8fd2SDaniel Borkmann NULL, NULL); 56264d8fd2SDaniel Borkmann if (IS_ERR(keyring)) { 57264d8fd2SDaniel Borkmann pr_err("bpf: cannot allocate bpf keyring: %ld\n", 58264d8fd2SDaniel Borkmann PTR_ERR(keyring)); 59264d8fd2SDaniel Borkmann return 0; 60264d8fd2SDaniel Borkmann } 61264d8fd2SDaniel Borkmann if (!bpf_keyring_unsealed && 62264d8fd2SDaniel Borkmann keyring_restrict(make_key_ref(keyring, true), NULL, NULL)) { 63264d8fd2SDaniel Borkmann pr_err("bpf: cannot seal bpf keyring\n"); 64264d8fd2SDaniel Borkmann key_revoke(keyring); 65264d8fd2SDaniel Borkmann key_put(keyring); 66264d8fd2SDaniel Borkmann return 0; 67264d8fd2SDaniel Borkmann } 68264d8fd2SDaniel Borkmann 69264d8fd2SDaniel Borkmann bpf_keyring = keyring; 70264d8fd2SDaniel Borkmann key_register_bpf_keyring(keyring); 71264d8fd2SDaniel Borkmann return 0; 72264d8fd2SDaniel Borkmann } 73264d8fd2SDaniel Borkmann late_initcall(bpf_keyring_init); 74