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