All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Borkmann <daniel@iogearbox.net>
To: memxor@gmail.com
Cc: brauner@kernel.org, kpsingh@kernel.org, ast@kernel.org,
	john.fastabend@gmail.com, a.s.protopopov@gmail.com,
	bpf@vger.kernel.org
Subject: [PATCH bpf-next 02/11] bpf: Refuse caller-supplied keyrings when the bpf one is active
Date: Fri, 21 Aug 2026 23:41:02 +0200	[thread overview]
Message-ID: <20260821214111.1120748-3-daniel@iogearbox.net> (raw)
In-Reply-To: <20260821214111.1120748-1-daniel@iogearbox.net>

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>
---
 .../admin-guide/kernel-parameters.txt         |  7 +++++
 include/linux/bpf.h                           |  6 ++++
 kernel/bpf/keys.c                             |  5 ++++
 kernel/bpf/verifier.c                         | 29 ++++++++++++-------
 4 files changed, 36 insertions(+), 11 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 2beb61092bb3..543f245cc255 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -673,6 +673,13 @@ 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 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. 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)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 240e527c864b..f6ef16c938cb 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -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)
 {
 }
diff --git a/kernel/bpf/keys.c b/kernel/bpf/keys.c
index dc4d3a33158a..60cb85295c89 100644
--- a/kernel/bpf/keys.c
+++ b/kernel/bpf/keys.c
@@ -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;
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 3be8d51d35ac..a93a8dc427d8 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -21018,21 +21018,28 @@ 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 (attr->keyring_id == VERIFY_USE_BPF_KEYRING) {
-		key = bpf_lookup_keyring();
-		if (!key) {
-			verbose(env, "the bpf keyring is empty or has not been restricted\n");
-			return -ENOKEY;
-		}
-	} else if (system_keyring_id_check(attr->keyring_id) == 0) {
+	if (!system_keyring_id_check(attr->keyring_id)) {
 		key = bpf_lookup_system_key(attr->keyring_id);
 	} else {
-		key = bpf_lookup_user_key(attr->keyring_id, 0);
+		if (attr->keyring_id != VERIFY_USE_BPF_KEYRING) {
+			if (bpf_keyring_enforced()) {
+				verbose(env, "caller-supplied keyring refused, use bpf keyring\n");
+				return -EPERM;
+			}
+			key = bpf_lookup_user_key(attr->keyring_id, 0);
+		} else {
+			key = bpf_lookup_keyring();
+		}
 	}
 	if (!key) {
-		verbose(env, "cannot resolve signing keyring with keyring_id %d\n",
-			attr->keyring_id);
-		return -EINVAL;
+		if (attr->keyring_id == VERIFY_USE_BPF_KEYRING) {
+			verbose(env, "the bpf keyring is empty or has not been restricted\n");
+			return -ENOKEY;
+		} else {
+			verbose(env, "cannot resolve signing keyring with keyring_id %d\n",
+				attr->keyring_id);
+			return -EINVAL;
+		}
 	}
 
 	sig = kvmemdup_bpfptr(usig, attr->signature_size);
-- 
2.43.0


  parent reply	other threads:[~2026-08-21 21:41 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-21 21:41 [PATCH bpf-next 00/11] BPF keyring and signed loader ML-DSA support Daniel Borkmann
2026-08-21 21:41 ` [PATCH bpf-next 01/11] bpf: Add a bpf keyring for program signature validation Daniel Borkmann
2026-08-21 21:56   ` sashiko-bot
2026-08-21 22:18     ` Daniel Borkmann
2026-08-21 22:50   ` bot+bpf-ci
2026-08-21 21:41 ` Daniel Borkmann [this message]
2026-08-21 22:39   ` [PATCH bpf-next 02/11] bpf: Refuse caller-supplied keyrings when the bpf one is active bot+bpf-ci
2026-08-21 21:41 ` [PATCH bpf-next 03/11] bpf: Raise the bound on a program's signature size Daniel Borkmann
2026-08-21 22:39   ` bot+bpf-ci
2026-08-21 21:41 ` [PATCH bpf-next 04/11] bpftool: Support ML-DSA program signing Daniel Borkmann
2026-08-21 22:39   ` bot+bpf-ci
2026-08-21 21:41 ` [PATCH bpf-next 05/11] selftests/bpf: Add a test for the sealed bpf keyring Daniel Borkmann
2026-08-21 21:53   ` sashiko-bot
2026-08-21 22:50   ` bot+bpf-ci
2026-08-21 21:41 ` [PATCH bpf-next 06/11] selftests/bpf: Rebuild signed lskels when signing key changes Daniel Borkmann
2026-08-21 21:41 ` [PATCH bpf-next 07/11] selftests/bpf: Rename the verify_sig_setup.sh setup into setup-rsa Daniel Borkmann
2026-08-21 21:41 ` [PATCH bpf-next 08/11] selftests/bpf: Add an end-to-end ML-DSA signed loader test Daniel Borkmann
2026-08-21 21:50   ` sashiko-bot
2026-08-21 22:39   ` bot+bpf-ci
2026-08-21 21:41 ` [PATCH bpf-next 09/11] selftests/bpf: Allow appending to guest kernel cmdline in vmtest.sh Daniel Borkmann
2026-08-21 21:41 ` [PATCH bpf-next 10/11] selftests/bpf: Add tests for bpf keyring in signed loader Daniel Borkmann
2026-08-21 21:53   ` sashiko-bot
2026-08-21 22:50   ` bot+bpf-ci
2026-08-21 21:41 ` [PATCH bpf-next 11/11] Documentation/bpf: Document the bpf keyring and improve examples Daniel Borkmann
2026-08-21 22:50   ` bot+bpf-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=20260821214111.1120748-3-daniel@iogearbox.net \
    --to=daniel@iogearbox.net \
    --cc=a.s.protopopov@gmail.com \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=brauner@kernel.org \
    --cc=john.fastabend@gmail.com \
    --cc=kpsingh@kernel.org \
    --cc=memxor@gmail.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.