[PATCH 1/2] KEYS: Add key_type keyagent

From: Benjamin Coddington
Date: Tue Jul 12 2022 - 08:35:32 EST


Define and register a new key_type called keyagent. When instantiated,
keyagent keys take a reference on the struct pid of the current task, and
store a number between SIGRTMIN and SIGRTMAX.

In a later patch, we'll use that number to send a realtime signal to the
keyagent task in order to answer request-key callouts for other key types.

Signed-off-by: Benjamin Coddington <bcodding@xxxxxxxxxx>
---
security/keys/Kconfig | 9 +++++
security/keys/Makefile | 1 +
security/keys/keyagent.c | 73 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 83 insertions(+)
create mode 100644 security/keys/keyagent.c

diff --git a/security/keys/Kconfig b/security/keys/Kconfig
index abb03a1b2a5c..f31a0f94ca88 100644
--- a/security/keys/Kconfig
+++ b/security/keys/Kconfig
@@ -112,6 +112,15 @@ config USER_DECRYPTED_DATA

If you are unsure as to whether this is required, answer N.

+config KEYAGENT
+ bool "KEYAGENT"
+ depends on KEYS
+ help
+ This option allows persistent userland processes to answer
+ request-key callouts.
+
+ If you are unsure as to whether this is required, answer N.
+
config KEY_DH_OPERATIONS
bool "Diffie-Hellman operations on retained keys"
depends on KEYS
diff --git a/security/keys/Makefile b/security/keys/Makefile
index 5f40807f05b3..c753f8f79c38 100644
--- a/security/keys/Makefile
+++ b/security/keys/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_SYSCTL) += sysctl.o
obj-$(CONFIG_PERSISTENT_KEYRINGS) += persistent.o
obj-$(CONFIG_KEY_DH_OPERATIONS) += dh.o
obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += keyctl_pkey.o
+obj-$(CONFIG_KEYAGENT) += keyagent.o

#
# Key types
diff --git a/security/keys/keyagent.c b/security/keys/keyagent.c
new file mode 100644
index 000000000000..87ebfe00c710
--- /dev/null
+++ b/security/keys/keyagent.c
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* Key Agent handling
+ *
+ * Copyright (C) 2022 Red Hat Inc. All Rights Reserved.
+ * Written by Benjamin Coddington (bcodding@xxxxxxxxxx)
+ */
+
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/key.h>
+#include <linux/key-type.h>
+
+#include <keys/user-type.h>
+
+/*
+ * Keyagent key payload.
+ */
+struct keyagent {
+ struct pid *pid;
+ int sig;
+};
+
+/*
+ * Instantiate takes a reference to the current task's struct pid
+ * and the requested realtime signal number.
+ */
+static int
+keyagent_instantiate(struct key *key, struct key_preparsed_payload *prep)
+{
+ struct keyagent *ka;
+ __be16 sig = *(__be16 *)prep->data;
+
+ /* Only real-time signals numbers allowed */
+ if (sig < SIGRTMIN || sig > SIGRTMAX)
+ return -EINVAL;
+
+ ka = kzalloc(sizeof(struct keyagent), GFP_KERNEL);
+ if (!ka)
+ return -ENOMEM;
+
+ ka->pid = get_task_pid(current, PIDTYPE_PID);
+ ka->sig = sig;
+ key->payload.data[0] = ka;
+
+ return 0;
+}
+
+static void keyagent_destroy(struct key *key)
+{
+ struct keyagent *ka = key->payload.data[0];
+
+ put_pid(ka->pid);
+ kfree(ka);
+}
+
+/*
+ * keyagent keys represent userland processes waiting on signals from the
+ * kernel to respond to request-key callouts
+ */
+struct key_type key_type_keyagent = {
+ .name = "keyagent",
+ .instantiate = keyagent_instantiate,
+ .def_datalen = sizeof(struct keyagent),
+ .destroy = keyagent_destroy,
+ .describe = user_describe,
+};
+
+static int __init keyagent_init(void)
+{
+ return register_key_type(&key_type_keyagent);
+}
+
+late_initcall(keyagent_init);
--
2.31.1