All of lore.kernel.org
 help / color / mirror / Atom feed
From: Roberto Sassu <roberto.sassu@huawei.com>
To: <ast@kernel.org>, <daniel@iogearbox.net>, <andrii@kernel.org>,
	<martin.lau@linux.dev>, <song@kernel.org>, <yhs@fb.com>,
	<john.fastabend@gmail.com>, <kpsingh@kernel.org>,
	<sdf@google.com>, <haoluo@google.com>, <jolsa@kernel.org>,
	<corbet@lwn.net>, <dhowells@redhat.com>, <jarkko@kernel.org>,
	<rostedt@goodmis.org>, <mingo@redhat.com>, <paul@paul-moore.com>,
	<jmorris@namei.org>, <serge@hallyn.com>, <shuah@kernel.org>
Cc: <bpf@vger.kernel.org>, <linux-doc@vger.kernel.org>,
	<keyrings@vger.kernel.org>,
	<linux-security-module@vger.kernel.org>,
	<linux-kselftest@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	Roberto Sassu <roberto.sassu@huawei.com>
Subject: [PATCH v9 06/10] bpf: Add bpf_lookup_*_key() and bpf_key_put() kfuncs
Date: Tue, 9 Aug 2022 15:45:59 +0200	[thread overview]
Message-ID: <20220809134603.1769279-7-roberto.sassu@huawei.com> (raw)
In-Reply-To: <20220809134603.1769279-1-roberto.sassu@huawei.com>

Add the bpf_lookup_user_key(), bpf_lookup_system_key() and bpf_key_put()
kfuncs, to respectively search a key with a given serial and flags, obtain
a key from a pre-determined ID defined in include/linux/verification.h, and
cleanup.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 include/linux/bpf.h      |   6 ++
 kernel/trace/bpf_trace.c | 151 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 157 insertions(+)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 0d56c23cc504..564b9e0b8c16 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -2572,4 +2572,10 @@ static inline void bpf_cgroup_atype_get(u32 attach_btf_id, int cgroup_atype) {}
 static inline void bpf_cgroup_atype_put(int cgroup_atype) {}
 #endif /* CONFIG_BPF_LSM */
 
+#ifdef CONFIG_KEYS
+struct bpf_key {
+	struct key *key;
+	bool valid_ptr;
+};
+#endif /* CONFIG_KEYS */
 #endif /* _LINUX_BPF_H */
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 68e5cdd24cef..33ca4cfe6e26 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -20,6 +20,7 @@
 #include <linux/fprobe.h>
 #include <linux/bsearch.h>
 #include <linux/sort.h>
+#include <linux/key.h>
 
 #include <net/bpf_sk_storage.h>
 
@@ -1181,6 +1182,156 @@ static const struct bpf_func_proto bpf_get_func_arg_cnt_proto = {
 	.arg1_type	= ARG_PTR_TO_CTX,
 };
 
+#ifdef CONFIG_KEYS
+__diag_push();
+__diag_ignore_all("-Wmissing-prototypes",
+		  "kfuncs which will be used in BPF programs");
+
+/**
+ * bpf_lookup_user_key - lookup a key by its serial
+ * @serial: key serial
+ * @flags: lookup-specific flags
+ *
+ * Search a key with a given *serial* and the provided *flags*. The
+ * returned key, if found, has the reference count incremented by
+ * one, and is stored in a bpf_key structure, returned to the caller.
+ * The bpf_key structure must be passed to bpf_key_put() when done
+ * with it, so that the key reference count is decremented and the
+ * bpf_key structure is freed.
+ *
+ * Permission checks are deferred to the time the key is used by
+ * one of the available key-specific kfuncs.
+ *
+ * Set *flags* with 1, to attempt creating a requested special
+ * keyring (e.g. session keyring), if it doesn't yet exist. Set
+ * *flags* with 2 to lookup a key without waiting for the key
+ * construction, and to retrieve uninstantiated keys (keys without
+ * data attached to them).
+ *
+ * Return: a bpf_key pointer with a valid key pointer if the key is found, a
+ *         NULL pointer otherwise.
+ */
+noinline __weak struct bpf_key *bpf_lookup_user_key(u32 serial, u64 flags)
+{
+	key_ref_t key_ref;
+	struct bpf_key *bkey;
+
+	/* Keep in sync with include/linux/key.h. */
+	if (flags > (KEY_LOOKUP_PARTIAL << 1) - 1)
+		return NULL;
+
+	/* Permission check is deferred until actual kfunc using the key. */
+	key_ref = lookup_user_key(serial, flags, KEY_DEFER_PERM_CHECK);
+	if (IS_ERR(key_ref))
+		return NULL;
+
+	bkey = kmalloc(sizeof(*bkey), GFP_KERNEL);
+	if (!bkey) {
+		key_put(key_ref_to_ptr(key_ref));
+		return bkey;
+	}
+
+	bkey->key = key_ref_to_ptr(key_ref);
+	bkey->valid_ptr = true;
+
+	return bkey;
+}
+
+/**
+ * bpf_lookup_system_key - lookup a key by a system-defined ID
+ * @id: key ID
+ *
+ * Obtain a bpf_key structure with a key pointer set to the passed key ID.
+ * The key pointer is marked as invalid, to prevent bpf_key_put() from
+ * attempting to decrement the key reference count on that pointer. The key
+ * pointer set in such way is currently understood only by
+ * verify_pkcs7_signature().
+ *
+ * Set *id* to one of the values defined in include/linux/verification.h:
+ * 0 for the primary keyring (immutable keyring of system keys); 1 for both
+ * the primary and secondary keyring (where keys can be added only if they
+ * are vouched for by existing keys in those keyrings); 2 for the platform
+ * keyring (primarily used by the integrity subsystem to verify a kexec'ed
+ * kerned image and, possibly, the initramfs signature).
+ *
+ * Return: a bpf_key pointer with an invalid key pointer set from the
+ *         pre-determined ID on success, a NULL pointer otherwise
+ */
+noinline __weak struct bpf_key *bpf_lookup_system_key(u64 id)
+{
+	struct bpf_key *bkey;
+
+	/* Keep in sync with defs in include/linux/verification.h. */
+	if (id > (unsigned long)VERIFY_USE_PLATFORM_KEYRING)
+		return NULL;
+
+	bkey = kmalloc(sizeof(*bkey), GFP_KERNEL);
+	if (!bkey)
+		return bkey;
+
+	bkey->key = (struct key *)(unsigned long)id;
+	bkey->valid_ptr = false;
+
+	return bkey;
+}
+
+/**
+ * bpf_key_put - decrement key reference count if key is valid and free bpf_key
+ * @bkey: bpf_key structure
+ *
+ * Decrement the reference count of the key inside *bkey*, if the pointer
+ * is valid, and free *bkey*.
+ */
+noinline __weak void bpf_key_put(struct bpf_key *bkey)
+{
+	if (bkey->valid_ptr)
+		key_put(bkey->key);
+
+	kfree(bkey);
+}
+
+__diag_pop();
+
+BTF_SET8_START(key_kfunc_set)
+BTF_ID_FLAGS(func, bpf_lookup_user_key, KF_ACQUIRE | KF_RET_NULL | KF_SLEEPABLE)
+BTF_ID_FLAGS(func, bpf_lookup_system_key,
+	     KF_ACQUIRE | KF_RET_NULL | KF_SLEEPABLE)
+BTF_ID_FLAGS(func, bpf_key_put, KF_RELEASE)
+BTF_SET8_END(key_kfunc_set)
+
+static const struct btf_kfunc_id_set bpf_key_kfunc_set = {
+	.owner = THIS_MODULE,
+	.set = &key_kfunc_set,
+};
+#endif /* CONFIG_KEYS */
+
+const struct btf_kfunc_id_set *kfunc_sets[] = {
+#ifdef CONFIG_KEYS
+	&bpf_key_kfunc_set,
+#endif /* CONFIG_KEYS */
+};
+
+static int __init bpf_kfuncs_init(void)
+{
+	int ret, i;
+
+	for (i = 0; i < ARRAY_SIZE(kfunc_sets); i++) {
+		ret = register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING,
+						kfunc_sets[i]);
+		if (!ret)
+			continue;
+
+		ret = register_btf_kfunc_id_set(BPF_PROG_TYPE_LSM,
+						kfunc_sets[i]);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+late_initcall(bpf_kfuncs_init);
+
 static const struct bpf_func_proto *
 bpf_tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
 {
-- 
2.25.1


  parent reply	other threads:[~2022-08-09 13:48 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-09 13:45 [PATCH v9 00/10] bpf: Add kfuncs for PKCS#7 signature verification Roberto Sassu
2022-08-09 13:45 ` [PATCH v9 01/10] btf: Add a new kfunc flag which allows to mark a function to be sleepable Roberto Sassu
2022-08-09 16:54   ` Jarkko Sakkinen
2022-08-10 13:44     ` Roberto Sassu
2022-08-10 14:25       ` Benjamin Tissoires
2022-08-10 14:38         ` Daniel Borkmann
2022-08-10 14:52           ` Roberto Sassu
2022-08-10 14:58         ` Yosry Ahmed
2022-08-09 13:45 ` [PATCH v9 02/10] bpf: Allow kfuncs to be used in LSM programs Roberto Sassu
2022-08-09 21:53   ` Daniel Borkmann
2022-08-09 13:45 ` [PATCH v9 03/10] btf: Handle dynamic pointer parameter in kfuncs Roberto Sassu
2022-08-09 22:08   ` Daniel Borkmann
2022-08-09 22:29   ` Daniel Borkmann
2022-08-09 13:45 ` [PATCH v9 04/10] bpf: Export bpf_dynptr_get_size() Roberto Sassu
2022-08-09 13:45 ` [PATCH v9 05/10] KEYS: Move KEY_LOOKUP_ to include/linux/key.h Roberto Sassu
2022-08-09 13:45 ` Roberto Sassu [this message]
2022-08-09 22:53   ` [PATCH v9 06/10] bpf: Add bpf_lookup_*_key() and bpf_key_put() kfuncs Daniel Borkmann
2022-08-10 14:17     ` Roberto Sassu
2022-08-10 14:29       ` Daniel Borkmann
2022-08-09 13:46 ` [PATCH v9 07/10] bpf: Add bpf_verify_pkcs7_signature() kfunc Roberto Sassu
2022-08-09 23:09   ` Daniel Borkmann
2022-08-10  2:41   ` Alexei Starovoitov
2022-08-09 13:46 ` [PATCH v9 08/10] selftests/bpf: Add verifier tests for bpf_lookup_*_key() and bpf_key_put() Roberto Sassu
2022-08-09 13:46 ` [PATCH v9 09/10] selftests/bpf: Add additional tests for bpf_lookup_*_key() Roberto Sassu
2022-08-09 13:46 ` [PATCH v9 10/10] selftests/bpf: Add test for bpf_verify_pkcs7_signature() kfunc Roberto Sassu
2022-08-09 16:20 ` [PATCH v9 00/10] bpf: Add kfuncs for PKCS#7 signature verification patchwork-bot+netdevbpf
2022-08-09 16:53 ` Jarkko Sakkinen
2022-08-10 10:47   ` Roberto Sassu

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=20220809134603.1769279-7-roberto.sassu@huawei.com \
    --to=roberto.sassu@huawei.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=corbet@lwn.net \
    --cc=daniel@iogearbox.net \
    --cc=dhowells@redhat.com \
    --cc=haoluo@google.com \
    --cc=jarkko@kernel.org \
    --cc=jmorris@namei.org \
    --cc=john.fastabend@gmail.com \
    --cc=jolsa@kernel.org \
    --cc=keyrings@vger.kernel.org \
    --cc=kpsingh@kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=martin.lau@linux.dev \
    --cc=mingo@redhat.com \
    --cc=paul@paul-moore.com \
    --cc=rostedt@goodmis.org \
    --cc=sdf@google.com \
    --cc=serge@hallyn.com \
    --cc=shuah@kernel.org \
    --cc=song@kernel.org \
    --cc=yhs@fb.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.