mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Benjamin Coddington <bcodding@redhat.com>
To: David Howells <dhowells@redhat.com>, linux-kernel@vger.kernel.org
Cc: ebiederm@xmission.com, Ian Kent <raven@themaw.net>,
	Trond Myklebust <trond.myklebust@hammerspace.com>,
	linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org
Subject: [PATCH 2/2] KEYS: Add keyagent request_key
Date: Tue, 12 Jul 2022 08:35:21 -0400	[thread overview]
Message-ID: <061dd6fe81dc97a4375e52ec0da20a54cf582cb5.1657624639.git.bcodding@redhat.com> (raw)
In-Reply-To: <cover.1657624639.git.bcodding@redhat.com>

During key construction, search the calling process' session keyring for a
keyagent key with a description that matches the requested key_type.  If
found, link the authkey into the keyagent's process_keyring, and signal the
keyagent task with a realtime signal containing the serial number of the
key that needs to be constructed.

Signed-off-by: Benjamin Coddington <bcodding@redhat.com>
---
 include/uapi/asm-generic/siginfo.h |  1 +
 security/keys/internal.h           |  4 ++
 security/keys/keyagent.c           | 85 ++++++++++++++++++++++++++++++
 security/keys/request_key.c        |  9 ++++
 4 files changed, 99 insertions(+)

diff --git a/include/uapi/asm-generic/siginfo.h b/include/uapi/asm-generic/siginfo.h
index ffbe4cec9f32..542e297f4466 100644
--- a/include/uapi/asm-generic/siginfo.h
+++ b/include/uapi/asm-generic/siginfo.h
@@ -185,6 +185,7 @@ typedef struct siginfo {
 #define SI_SIGIO	-5		/* sent by queued SIGIO */
 #define SI_TKILL	-6		/* sent by tkill system call */
 #define SI_DETHREAD	-7		/* sent by execve() killing subsidiary threads */
+#define SI_KEYAGENT	-8		/* sent by request-key */
 #define SI_ASYNCNL	-60		/* sent by glibc async name lookup completion */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 9b9cf3b6fcbb..a6db6eecfff5 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -372,5 +372,9 @@ static inline void key_check(const struct key *key)
 
 #define key_check(key) do {} while(0)
 
+#endif
+
+#ifdef CONFIG_KEYAGENT
+extern int keyagent_request_key(struct key *authkey, void *aux);
 #endif
 #endif /* _INTERNAL_H */
diff --git a/security/keys/keyagent.c b/security/keys/keyagent.c
index 87ebfe00c710..cf70146925f0 100644
--- a/security/keys/keyagent.c
+++ b/security/keys/keyagent.c
@@ -9,8 +9,11 @@
 #include <linux/slab.h>
 #include <linux/key.h>
 #include <linux/key-type.h>
+#include <linux/sched/signal.h>
+#include <linux/sched/task.h>
 
 #include <keys/user-type.h>
+#include <keys/request_key_auth-type.h>
 
 /*
  * Keyagent key payload.
@@ -20,6 +23,88 @@ struct keyagent {
 	int sig;
 };
 
+struct key_type key_type_keyagent;
+
+/*
+ * Given a key representing a keyagent and a target_key to construct, link
+ * the the authkey into the keyagent's process_keyring and signal the
+ * keyagent to construct the target_key.
+ */
+static int keyagent_signal(struct key *ka_key, struct key *target_key,
+							struct key *authkey)
+{
+	struct keyagent *ka = ka_key->payload.data[0];
+	struct task_struct *task;
+	const struct cred *cred;
+	kernel_siginfo_t info = {
+		.si_code = SI_KEYAGENT,
+		.si_signo = ka->sig,
+		.si_int = target_key->serial,
+	};
+	int ret = -ENOKEY;
+
+	task = get_pid_task(ka->pid, PIDTYPE_PID);
+	/* If the task is gone, should we revoke the keyagent key? */
+	if (!task) {
+		key_revoke(ka_key);
+		goto out;
+	}
+
+	/* We're expecting valid keyagents to have a process keyring,
+	 * if not, should we warn? */
+	cred = get_cred(task->cred);
+	if (!cred->process_keyring)
+		goto out_nolink;
+
+	/* Link the autkey to the keyagent's process_keyring */
+	ret = key_link(cred->process_keyring, authkey);
+	if (ret < 0)
+		goto out_nolink;
+
+	ret = send_sig_info(ka->sig, &info, task);
+
+out_nolink:
+	put_cred(cred);
+	put_task_struct(task);
+out:
+	return ret;
+}
+
+/*
+ * Search the calling process' keyrings for a keyagent that
+ * matches the requested key type.  If found, signal the keyagent
+ * to construct and link the key, else return -ENOKEY.
+ */
+int keyagent_request_key(struct key *authkey, void *aux)
+{
+	struct key *ka_key, *target_key;
+	struct request_key_auth *rka;
+	key_ref_t ka_ref;
+	const struct cred *cred = current_cred();
+	int ret;
+
+	/* We must be careful not to touch authkey and aux if
+	 * returning -ENOKEY, since it will be reused.   */
+	rka = get_request_key_auth(authkey);
+	target_key = rka->target_key;
+
+	/* Does the calling process have a keyagent in its session keyring? */
+	ka_ref = keyring_search(
+					make_key_ref(cred->session_keyring, 1),
+					&key_type_keyagent,
+					target_key->type->name, false);
+
+	if (IS_ERR(ka_ref))
+		return -ENOKEY;
+
+	/* We found a keyagent, let's call out to it. */
+	ka_key = key_ref_to_ptr(ka_ref);
+	ret = keyagent_signal(ka_key, target_key, authkey);
+	key_put(key_ref_to_ptr(ka_ref));
+
+	return ret;
+}
+
 /*
  * Instantiate takes a reference to the current task's struct pid
  * and the requested realtime signal number.
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 2da4404276f0..4c1f5ef55856 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -240,9 +240,18 @@ static int construct_key(struct key *key, const void *callout_info,
 	actor = call_sbin_request_key;
 	if (key->type->request_key)
 		actor = key->type->request_key;
+#ifdef CONFIG_KEYAGENT
+	else {
+		ret = keyagent_request_key(authkey, aux);
 
+		/* ENOKEY: no keyagents match on calling process' keyrings */
+		if (ret != -ENOKEY)
+			goto done;
+	}
+#endif
 	ret = actor(authkey, aux);
 
+done:
 	/* check that the actor called complete_request_key() prior to
 	 * returning an error */
 	WARN_ON(ret < 0 &&
-- 
2.31.1


  parent reply	other threads:[~2022-07-12 12:35 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-12 12:35 [RFC PATCH 0/2] Keyagents: another call_usermodehelper approach for namespaces Benjamin Coddington
2022-07-12 12:35 ` [PATCH 1/2] KEYS: Add key_type keyagent Benjamin Coddington
2022-07-12 12:35 ` Benjamin Coddington [this message]
2022-07-14 22:10   ` [PATCH 2/2] KEYS: Add keyagent request_key kernel test robot
2022-07-15 15:28   ` kernel test robot
2022-07-15 15:28   ` kernel test robot
2022-07-12 14:16 ` [RFC PATCH 0/2] Keyagents: another call_usermodehelper approach for namespaces Eric W. Biederman
2022-07-12 16:47   ` Benjamin Coddington

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=061dd6fe81dc97a4375e52ec0da20a54cf582cb5.1657624639.git.bcodding@redhat.com \
    --to=bcodding@redhat.com \
    --cc=dhowells@redhat.com \
    --cc=ebiederm@xmission.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=raven@themaw.net \
    --cc=trond.myklebust@hammerspace.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

all inboxes | Powered by JetHome®