From: "Thomas Weißschuh" <linux@weissschuh.net>
To: "David Howells" <dhowells@redhat.com>,
"David Woodhouse" <dwmw2@infradead.org>,
"Jarkko Sakkinen" <jarkko@kernel.org>,
"Paul Moore" <paul@paul-moore.com>,
"James Morris" <jmorris@namei.org>,
"Serge E. Hallyn" <serge@hallyn.com>,
"Mickaël Salaün" <mic@digikod.net>
Cc: keyrings@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-security-module@vger.kernel.org,
"Paul Menzel" <pmenzel@molgen.mpg.de>,
"Mark Pearson" <markpearson@lenovo.com>,
"Thomas Weißschuh" <linux@weissschuh.net>
Subject: [PATCH RESEND v6 2/3] KEYS: Add new function key_create()
Date: Mon, 09 Jan 2023 23:59:42 +0000 [thread overview]
Message-ID: <20221212-keys-blacklist-v6-2-933267a80582@weissschuh.net> (raw)
In-Reply-To: <20221212-keys-blacklist-v6-0-933267a80582@weissschuh.net>
key_create() works like key_create_or_update() but does not allow
updating an existing key, instead returning ERR_PTR(-EEXIST).
key_create() will be used by the blacklist keyring which should not
create duplicate entries or update existing entries.
Instead a dedicated message with appropriate severity will be logged.
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
include/linux/key.h | 8 +++
security/keys/key.c | 137 ++++++++++++++++++++++++++++++++++++++--------------
2 files changed, 108 insertions(+), 37 deletions(-)
diff --git a/include/linux/key.h b/include/linux/key.h
index d27477faf00d..8dc7f7c3088b 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -386,6 +386,14 @@ extern int wait_for_key_construction(struct key *key, bool intr);
extern int key_validate(const struct key *key);
+extern key_ref_t key_create(key_ref_t keyring,
+ const char *type,
+ const char *description,
+ const void *payload,
+ size_t plen,
+ key_perm_t perm,
+ unsigned long flags);
+
extern key_ref_t key_create_or_update(key_ref_t keyring,
const char *type,
const char *description,
diff --git a/security/keys/key.c b/security/keys/key.c
index c45afdd1dfbb..5c0c7df833f8 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -788,38 +788,18 @@ static inline key_ref_t __key_update(key_ref_t key_ref,
goto out;
}
-/**
- * key_create_or_update - Update or create and instantiate a key.
- * @keyring_ref: A pointer to the destination keyring with possession flag.
- * @type: The type of key.
- * @description: The searchable description for the key.
- * @payload: The data to use to instantiate or update the key.
- * @plen: The length of @payload.
- * @perm: The permissions mask for a new key.
- * @flags: The quota flags for a new key.
- *
- * Search the destination keyring for a key of the same description and if one
- * is found, update it, otherwise create and instantiate a new one and create a
- * link to it from that keyring.
- *
- * If perm is KEY_PERM_UNDEF then an appropriate key permissions mask will be
- * concocted.
- *
- * Returns a pointer to the new key if successful, -ENODEV if the key type
- * wasn't available, -ENOTDIR if the keyring wasn't a keyring, -EACCES if the
- * caller isn't permitted to modify the keyring or the LSM did not permit
- * creation of the key.
- *
- * On success, the possession flag from the keyring ref will be tacked on to
- * the key ref before it is returned.
+/*
+ * Create or potentially update a key. The combined logic behind
+ * key_create_or_update() and key_create()
*/
-key_ref_t key_create_or_update(key_ref_t keyring_ref,
- const char *type,
- const char *description,
- const void *payload,
- size_t plen,
- key_perm_t perm,
- unsigned long flags)
+static key_ref_t __key_create_or_update(key_ref_t keyring_ref,
+ const char *type,
+ const char *description,
+ const void *payload,
+ size_t plen,
+ key_perm_t perm,
+ unsigned long flags,
+ bool allow_update)
{
struct keyring_index_key index_key = {
.description = description,
@@ -906,14 +886,23 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
goto error_link_end;
}
- /* if it's possible to update this type of key, search for an existing
- * key of the same type and description in the destination keyring and
- * update that instead if possible
+ /* if it's requested and possible to update this type of key, search
+ * for an existing key of the same type and description in the
+ * destination keyring and update that instead if possible
*/
- if (index_key.type->update) {
+ if (allow_update) {
+ if (index_key.type->update) {
+ key_ref = find_key_to_update(keyring_ref, &index_key);
+ if (key_ref)
+ goto found_matching_key;
+ }
+ } else {
key_ref = find_key_to_update(keyring_ref, &index_key);
- if (key_ref)
- goto found_matching_key;
+ if (key_ref) {
+ key_ref_put(key_ref);
+ key_ref = ERR_PTR(-EEXIST);
+ goto error_link_end;
+ }
}
/* if the client doesn't provide, decide on the permissions we want */
@@ -985,8 +974,82 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
goto error_free_prep;
}
+
+/**
+ * key_create_or_update - Update or create and instantiate a key.
+ * @keyring_ref: A pointer to the destination keyring with possession flag.
+ * @type: The type of key.
+ * @description: The searchable description for the key.
+ * @payload: The data to use to instantiate or update the key.
+ * @plen: The length of @payload.
+ * @perm: The permissions mask for a new key.
+ * @flags: The quota flags for a new key.
+ *
+ * Search the destination keyring for a key of the same description and if one
+ * is found, update it, otherwise create and instantiate a new one and create a
+ * link to it from that keyring.
+ *
+ * If perm is KEY_PERM_UNDEF then an appropriate key permissions mask will be
+ * concocted.
+ *
+ * Returns a pointer to the new key if successful, -ENODEV if the key type
+ * wasn't available, -ENOTDIR if the keyring wasn't a keyring, -EACCES if the
+ * caller isn't permitted to modify the keyring or the LSM did not permit
+ * creation of the key.
+ *
+ * On success, the possession flag from the keyring ref will be tacked on to
+ * the key ref before it is returned.
+ */
+key_ref_t key_create_or_update(key_ref_t keyring_ref,
+ const char *type,
+ const char *description,
+ const void *payload,
+ size_t plen,
+ key_perm_t perm,
+ unsigned long flags)
+{
+ return __key_create_or_update(keyring_ref, type, description, payload,
+ plen, perm, flags, true);
+}
EXPORT_SYMBOL(key_create_or_update);
+/**
+ * key_create - Create and instantiate a key.
+ * @keyring_ref: A pointer to the destination keyring with possession flag.
+ * @type: The type of key.
+ * @description: The searchable description for the key.
+ * @payload: The data to use to instantiate or update the key.
+ * @plen: The length of @payload.
+ * @perm: The permissions mask for a new key.
+ * @flags: The quota flags for a new key.
+ *
+ * Create and instantiate a new key and link to it from the destination keyring.
+ *
+ * If perm is KEY_PERM_UNDEF then an appropriate key permissions mask will be
+ * concocted.
+ *
+ * Returns a pointer to the new key if successful, -EEXIST if a key with the
+ * same description already exists, -ENODEV if the key type wasn't available,
+ * -ENOTDIR if the keyring wasn't a keyring, -EACCES if the caller isn't
+ * permitted to modify the keyring or the LSM did not permit creation of the
+ * key.
+ *
+ * On success, the possession flag from the keyring ref will be tacked on to
+ * the key ref before it is returned.
+ */
+key_ref_t key_create(key_ref_t keyring_ref,
+ const char *type,
+ const char *description,
+ const void *payload,
+ size_t plen,
+ key_perm_t perm,
+ unsigned long flags)
+{
+ return __key_create_or_update(keyring_ref, type, description, payload,
+ plen, perm, flags, false);
+}
+EXPORT_SYMBOL(key_create);
+
/**
* key_update - Update a key's contents.
* @key_ref: The pointer (plus possession flag) to the key.
--
2.39.0
next prev parent reply other threads:[~2023-01-10 0:00 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-01-09 23:59 [PATCH RESEND v6 0/3] certs: Prevent spurious errors on repeated blacklisting Thomas Weißschuh
2023-01-09 23:59 ` [PATCH RESEND v6 1/3] certs: make blacklisted hash available in klog Thomas Weißschuh
2023-01-09 23:59 ` Thomas Weißschuh [this message]
2023-01-09 23:59 ` [PATCH RESEND v6 3/3] certs: don't try to update blacklist keys Thomas Weißschuh
2023-01-20 21:10 ` [PATCH RESEND v6 0/3] certs: Prevent spurious errors on repeated blacklisting Jarkko Sakkinen
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=20221212-keys-blacklist-v6-2-933267a80582@weissschuh.net \
--to=linux@weissschuh.net \
--cc=dhowells@redhat.com \
--cc=dwmw2@infradead.org \
--cc=jarkko@kernel.org \
--cc=jmorris@namei.org \
--cc=keyrings@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=markpearson@lenovo.com \
--cc=mic@digikod.net \
--cc=paul@paul-moore.com \
--cc=pmenzel@molgen.mpg.de \
--cc=serge@hallyn.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).