mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
bpf: Refuse caller-supplied keyrings when the bpf one is active
Nothing changes for systems that do not use the bpf keyring. Without bpf.keyring_unsealed=1 a caller-supplied keyring behaves exactly as before, which also lets it serve as the staging step for software installed onto a running system whose signing key is not enrolled anywhere yet. Passing bpf.keyring_unsealed=1 states that the bpf keyring is the trust anchor for this boot, so from the first program load onwards a caller- supplied keyring is refused with -EPERM. Deriving this from the boot flag rather than from the keyring's runtime state keeps the decision immutable from userspace. Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/r/20260828175227.1537793-3-daniel@iogearbox.net Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
264d8fd279
commit
abaa0835b4
|
|
@ -673,6 +673,14 @@ Kernel parameters
|
|||
keys. Once the keyring is restricted it becomes active
|
||||
and can be used for BPF program signature verification.
|
||||
|
||||
Setting this also means that the bpf keyring is the
|
||||
only non-system keyring a loader may select for the
|
||||
rest of the boot: caller-supplied user/session
|
||||
keyrings are refused with -EPERM, whether or not
|
||||
provisioning actually completed. The system keyrings
|
||||
stay selectable. Leaving it unset keeps the prior
|
||||
behaviour, where a caller-supplied keyring is allowed.
|
||||
|
||||
See Documentation/bpf/signing.rst
|
||||
|
||||
bttv.card= [HW,V4L] bttv (bt848 + bt878 based grabber cards)
|
||||
|
|
|
|||
|
|
@ -3821,6 +3821,7 @@ struct bpf_key {
|
|||
struct bpf_key *bpf_lookup_user_key(s32 serial, u64 flags);
|
||||
struct bpf_key *bpf_lookup_system_key(u64 id);
|
||||
struct bpf_key *bpf_lookup_keyring(void);
|
||||
bool bpf_keyring_enforced(void);
|
||||
void bpf_key_put(struct bpf_key *bkey);
|
||||
int bpf_verify_pkcs7_signature(const struct bpf_dynptr *data_p,
|
||||
const struct bpf_dynptr *sig_p,
|
||||
|
|
@ -3846,6 +3847,11 @@ static inline struct bpf_key *bpf_lookup_keyring(void)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static inline bool bpf_keyring_enforced(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void bpf_key_put(struct bpf_key *bkey)
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,11 @@ static bool bpf_keyring_unsealed __ro_after_init;
|
|||
module_param_named(keyring_unsealed, bpf_keyring_unsealed, bool, 0444);
|
||||
MODULE_PARM_DESC(keyring_unsealed, "Leave the bpf keyring unsealed");
|
||||
|
||||
bool bpf_keyring_enforced(void)
|
||||
{
|
||||
return bpf_keyring_unsealed;
|
||||
}
|
||||
|
||||
struct bpf_key *bpf_lookup_keyring(void)
|
||||
{
|
||||
struct bpf_key *bkey;
|
||||
|
|
|
|||
|
|
@ -21165,12 +21165,16 @@ static int bpf_prog_verify_signature(struct bpf_verifier_env *env,
|
|||
if (!attr->signature_size ||
|
||||
attr->signature_size > KMALLOC_MAX_CACHE_SIZE)
|
||||
return -EINVAL;
|
||||
if (system_keyring_id_check(attr->keyring_id) == 0)
|
||||
if (system_keyring_id_check(attr->keyring_id) == 0) {
|
||||
key = bpf_lookup_system_key(attr->keyring_id);
|
||||
else if (attr->keyring_id == KEY_SPEC_BPF_KEYRING)
|
||||
} else if (attr->keyring_id == KEY_SPEC_BPF_KEYRING) {
|
||||
key = bpf_lookup_keyring();
|
||||
else
|
||||
} else if (bpf_keyring_enforced()) {
|
||||
verbose(env, "caller-supplied keyring refused, use bpf keyring\n");
|
||||
return -EPERM;
|
||||
} else {
|
||||
key = bpf_lookup_user_key(attr->keyring_id, 0);
|
||||
}
|
||||
if (!key) {
|
||||
if (attr->keyring_id == KEY_SPEC_BPF_KEYRING) {
|
||||
verbose(env, "the bpf keyring is empty or has not been restricted\n");
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user